/* ContentOS on the Commerce OS Workbench design system.

   Loaded after tokens.css and bundle.css on every page. Three jobs:
     1. the per-theme overrides tokens.css cannot carry (font, radius, sidebar text ramp), copied
        from app/globals.css in CommerceOS-Workbench so the four palettes match the workbench;
     2. the app shell: the hover-expanding rail on the left, the page header, the scroll region.
        Same numbers as ui/app-shell.tsx and ui/sidebar.tsx (56px rail, 220px expanded, 200ms);
     3. the shared primitives ContentOS pages reach for (buttons, badges, fields, eyebrows).

   Rule from design-system/README.md: no component names a colour. Everything here is a token. */

/* ── 1. Theme overrides ─────────────────────────────────────────────────── */
:root {
  --sidebar-nav-fg: color-mix(in oklab, var(--sidebar-foreground) 70%, transparent);
  --sidebar-section-fg: color-mix(in oklab, var(--muted-foreground) 60%, transparent);
  --sidebar-util-fg: color-mix(in oklab, var(--sidebar-foreground) 50%, transparent);
  --sidebar-nav-weight: 400;
  --sidebar-nav-active-weight: 500;
  --tracking-normal: 0em;
  --radius: 10px;
}
[data-theme="supabase"], [data-theme="supabase-dark"] {
  --font-sans: Outfit, ui-sans-serif, system-ui, sans-serif;
  --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, monospace;
  --radius: 8px; --radius-sm: 4px; --radius-md: 6px; --radius-lg: 8px; --radius-xl: 12px;
  --tracking-normal: 0.025em;
  --sidebar-nav-weight: 500; --sidebar-nav-active-weight: 600;
  --opacity-sidebar-icon: 0.85;
}
[data-theme="supabase"] {
  --sidebar-nav-fg: oklch(0.4386 0 0); --sidebar-section-fg: oklch(0.5 0 0); --sidebar-util-fg: oklch(0.5452 0 0);
}
[data-theme="supabase-dark"] {
  --sidebar-nav-fg: oklch(0.7122 0 0); --sidebar-section-fg: oklch(0.6301 0 0); --sidebar-util-fg: oklch(0.6301 0 0);
  --opacity-sidebar-icon-muted: 0.72;
}
[data-theme="newlook"], [data-theme="newlook-dark"] {
  --font-sans: Outfit, ui-sans-serif, system-ui, sans-serif;
  --font-serif: Outfit, ui-sans-serif, system-ui, sans-serif;
  --radius: 4px; --radius-sm: 2px; --radius-md: 3px; --radius-lg: 4px; --radius-xl: 8px;
}
/* Dark themes flip the hairline shadow the app-shell overlay needs. */
[data-theme$="-dark"] { color-scheme: dark; }

/* ── 2. Base ────────────────────────────────────────────────────────────── */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  background: var(--background); color: var(--foreground);
  font-family: var(--font-sans); font-size: 13px; line-height: 1.45;
  letter-spacing: var(--tracking-normal); -webkit-font-smoothing: antialiased;
}
button, input, textarea, select { font-family: inherit; font-size: inherit; color: inherit; letter-spacing: inherit; }
button { cursor: pointer; }
button:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
h1, h2, h3, h4 { font-family: var(--font-serif); letter-spacing: -0.02em; font-weight: 600; margin: 0; }
a { color: var(--primary); }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.hidden { display: none !important; }
::selection { background: var(--accent); color: var(--accent-foreground); }

/* The four label styles from the type scale. Sans, caps, tracked wider as the size drops. */
.eyebrow { font-family: var(--font-sans); font-size: 10px; line-height: 14px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted-foreground); }
.overline { font-family: var(--font-sans); font-size: 9px; line-height: 12px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted-foreground); }

@keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .3 } }
@keyframes rise { from { opacity: 0; transform: translateY(6px) } to { opacity: 1; transform: none } }
@keyframes sweep { 0% { transform: translateX(-100%) } 100% { transform: translateX(300%) } }
@keyframes spin { to { transform: rotate(360deg) } }
@media (prefers-reduced-motion: reduce) {
  .badge.busy .dot, .bar > div, .spin { animation: none !important; }
}

/* ── 3. App shell ───────────────────────────────────────────────────────── */
.shell { display: flex; height: 100vh; width: 100%; overflow: hidden; }
.railwrap { position: relative; flex: 0 0 var(--rail-width); height: 100%; z-index: 40; }
.rail {
  position: absolute; inset: 0 auto 0 0; width: var(--rail-width); height: 100%;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--sidebar); color: var(--sidebar-foreground); border-right: 1px solid var(--sidebar-border);
  transition: width 200ms ease-in-out;
}
.railwrap:hover .rail, .railwrap:focus-within .rail { width: var(--shell-width); box-shadow: var(--shadow-xl); }
.rail .rhead { display: flex; align-items: center; gap: 10px; height: 48px; padding: 0 16px; border-bottom: 1px solid var(--sidebar-border); flex: none; }
.rail .mark { width: 24px; height: 24px; flex: none; border-radius: var(--radius-md); background: var(--primary); color: var(--primary-foreground); display: grid; place-items: center; font-family: var(--font-serif); font-weight: 700; font-size: 13px; }
.rail .rname { min-width: 0; white-space: nowrap; opacity: 0; transition: opacity 150ms; }
.rail .rname .p { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted-foreground); }
.rail .rname .t { font-size: 12px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; }
.railwrap:hover .rname, .railwrap:focus-within .rname { opacity: 1; }
.rail nav { flex: 1; padding: 8px; display: flex; flex-direction: column; gap: 1px; overflow-y: auto; overflow-x: hidden; }
.rail .sec { height: 22px; padding: 8px 8px 0; font-size: 9px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--sidebar-section-fg); white-space: nowrap; opacity: 0; transition: opacity 150ms; }
.railwrap:hover .sec, .railwrap:focus-within .sec { opacity: 1; }
.rail .ni {
  position: relative; display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px; width: 100%;
  border: 0; border-radius: var(--radius-lg); background: none; text-align: left; text-decoration: none;
  color: var(--sidebar-nav-fg); font-family: var(--font-sans); font-size: 12px; font-weight: var(--sidebar-nav-weight);
  white-space: nowrap; cursor: pointer; transition: background-color 150ms, color 150ms;
}
.rail .ni svg { width: 16px; height: 16px; flex: none; opacity: var(--opacity-sidebar-icon); }
.rail .ni:hover { background: color-mix(in oklab, var(--sidebar-accent) 60%, transparent); color: var(--sidebar-accent-foreground); }
.rail .ni.on { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); font-weight: var(--sidebar-nav-active-weight); box-shadow: var(--shadow-sm); }
.rail .ni.on svg { opacity: 1; }
.rail .ni.on::before { content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%); height: 14px; width: 2px; border-radius: var(--radius-full); background: var(--primary); }
.rail .ni .lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; opacity: 0; transition: opacity 150ms; }
.rail .ni .cnt { opacity: 0; transition: opacity 150ms; }
.railwrap:hover .ni .lbl, .railwrap:focus-within .ni .lbl, .railwrap:hover .ni .cnt, .railwrap:focus-within .ni .cnt { opacity: 1; }
.rail .ni .dotbadge { position: absolute; top: 6px; right: 6px; min-width: 14px; height: 14px; padding: 0 4px; border-radius: var(--radius-full); background: var(--primary); color: var(--primary-foreground); font-family: var(--font-mono); font-size: 9px; font-weight: 600; display: flex; align-items: center; justify-content: center; }
.railwrap:hover .ni .dotbadge, .railwrap:focus-within .ni .dotbadge { position: static; min-width: 20px; height: 18px; font-size: 10px; }
.rail .rfoot { border-top: 1px solid var(--sidebar-border); padding: 8px; display: flex; flex-direction: column; gap: 1px; flex: none; }
.rail .rfoot .ni { color: var(--sidebar-util-fg); font-size: 11px; height: 30px; }
.rail .rfoot .ni:hover { color: var(--sidebar-foreground); }
.rail .rfoot .ni.danger:hover { color: var(--destructive); background: color-mix(in oklab, var(--destructive) 10%, transparent); }
.rail .who { padding: 6px 12px 2px; font-size: 10px; color: var(--sidebar-util-fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0; transition: opacity 150ms; }
.railwrap:hover .who, .railwrap:focus-within .who { opacity: 1; }

/* Theme menu, anchored to the rail's Theme row. */
.thememenu { position: fixed; z-index: 130; min-width: 220px; padding: 6px; background: var(--popover); color: var(--popover-foreground); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); animation: rise 140ms ease-out both; }
.thememenu .mh { padding: 6px 10px 4px; font-size: 9px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted-foreground); }
.thememenu .mi { display: flex; align-items: center; gap: 8px; width: 100%; padding: 7px 10px; border: 0; border-radius: var(--radius-md); background: none; text-align: left; font-size: 12px; color: inherit; }
.thememenu .mi:hover { background: var(--accent); color: var(--accent-foreground); }
.thememenu .mi.on { font-weight: 500; }
.thememenu .mi .sw { width: 12px; height: 12px; border-radius: var(--radius-full); border: 1px solid var(--border); flex: none; }
.thememenu .mi .tick { margin-left: auto; font-family: var(--font-mono); font-size: 11px; color: var(--primary); }
.thememenu .sep { height: 1px; background: var(--border); margin: 6px 4px; }

/* ── 3b. The Commerce OS look-alike shell (flag ui.commerceos_shell) ───────
   commerceos-shell.js writes the markup; this decides which shell shows. `html[data-shell]` is set
   before first paint by the inline script in each page's <head>. Numbers are ui/sidebar.tsx's
   Tailwind classes spelled out: rows px-2.5 py-1.5 (collapsed p-2), text-xs, gap-2, the 2px x 14px
   primary bar on the active row, section headings 9px caps at 0.16em, 220px / 56px (app-shell.tsx,
   in hover mode the panel floats over the page; in pinned mode the reserved space jumps and the panel
   animates its width over 200ms). */
html:not([data-shell="commerceos"]) .cosbar-wrap,
html:not([data-shell="commerceos"]) .walton,
html:not([data-shell="commerceos"]) .costools { display: none !important; }
html[data-shell="commerceos"] .railwrap { display: none; }
html[data-shell="commerceos"] .page { margin-right: 52px; }
.cosbar-wrap { position: relative; flex: 0 0 220px; width: 220px; height: 100%; z-index: 40; }
/* Reserved width, app-shell.tsx: hover mode (the default, preferences.sidebarHoverExpand) always
   reserves 56px and the 220px panel floats over the page on hover; pinned mode (the preference off,
   html[data-cos-pinned]) reserves what it shows, so the page slides. */
html:not([data-cos-pinned]) .cosbar-wrap, html[data-cos-pinned][data-cos-collapsed] .cosbar-wrap { flex-basis: 56px; width: 56px; }
.cosbar {
  position: relative; width: 220px; height: 100%; display: flex; flex-direction: column; overflow: hidden;
  background: var(--sidebar); border-right: 1px solid var(--sidebar-border); transition: width 200ms ease-in-out;
}
.cosbar-wrap.c .cosbar { width: 56px; }                     /* visually collapsed: set by commerceos-shell.js */
.cosbar-wrap.ov .cosbar { position: absolute; top: 0; bottom: 0; left: 0; z-index: 40; box-shadow: var(--shadow-xl); }
html:not([data-cos-pinned]) .cosbar #cb-collapse { display: none !important; }   /* hover mode: onToggle is undefined */
.cosbar-wrap.c .cosbar .x-only, .cosbar-wrap:not(.c) .cosbar .c-only { display: none !important; }

.cosbar .cb-head { display: flex; align-items: center; gap: 10px; padding: 12px; border-bottom: 1px solid var(--sidebar-border); flex: none; }
.cosbar-wrap.c .cosbar .cb-head { justify-content: center; padding: 12px 0; gap: 0; }
.cosbar .cb-logo { height: 24px; width: auto; max-width: 90px; object-fit: contain; flex: none; filter: brightness(0); }
.cosbar-wrap.c .cosbar .cb-logo { width: 24px; }
.cosbar .cb-logo[hidden] { display: none; }
.cosbar .cb-logo-fallback:not([hidden]) { display: inline-flex; align-items: center; height: 24px; font-family: var(--font-sans); font-weight: 700; font-size: 15px; letter-spacing: -0.02em; color: var(--foreground); flex: none; }
.cosbar .cb-org { flex: 1; min-width: 0; }
.cosbar .cb-org p { margin: 0; font-family: var(--font-sans); font-size: 10px; line-height: 15px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-foreground); }

.cosbar .cb-nav { flex: 1; min-height: 0; padding: 8px 6px; display: flex; flex-direction: column; gap: 1px; overflow-y: auto; overflow-x: hidden; font-weight: var(--sidebar-nav-weight); }
.cosbar-wrap.c .cosbar .cb-nav { padding: 8px; }
.cosbar .cb-nav > div { display: flex; flex-direction: column; gap: 1px; }
.cosbar .cb-sec { margin: 0; padding: 10px 8px 2px; font-family: var(--font-sans); font-size: 9px; line-height: 13.5px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--sidebar-section-fg); white-space: nowrap; }

.cosbar .cb-row {
  position: relative; display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 10px;
  border: 0; border-radius: var(--radius); background: none; text-align: left; text-decoration: none; cursor: pointer;
  font-family: var(--font-sans); font-size: 12px; line-height: 16px; font-weight: inherit; color: var(--sidebar-nav-fg);
  transition: background-color 150ms, color 150ms, box-shadow 150ms;
}
.cosbar-wrap.c .cosbar .cb-row { justify-content: center; padding: 8px; gap: 0; }
.cosbar .cb-row:hover { background: color-mix(in oklab, var(--sidebar-accent) 60%, transparent); color: var(--sidebar-accent-foreground); }
.cosbar .cb-row:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
.cosbar .cb-row .cb-ic { flex: none; opacity: var(--opacity-sidebar-icon); }
.cosbar .cb-row .cb-ic.full { opacity: 1; }
.cosbar .cb-row.on { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); font-weight: var(--sidebar-nav-active-weight); box-shadow: var(--shadow-sm); }
.cosbar .cb-row.on .cb-ic { opacity: 1; }
.cosbar .cb-row.on::before { content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%); height: 14px; width: 2px; border-radius: var(--radius-full); background: var(--primary); }
.cosbar .cb-lbl { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; overflow: hidden; }
.cosbar .cb-lbl .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cosbar .cb-beta { display: inline-flex; flex: none; align-items: center; padding: 1px 4px; border-radius: 4px; border: 1px solid color-mix(in oklab, var(--border) 70%, transparent); background: color-mix(in oklab, var(--background) 80%, transparent); font-size: 8px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: color-mix(in oklab, var(--muted-foreground) 90%, transparent); }
.cosbar .cb-chip { display: inline-flex; flex: none; align-items: center; gap: 4px; padding: 1px 6px; border-radius: var(--radius-full); font-size: 9px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }
.cosbar .cb-chip .d { width: 6px; height: 6px; border-radius: var(--radius-full); }
.cosbar .cb-chip.live { background: var(--success-soft); color: var(--success-text); }
.cosbar .cb-chip.live .d { background: var(--score-excellent); animation: cospulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
.cosbar .cb-chip.paused { background: var(--muted); color: var(--muted-foreground); }
.cosbar .cb-chip.paused .d { background: color-mix(in oklab, var(--muted-foreground) 50%, transparent); }
.cosbar .cb-on { width: 6px; height: 6px; flex: none; border-radius: var(--radius-full); background: color-mix(in oklab, var(--score-excellent) 80%, transparent); }
.cosbar .cb-cdot { position: absolute; top: 4px; right: 4px; width: 6px; height: 6px; border-radius: var(--radius-full); background: var(--score-excellent); }
.cosbar .cb-cdot.paused { background: color-mix(in oklab, var(--muted-foreground) 50%, transparent); }
@keyframes cospulse { 50% { opacity: .5; } }
.cosbar .cb-chev { flex: none; opacity: var(--opacity-sidebar-icon-muted); transition: transform 150ms; }
.cosbar .cb-group[aria-expanded="true"] .cb-chev { transform: rotate(180deg); }
.cosbar .cb-kids:not([hidden]) { display: flex; flex-direction: column; gap: 1px; margin-top: 1px; padding-left: 12px; }

.cosbar .cb-foot { flex: none; border-top: 1px solid var(--sidebar-border); padding: 8px 6px; display: flex; flex-direction: column; gap: 1px; font-weight: var(--sidebar-nav-weight); }
.cosbar-wrap.c .cosbar .cb-foot { padding: 8px; align-items: center; }
.cosbar .cb-foot .cb-row { line-height: 1.5; }
.cosbar .cb-flab { flex: 1; font-size: 12px; }
.cosbar .cb-ext { flex: none; opacity: .6; }
.cosbar .cb-util { color: var(--sidebar-util-fg); }
.cosbar .cb-util:hover { color: var(--sidebar-foreground); }
.cosbar .cb-ulab { font-size: 11px; }
.cosbar .cb-out:hover { color: var(--destructive); background: color-mix(in oklab, var(--destructive) 10%, transparent); }

/* The closed Agent Walton rail, features/agent/agent-sidebar.tsx. */
.walton { position: fixed; top: 0; right: 0; bottom: 0; width: 52px; z-index: 30; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 16px 0; background: var(--background); }
.walton button { display: grid; place-items: center; width: 36px; height: 36px; padding: 0; border: 0; cursor: pointer; transition: background-color 150ms, color 150ms, box-shadow 150ms; }
.walton .wa-main { border-radius: 12px; background: linear-gradient(to bottom right, var(--primary), color-mix(in oklab, var(--primary) 70%, transparent)); color: var(--primary-foreground); box-shadow: var(--shadow-sm); }
.walton .wa-main:hover { box-shadow: var(--shadow-md); }
.walton .wa-btn { border-radius: var(--radius-lg); background: none; color: var(--muted-foreground); }
.walton .wa-btn:hover { color: var(--foreground); background: color-mix(in oklab, var(--secondary) 60%, transparent); }
.walton .wa-foot { margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.walton .wa-name { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; color: color-mix(in oklab, var(--muted-foreground) 60%, transparent); transform: rotate(-90deg); margin-bottom: 12px; }
.walton .wa-dot { width: 6px; height: 6px; border-radius: var(--radius-full); background: var(--score-excellent); }

/* The ContentOS tools while the look-alike is on: one header button, a menu cloned from the rail. */
.costoolsmenu .mi svg { width: 16px; height: 16px; flex: none; opacity: .8; }
.costoolsmenu .mi .tick { font-family: var(--font-mono); }
#costoast[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .cosbar, .cosbar .cb-chip.live .d { transition: none; animation: none; } }

.page { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; overflow: hidden; }
.pagehead { background: var(--background); flex: none; padding: 10px 24px; }
.pagehead .cos-page-header__title { font-size: 20px; }
.pagehead .cos-page-header__actions { flex-wrap: wrap; justify-content: flex-end; }
.pagehead .cos-page-header__actions > * { flex: none; }
.pagehead select, .pagehead .runbtn {
  height: 32px; padding: 0 10px; border: 1px solid var(--input); border-radius: var(--radius-lg);
  background: var(--card); color: var(--foreground); font-family: var(--font-sans); font-size: 12px; font-weight: 500;
}
.pagehead select:focus, .pagehead .runbtn:focus-visible { outline: none; box-shadow: 0 0 0 2px color-mix(in oklab, var(--ring) 20%, transparent); }
.pagescroll { flex: 1; min-height: 0; overflow: auto; }

/* ── 4. Primitives shared by every page ─────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 36px; padding: 0 14px;
  border: 1px solid transparent; border-radius: var(--radius-lg); background: var(--primary); color: var(--primary-foreground);
  font-weight: 500; font-size: 13px; line-height: 1; white-space: nowrap; transition: background-color 150ms, color 150ms, opacity 150ms;
}
.btn:hover:not(:disabled) { opacity: .9; }
.btn:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.btn.sm, .btn.small { height: 30px; padding: 0 11px; font-size: 12px; }
.btn.outline { background: transparent; color: var(--foreground); border-color: var(--border); }
.btn.outline:hover:not(:disabled) { opacity: 1; background: color-mix(in oklab, var(--secondary) 30%, transparent); }
.btn.ghost { background: transparent; color: var(--foreground); }
.btn.ghost:hover:not(:disabled) { opacity: 1; background: color-mix(in oklab, var(--secondary) 50%, transparent); }
.btn.secondary { background: var(--secondary); color: var(--secondary-foreground); border-color: var(--border); }
.btn.secondary:hover:not(:disabled) { opacity: 1; background: color-mix(in oklab, var(--secondary) 80%, transparent); }
.btn.full { width: 100%; }
.btn .ic { font-size: 13px; line-height: 1; }
.linkbtn { background: none; border: 0; padding: 0; color: var(--primary); font-size: 12px; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.linkbtn:hover { color: var(--accent-foreground); }

.badge {
  display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px; border-radius: var(--radius-full);
  border: 1px solid var(--border); background: transparent; color: var(--muted-foreground);
  font-size: 11.5px; font-weight: 500; letter-spacing: 0.02em; white-space: nowrap;
}
/* `hidden` must win over the inline-flex above: landing.html hides its spend badge that way when
   ui.costs is off, and without this the placeholder "…" showed through. */
.badge[hidden] { display: none; }
.badge .dot { width: 6px; height: 6px; border-radius: var(--radius-full); background: currentColor; }
.badge.ok { background: var(--success-soft); color: var(--success-text); border-color: var(--success-border); }
.badge.warn { background: var(--warning-soft); color: var(--warning-text); border-color: var(--warning-border); }
.badge.bad { background: var(--danger-soft); color: var(--danger-text); border-color: var(--danger-border); }
.badge.info { background: var(--accent); color: var(--accent-foreground); border-color: color-mix(in oklab, var(--accent-foreground) 25%, transparent); }
.badge.busy .dot { animation: pulse 1s infinite; }
.badge.solid.ok { background: var(--score-excellent); color: var(--primary-foreground); border-color: transparent; }
.badge.solid.bad { background: var(--destructive); color: var(--destructive-foreground); border-color: transparent; }

textarea, input.text, input:not([type]), input[type=text], input[type=password], input[type=search] {
  width: 100%; border: 1px solid var(--input); border-radius: var(--radius-lg); padding: 7px 10px;
  background: var(--card); color: var(--foreground); font-size: 13px; line-height: 1.45; resize: vertical;
}
textarea::placeholder, input::placeholder { color: var(--muted-foreground); }
textarea:focus, input.text:focus, input:not([type]):focus, input[type=text]:focus, input[type=password]:focus, input[type=search]:focus, select:focus {
  outline: none; border-color: var(--ring); box-shadow: 0 0 0 2px color-mix(in oklab, var(--ring) 20%, transparent);
}
select { border: 1px solid var(--input); border-radius: var(--radius-lg); background: var(--card); color: var(--foreground); padding: 4px 8px; }
input[type=checkbox], input[type=radio] { accent-color: var(--primary); }
input[type=range] { accent-color: var(--primary); }
code { font-family: var(--font-mono); font-size: 12px; background: var(--secondary); padding: 1px 5px; border-radius: var(--radius-sm); }

.card, aside section, main section { background: var(--card); color: var(--card-foreground); border: 1px solid var(--border); border-radius: var(--radius-lg); }
p.help, .help { font-size: 12px; color: var(--muted-foreground); line-height: 1.5; margin: 0 0 8px; }
.toast { position: fixed; left: 50%; bottom: 76px; transform: translateX(-50%); background: var(--foreground); color: var(--background); padding: 9px 14px; border-radius: var(--radius-full); font-size: 13px; z-index: 70; animation: rise 140ms ease-out both; box-shadow: var(--shadow-lg); }

/* Overlays and modals: popover plane, lg shadow, per the elevation rule. */
.overlay { position: fixed; inset: 0; background: color-mix(in oklab, var(--foreground) 55%, transparent); z-index: 60; display: flex; align-items: center; justify-content: center; padding: 24px; }
.modal { background: var(--popover); color: var(--popover-foreground); border: 1px solid var(--border); border-radius: var(--radius-xl); width: min(1180px, 100%); max-height: 92vh; overflow: auto; box-shadow: var(--shadow-lg); animation: rise 160ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.modal.small { width: min(660px, 100%); }
.modal .pad { padding: 20px; }
.modal .head { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.modal .head .n { font-family: var(--font-mono); font-size: 13px; }
.modal .head .f { font-size: 12px; color: var(--muted-foreground); flex: 1; }
.modal .head button.ic { width: 30px; height: 30px; border-radius: var(--radius-full); border: 1px solid var(--border); background: var(--card); color: var(--foreground); }
.cardhead { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.cardhead .t { flex: 1; font-family: var(--font-serif); font-size: 16px; line-height: 24px; font-weight: 500; letter-spacing: -0.02em; }

/* Metric tile, as in ui/metric-card.tsx. */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.stats > div, .stat { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--card); padding: 8px 4px; text-align: center; min-width: 0; overflow: hidden; }
.stats .k, .stat .k { font-size: 9px; line-height: 14px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted-foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stats .v, .stat .v { font-family: var(--font-serif); font-size: 22px; line-height: 28px; font-weight: 600; letter-spacing: -0.025em; }

/* Tables */
table.tim { width: 100%; border-collapse: collapse; font-size: 13px; }
table.tim th { text-align: left; font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-foreground); font-weight: 500; padding: 6px 8px; border-bottom: 1px solid var(--border); }
table.tim td { padding: 7px 8px; border-bottom: 1px solid var(--border); font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums; }

/* Narrow windows: the rail stays, the page header sheds labels. */
@media (max-width: 1180px) {
  .pagehead .btn .lbl { display: none; }
  .pagehead select { max-width: 150px; }
}
@media (max-width: 820px) {
  .shell { height: auto; min-height: 100vh; overflow: visible; }
  .page { height: auto; overflow: visible; }
  .pagescroll { overflow: visible; }
}

/* ── 5. Loading states ──────────────────────────────────────────────────────
   From the design system's motion vocabulary (design-system/motion.md): a shimmer for content that
   is on its way (pim-shimmer), and `agent-stream` (520ms, 8px rise, blur clearing) reserved for text
   a model produced. A running indicator must still say "running" under reduced motion, so the
   shimmer degrades to a flat tint, never to nothing.

   Images: every <img> carries the shimmer as its own background until contentos.js marks it
   `.loaded` (or `.failed`). A loaded opaque image covers its background, so a cached image that is
   re-rendered never flickers; the animation is stopped once loaded so a grid of tiles costs nothing. */
@keyframes cos-shimmer { from { background-position: 150% 0; } to { background-position: -50% 0; } }
@keyframes agent-stream { from { opacity: 0; transform: translateY(8px); filter: blur(4px); } 60% { filter: blur(0); } to { opacity: 1; transform: none; filter: none; } }
@keyframes agent-thinking-dot { 0%, 100% { opacity: .25; transform: none; } 50% { opacity: 1; transform: translateY(-2px); } }

.skel, img:not(.loaded):not(.failed):not(.noskel) {
  background-color: var(--muted);
  background-image: linear-gradient(90deg, transparent 0%, color-mix(in oklab, var(--card) 70%, transparent) 50%, transparent 100%);
  background-size: 50% 100%;
  background-repeat: no-repeat;
  animation: cos-shimmer 1.4s linear infinite;
}
img.loaded { animation: none; }
/* Alt text belongs to a failed image, not to one still loading or not yet given a src. */
img:not(.loaded):not(.failed) { color: transparent; }
img.failed { animation: none; opacity: 0; }                 /* the container says why, not a broken-image icon */
.img-failed { background: var(--muted); }
.img-failed { position: relative; }
.img-failed::after {
  content: "Image unavailable"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  padding: 6px; text-align: center; font-size: 10.5px; line-height: 1.3; color: var(--muted-foreground); pointer-events: none;
}
/* Text skeleton: a bar the height of the line it stands in for. */
.skel { color: transparent !important; border-radius: var(--radius-sm); user-select: none; }
.skel-line { display: block; height: 10px; margin: 6px 0; border-radius: var(--radius-sm); }
.skel-line.w90 { width: 90%; } .skel-line.w75 { width: 75%; } .skel-line.w60 { width: 60%; } .skel-line.w40 { width: 40%; }
.skel-card { border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; background: var(--card); }
.skel-card .skel-ph { aspect-ratio: 4/5; }
.skel-card .skel-t { padding: 9px 11px 11px; }

/* Thinking dots: the wait before an agent's first words (agent-thinking-dot, 1.1s staggered). */
.thinking { display: inline-flex; gap: 3px; vertical-align: middle; margin-left: 4px; }
.thinking i { width: 4px; height: 4px; border-radius: 50%; background: currentColor; animation: agent-thinking-dot 1.1s ease-in-out infinite; }
.thinking i:nth-child(2) { animation-delay: .18s; } .thinking i:nth-child(3) { animation-delay: .36s; }

/* Agent output arriving. */
.agent-stream { animation: agent-stream 520ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }

@media (prefers-reduced-motion: reduce) {
  .skel, img:not(.loaded):not(.failed):not(.noskel) { animation: none; background-image: none; background-color: color-mix(in oklab, var(--muted) 80%, var(--primary) 6%); }
  .thinking i { animation: none; opacity: .6; }
  .agent-stream { animation: none; }
}

/* ── 6. Client view ─────────────────────────────────────────────────────────
   One per-browser switch (Settings > Interface) for recording or showing the app to a client. It
   hides everything internal: model and provider names, the GPU, the pipeline log, feature flags,
   mask tuning, raw fields, file paths, the demo-brief labels, the demo shelf. Applied as
   html[data-client] by a pre-paint script, so a recording never shows a frame of the internals.
   Mark static markup with .internal (hidden) or pair .internal / .client-only spans (reworded). */
.client-only { display: none !important; }
html[data-client] .client-only { display: revert !important; }
html[data-client] .internal { display: none !important; }
html[data-client] .st-row .src { display: none; }
