/* ───────────────────────────────────────────────────────────────────────────
   Shared design tokens and the primitives both pages use.

   Colours are not chosen by eye. The three provider hues are validated
   dark-mode categorical slots (aqua / blue / orange) and clear the CVD and
   normal-vision separation gates on every pair against the #14161a card
   surface. Ink and status steps are picked for >=4.5:1 on that surface:
   --text-3 measures 5.06:1 and --crit 5.61:1, where the more obvious #6b727c
   and #d03b3b both land near 3.7:1 and fail as small text.

   One system sans, no webfont — the previous three Google families were both a
   third-party request from an internal tool and the main reason the UI read as
   generic. Mono is reserved for identifiers and for figures that align in a
   column; large standalone numbers keep proportional figures, because tabular
   digits make a value like 121 look gappy at display size.
   ─────────────────────────────────────────────────────────────────────────── */
:root{
  --bg:#0b0c0e;
  --surface:#14161a;
  --surface-2:#1b1e23;
  --line:#23262c;
  --line-2:#2f333a;

  --text:#e8eaed;
  --text-2:#9aa1ab;
  --text-3:#818892;

  --accent:#3987e5;
  --good:#0ca30c;
  --warn:#fab219;
  --crit:#e66767;

  /* Control fills. Every small action used to be a transparent box with a hairline
     border and --text-3 text, which is the same treatment this UI gives *disabled*
     things — so "Save", "start", "end", "Open library" and the rest read as labels
     rather than as buttons. A control now has a fill that separates it from the card
     it sits on (1.36:1, the smallest step that is actually perceptible here) and a
     label at --text-2 rather than --text-3.

     These are neutral steps, not new identity colours: the three-hue rule is about
     hues carrying meaning, and --surface / --surface-2 already establish the ladder.

     --crit is NOT usable on a control fill — #e66767 measures 4.11:1 there and fails
     as small text — so destructive controls use the lighter tint, which clears 4.5:1
     on both the resting and the hover fill. */
  --control:#2b3038;
  --control-hover:#373d46;
  --control-line:#434a54;
  --crit-on-control:#f08c8c;

  --openai:#199e70;
  --gemini:#3987e5;
  --veo:#d95926;

  --sans:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --mono:ui-monospace,'SF Mono',Menlo,Consolas,monospace;

  --fs-xs:11px; --fs-sm:12px; --fs-md:13px; --fs-lg:15px; --fs-xl:20px; --fs-2xl:28px;
  --r:10px; --r-sm:6px;
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--bg);color:var(--text);
  font-family:var(--sans);font-size:var(--fs-md);line-height:1.5;
  -webkit-font-smoothing:antialiased;
  display:flex;flex-direction:column;
}
a{color:var(--accent);text-decoration:none}
button{cursor:pointer;font-family:inherit;font-size:inherit;color:inherit}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
::selection{background:rgba(57,135,229,.3)}

/* ── Topbar ── */
.topbar{
  flex:none;height:52px;display:flex;align-items:center;gap:24px;
  padding:0 20px;border-bottom:1px solid var(--line);background:var(--bg);
}
/* The wordmark is a link (home, and a filter reset on the dashboard), so it has
   to opt out of the global anchor colour — a blue product name reads as a stray
   link rather than the identity of the page. */
.brand{
  font-size:var(--fs-md);font-weight:600;letter-spacing:-.01em;white-space:nowrap;
  color:var(--text);text-decoration:none;
}
.brand:hover{color:var(--text)}
.brand span{color:var(--text-3);font-weight:400;margin-left:8px}
.nav{display:flex;gap:2px;align-items:center}
.nav a{font-size:var(--fs-md);padding:6px 10px;border-radius:var(--r-sm);color:var(--text-2)}
.nav a:hover{color:var(--text);background:var(--surface-2)}
.nav a[aria-current="page"]{color:var(--text);background:var(--surface-2)}
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:12px}

/* ── Buttons ── */
.btn-primary{
  background:var(--text);color:var(--bg);font-weight:500;font-size:var(--fs-md);
  padding:8px 16px;border:none;border-radius:var(--r-sm);white-space:nowrap;
  display:inline-flex;align-items:center;gap:7px;
}
.btn-primary:hover{background:#fff}
.btn-primary:disabled{opacity:.4;cursor:not-allowed}
.btn-secondary{
  background:transparent;color:var(--text-2);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:8px 14px;font-size:var(--fs-md);
}
.btn-secondary:hover{color:var(--text);border-color:var(--line-2)}

/* ── Status — always a mark AND a word, never colour alone ── */
.status{display:inline-flex;align-items:center;gap:5px;font-size:var(--fs-xs);color:var(--text-2);flex:none}
.status .dot{width:6px;height:6px;border-radius:50%;flex:none;background:var(--text-3)}
.status.done .dot{background:var(--good)}
.status.running .dot{background:var(--warn);animation:blink 1.4s ease-in-out infinite}
.status.error .dot{background:var(--crit)}
.status.error{color:var(--crit)}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.35}}

/* ── Live indicator ── */
.live{display:flex;align-items:center;gap:7px;font-size:var(--fs-sm);color:var(--text-3)}
.live .dot{width:6px;height:6px;border-radius:50%;background:var(--text-3);flex:none}
.live.on{color:var(--text-2)}
.live.on .dot{background:var(--good)}
/* Degraded, not dead: the stream is down or stalled and the page is polling
   instead. Worth showing, because it used to claim "Live" either way. */
.live.warn{color:var(--text-2)}
.live.warn .dot{background:var(--warn)}

/* ── Small actions ──
   One treatment for every small clickable thing on all three pages, listed here rather
   than restyled per page because there were eight different versions of "small button"
   and no two of them looked alike.

   The selector list is the affordance contract: if something is clickable and it is not
   one of the two big buttons above, it belongs in here. Page stylesheets load after
   this one, so they keep only position — margin, grid placement, order — and must not
   set background, border, colour or padding for these.

   Minimum target is 26px tall. The old .tovid links were 15px, which is under any
   reasonable touch or trackpad target. */
.dl, .tovid a, .tbtn, .chip, .lb .x,
.mlist-add, .mlist-del, .fs-clear, .fs-del, .file-clear, .preset-btn, .sm-manage,
.btn, .new-btn {
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-height:26px;padding:4px 10px;
  background:var(--control);color:var(--text-2);
  border:1px solid var(--control-line);border-radius:var(--r-sm);
  font-family:inherit;font-size:var(--fs-sm);line-height:1.3;
  text-decoration:none;white-space:nowrap;cursor:pointer;
  transition:background .12s,color .12s,border-color .12s;
}
.dl:hover, .tovid a:hover, .tbtn:hover, .chip:hover, .lb .x:hover,
.mlist-add:hover:not(:disabled), .mlist-del:hover:not(:disabled), .fs-clear:hover,
.fs-del:hover, .file-clear:hover, .preset-btn:hover, .sm-manage:hover,
.btn:hover:not(:disabled), .new-btn:hover {
  background:var(--control-hover);color:var(--text);border-color:var(--text-3);
}
/* Pressed state. Without it a click on a control that navigates or posts gives no
   feedback at all until the page changes. */
.dl:active, .tovid a:active, .tbtn:active, .chip:active,
.mlist-add:active, .fs-clear:active, .preset-btn:active, .btn:active, .new-btn:active {
  background:var(--control);
}
.mlist-add:disabled, .mlist-del:disabled, .btn:disabled, .tbtn:disabled {
  opacity:.45;cursor:not-allowed;
}
/* Destructive ones announce themselves on hover rather than sitting there red: at rest
   they are ordinary controls, so a row of them does not read as a row of warnings. */
.fs-clear:hover, .fs-del:hover, .file-clear:hover, .mlist-del:hover:not(:disabled),
.preset-btn.del:hover, .btn.danger:hover, .tbtn.danger:hover {
  color:var(--crit-on-control);border-color:var(--crit);
}
/* Icon-only controls are square, so the glyph is centred rather than sitting in a box
   that is wider than it is tall. */
.fs-del, .mlist-del, .lb .x.icon { width:26px;padding:0 }

@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
