import { readFileSync } from "node:fs"; import { describe, expect, it } from "vitest"; function readThemeCss() { return readFileSync(new URL("./base.css", import.meta.url), "utf8"); } function compact(value) { return value.replace(/\s+/g, ""); } describe("platform web shared theme CSS", () => { it("keeps plugin lifecycle controls bounded at narrow width", () => { const css = compact(readThemeCss()); expect(css).toContain("@media(max-width:640px){.plugin-lifecycle-controls{grid-template-columns:minmax(0,1fr)}"); expect(css).toContain("overflow-wrap:anywhere"); }); it("suppresses nested state frames inside shared framed surfaces", () => { const css = compact(readThemeCss()); expect(css).toContain(".state-view::after,:root[data-theme-palette]:where("); expect(css).toContain(".state-view::before{content:none;background:00;box-shadow:none;filter:none}"); }); it("keeps server card runtime actions as compact overlay menus", () => { const css = compact(readThemeCss()); expect(css).toContain(".runtime-action-popover{position:fixed;z-index:45"); expect(css).toContain(".runtime-action-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))"); }); it("keeps runtime task progress display visually explicit", () => { const css = compact(readThemeCss()); expect(css).toContain(".runtime-task-progress-summary{display:grid"); expect(css).toContain(".runtime-task-progress-summary>span{color:var(--accent)"); expect(css).toContain(".runtime-task-meter-track{height:10px"); }); it("themes shared scrollbars instead of exposing browser-default gutters", () => { const css = compact(readThemeCss()); expect(css).toContain(":root[data-theme-palette],:root[data-theme-palette]*{scrollbar-color:color-mix(insrgb,var(--accent)62%,var(--surface-solid))color-mix(insrgb,var(--surface-solid)62%,transparent);scrollbar-width:thin}"); expect(css).toContain(":root[data-theme-palette]::-webkit-scrollbar,:root[data-theme-palette]*::-webkit-scrollbar{width:10px;height:10px}"); expect(css).toContain(":root[data-theme-palette]::-webkit-scrollbar-thumb,:root[data-theme-palette]*::-webkit-scrollbar-thumb{min-height:42px;border:2pxsolid"); expect(css).toContain("background:linear-gradient(180deg,color-mix(insrgb,var(--accent)62%,var(--surface-solid)),color-mix(insrgb,var(--gold)46%,var(--accent)))"); expect(css).toContain("::-webkit-scrollbar-corner"); }); it("keeps server card stat tiles readable over busy backgrounds", () => { const css = compact(readThemeCss()); expect(css).toContain(".server-card-stat{display:grid;gap:2px;padding:8px;border:1pxsolid"); expect(css).toContain("--surface-solid"); expect(css).toContain("font-weight:850"); expect(css).toContain(":root[data-custom-background=true].server-card-stat"); }); it("gives server cards enough room for long status labels", () => { const css = compact(readThemeCss()); expect(css).toContain(".server-card-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,420px),1fr))"); expect(css).toContain(".server-card-head{display:grid;gap:8px;min-width:0}"); expect(css).toContain(".server-card-head>span:last-child{justify-self:start;white-space:normal"); }); it("keeps magical custom-background signal rows readable without the jelly wash", () => { const css = compact(readThemeCss()); expect(css).toContain(":root[data-custom-background=true][data-theme-palette=magical-girl].signal-item"); expect(css).toContain("rgba(58,44,56,.72)"); expect(css).toContain("backdrop-filter:blur(12px)saturate(0.92)"); expect(css).not.toContain("var(--jelly-highlight),var(--glass-wash),var(--surface-solid)"); }); it("keeps shared controls off the heavy jelly and corner-sparkle button wash", () => { const css = readThemeCss(); expect(css).toContain("--control-surface"); expect(css).toContain("--primary-command-surface"); expect(css).not.toContain("background: var(--jelly-highlight), var(--glass-wash), var(--surface-solid)"); expect(css).not.toContain("linear-gradient(145deg, rgba(255, 255, 255, 0.72), transparent 36%)"); }); it("keeps SCUM user identity and economy columns readable", () => { const css = compact(readThemeCss()); expect(css).toContain(".scum-user-table{min-width:1240px;table-layout:fixed}"); expect(css).toContain(".scum-user-tableth,.scum-user-tabletd{padding:9px12px;border-bottom-color:color-mix(insrgb,var(--line)64%,transparent);white-space:nowrap}"); expect(css).toContain(".scum-user-tableth:nth-child(7),.scum-user-tabletd:nth-child(7){width:190px}"); expect(css).toContain(".scum-mono-cell{font-family:var(--font-mono);font-size:12px}"); }); it("uses shared orbital construct backdrop and button ring effects", () => { const themeCss = readThemeCss(); const constructRule = themeCss.slice(themeCss.indexOf(".global-orbital-construct"), themeCss.indexOf(".mobile-sidebar-backdrop")); expect(constructRule).toContain("clip-path:circle(49% at 50% 50%)"); expect(constructRule).toContain("background:var(--orbital-construct-image) center/contain no-repeat transparent"); expect(constructRule).toContain("filter:var(--orbital-construct-filter)"); expect(constructRule).toContain(".global-orbital-construct::before,.global-orbital-construct::after{content:none}"); expect(constructRule).toContain(":root[data-theme-palette=mecha-black] .global-orbital-construct{display:block;opacity:.22}"); expect(constructRule).toContain(":root[data-theme-palette=magical-girl] .global-orbital-construct{display:block;opacity:.24}"); expect(constructRule).toContain(".global-particle-lightfall"); expect(constructRule).toContain(".global-particle-side-ray"); expect(themeCss).not.toContain("global-particle-frame"); expect(themeCss).not.toContain("global-particle-orbit"); expect(themeCss).not.toContain("particle-orbit-drift"); expect(constructRule).toContain("orbital-construct-drift"); expect(constructRule).toContain("prefers-reduced-motion"); expect(constructRule).toContain("var(--command-ring-sheen"); expect(constructRule).toContain(".app-nav-group-button::after"); expect(constructRule).toContain("magic-side-ray-pulse-right"); expect(constructRule).toContain("transform:translateY(1px)"); expect(themeCss).toContain(":root[data-custom-background=true] .global-particle-layer{opacity:.42}"); expect(themeCss).toContain(":root[data-custom-background=true][data-theme-palette=magical-girl] .global-particle-layer{opacity:.54}"); expect(themeCss).not.toContain(":root[data-custom-background=true] .global-particle-layer{opacity:.03}"); }); it("keeps magical-girl custom-background panel overlays restrained", () => { const css = compact(readThemeCss()); expect(css).toContain(":root[data-custom-background=true][data-theme-palette=magical-girl]{--frame-accessory-opacity:0.22"); expect(css).toContain("--surface:rgba(22,22,29,0.42)"); expect(css).toContain("linear-gradient(180deg,rgba(24,24,31,.22),rgba(18,19,26,.18))"); expect(css).not.toContain("255,119,200,0.78"); }); it("keeps catalog and console panels translucent without fading content", () => { const css = compact(readThemeCss()); expect(css).toContain(".catalog-card,.console-panel{border:1pxsolidvar(--line);border-radius:8px;background:var(--sugar-dust),linear-gradient(135deg,color-mix(insrgb,var(--surface)22%,transparent),color-mix(insrgb,var(--surface-raised)14%,transparent))"); expect(css).toContain("-webkit-backdrop-filter:blur(10px)saturate(.9);backdrop-filter:blur(10px)saturate(.9)"); expect(css).toContain(":root[data-custom-background=true].catalog-card"); expect(css).toContain("linear-gradient(180deg,rgba(5,10,16,.42),rgba(5,10,16,.34))"); expect(css).not.toContain(".catalog-card,.console-panel{opacity:"); expect(css).not.toContain(".catalog-card,.console-panel{border:1pxsolidvar(--line);border-radius:8px;background:var(--panel-material);backdrop-filter:blur(22px)saturate(1.28)"); }); it("styles runtime task progress as a dialog with staged status", () => { const css = readThemeCss(); expect(css).toContain(".runtime-task-panel"); expect(css).toContain(".runtime-task-meter-track"); expect(css).toContain(".runtime-task-stages"); expect(css).toContain(".runtime-task-log"); expect(css).toContain("prefers-reduced-motion"); }); it("styles operations surfaces with shared theme materials and narrow-screen collapse", () => { const css = compact(readThemeCss()); expect(css).toContain(".operations-tray{position:relative;z-index:2"); expect(css).toContain("background:var(--panel-material),var(--surface)"); expect(css).toContain(".operations-tray-panel{position:absolute"); expect(css).toContain("@media(max-width:760px){.operations-command-grid{grid-template-columns:1fr}"); expect(css).toContain(".operations-job-row-failed"); expect(css).toContain("prefers-reduced-motion"); }); it("keeps mobile navigation off-canvas with readable vertical labels", () => { const css = compact(readThemeCss()); expect(css).toContain(".mobile-sidebar-handle{position:fixed"); expect(css).toContain(".app-sidebar{position:fixed;inset:0auto00"); expect(css).toContain("transform:translateX(calc(-100%-18px))"); expect(css).toContain(".app-sidebar-mobile-open"); expect(css).toContain("grid-template-columns:40pxminmax(0,1fr)"); expect(css).toContain(".app-nav-copystrong{display:block"); }); it("keeps desktop sidebar controls pinned inside the viewport", () => { const css = compact(readThemeCss()); expect(css).toContain(".app-shell{min-height:100dvh"); expect(css).toContain(".app-sidebar{position:sticky"); expect(css).toContain("height:100dvh"); expect(css).toContain("overflow-y:auto"); expect(css).toContain("overscroll-behavior:contain"); }); it("keeps dialogs and drawers internally scrollable on short viewports", () => { const css = compact(readThemeCss()); expect(css).toContain(".dialog-panel-header,.drawer-panel>.panel-header{position:sticky"); expect(css).toContain("overflow-y:auto"); expect(css).toContain("overscroll-behavior:contain"); expect(css).toContain("max-height:calc(100dvh-32px)"); expect(css).toContain("max-height:calc(100dvh-20px)"); }); it("keeps the management terminal opaque and large", () => { const css = compact(readThemeCss()); expect(css).toContain(".terminal-drawer-backdrop{align-items:flex-end;justify-content:center;padding:10dvh00;background:#000;backdrop-filter:none}"); expect(css).toContain(".management-terminal-drawer{width:100%;max-width:none;height:90dvh;max-height:90dvh"); expect(css).toContain("background:#000;backdrop-filter:none;box-shadow:none"); expect(css).toContain(".management-terminal-body{height:100%;grid-template-rows:minmax(0,1fr)auto"); expect(css).toContain(".terminal-output-panel{display:grid;grid-template-rows:autominmax(0,1fr);min-height:0;border:1pxsolid#222;border-radius:8px;background:#000"); expect(css).toContain(".terminal-output-topbar{display:flex;align-items:center;justify-content:space-between"); expect(css).toContain(".terminal-output{display:block;min-height:260px"); expect(css).toContain(".terminal-line{display:grid;grid-template-columns:74pxminmax(0,1fr)"); expect(css).toContain(".terminal-text{min-width:0;white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word"); expect(css).toContain(".terminal-source-system.terminal-text,.terminal-source-platform.terminal-text,.terminal-source-bridge.terminal-text{color:#d2a8ff}"); expect(css).toContain(".terminal-line-error.terminal-text,.terminal-source-stderr.terminal-text,.terminal-source-stderrtime{color:#ff7b72}"); expect(css).toContain(".terminal-quick-command-list{display:grid;grid-template-columns:repeat(4,minmax(0,1fr))"); }); it("keeps deployment workflow fields compact when a mode has one input", () => { const css = compact(readThemeCss()); expect(css).toContain(".deployment-workflow-body{display:grid;align-content:start;gap:12px;min-height:0}"); expect(css).toContain(".deployment-workflow-body.form-grid{align-content:start;align-items:start;grid-auto-rows:min-content}"); }); it("keeps the guided-install plan compact and responsive inside the deployment workflow", () => { const css = compact(readThemeCss()); expect(css).toContain(".guided-install-plan{display:grid;gap:10px;padding:12px;border:1pxsolidcolor-mix(insrgb,var(--accent)42%,var(--line));border-radius:8px"); expect(css).toContain(".guided-install-planol{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px"); expect(css).toContain(".guided-install-planol,.maintenance-node-item"); }); it("keeps magical card decoration from becoming square background patches", () => { const css = compact(readThemeCss()); expect(css).toContain(":root[data-theme-palette=magical-girl].catalog-card"); expect(css).toContain("background:var(--sugar-dust),linear-gradient(180deg,color-mix(insrgb,var(--surface)16%,transparent),color-mix(insrgb,var(--surface-raised)10%,transparent));overflow:visible"); expect(css).not.toContain("background-size:56px56px"); expect(css).not.toContain("background-image:var(--corner-sparkle),var(--panel-material)"); expect(css).not.toContain(".global-magic-ring"); }); });