/* ============================================================================
   svid.ai design system — the violet brand over a blue-graphite base: the look
   of night monitoring gear, not a generic dark SaaS theme. Violet is the single
   signal accent; the cool gradient (--grad) is reserved for the wordmark,
   primary CTAs and active-nav accents; red is REC/alert only.
   Rules: animate transform/opacity only · three durations (fast/med/slow) ·
   spring easing reserved for pops (badges, chips, toasts).
   ========================================================================== */

/* Self-hosted — no CDN. Bricolage Grotesque (display), Hanken Grotesk (body),
   Space Mono (timecode/IDs). Bricolage + Hanken ship as variable woff2. */
@font-face {
  font-family:"Bricolage Grotesque"; font-style:normal; font-weight:400 800; font-display:swap;
  src:url("/fonts/bricolage-grotesque.woff2") format("woff2");
}
@font-face {
  font-family:"Hanken Grotesk"; font-style:normal; font-weight:400 700; font-display:swap;
  src:url("/fonts/hanken-grotesk.woff2") format("woff2");
}
@font-face {
  font-family:"Space Mono"; font-style:normal; font-weight:400; font-display:swap;
  src:url("/fonts/space-mono-400.woff2") format("woff2");
}
@font-face {
  font-family:"Space Mono"; font-style:normal; font-weight:700; font-display:swap;
  src:url("/fonts/space-mono-700.woff2") format("woff2");
}

/* Two palettes share every rule below via CSS custom properties. Dark is the
   default (:root); light overrides only the colour tokens. The active theme is
   stamped on <html> before first paint (inline script in index.html). Anything
   painted over video footage (letterbox #000, scrim whites) stays fixed. */
:root {
  --bg0:#0a0c10; --bg1:#111419; --bg2:#161a20; --bg3:#1f242c;
  --hairline:rgba(236,232,222,.09); --hairline-strong:rgba(236,232,222,.17);
  --text:#ece8de; --text2:#8b94a0; --text3:#636d7a;
  --accent:#a78bfa; --accent2:#7c5cf6;  /* violet · violet-deep (hover/anchor) */
  --brand-violet:#8b3fd6; --brand-blue:#3b82f6; --brand-cyan:#43c6ff;
  --grad:linear-gradient(120deg,var(--brand-violet),var(--brand-blue),var(--brand-cyan));
  --accent-soft:rgba(167,139,250,.13); --accent-ring:rgba(167,139,250,.5);
  --on-accent:#ffffff;                  /* white ink on the cool-gradient fill */
  --ok:#34c98e; --ok-soft:rgba(52,201,142,.14);
  --warn:#e6a12f; --warn-soft:rgba(230,161,47,.14);
  --danger:#ff5a4d; --danger-soft:rgba(255,90,77,.14);
  --live:#ff5a4d;                       /* REC — red, alert-only */
  --rail-blur:rgba(17,20,25,.92);       /* translucent chrome fills */
  --font:"Hanken Grotesk",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --font-display:"Bricolage Grotesque",var(--font);
  --mono:"Space Mono",ui-monospace,"SF Mono",Menlo,monospace;
  --r-s:6px; --r-m:10px; --r-l:14px;    /* tight equipment bezels, not soft cards */
  --sh-1:0 1px 2px rgba(0,0,0,.5);
  --sh-2:inset 0 1px 0 rgba(236,232,222,.04), 0 8px 24px rgba(0,0,0,.4);
  --sh-3:inset 0 1px 0 rgba(236,232,222,.05), 0 24px 64px rgba(0,0,0,.6);
  --glow:0 0 44px -10px rgba(167,139,250,.5);  /* violet standby glow */
  --t-fast:120ms; --t-med:200ms; --t-slow:320ms;
  --ease-out:cubic-bezier(.2,.8,.2,1);
  --ease-spring:cubic-bezier(.34,1.56,.64,1);
  --rail-w:216px;
  --tabbar-h:calc(58px + env(safe-area-inset-bottom));
}

/* Light — the violet grade in daylight: warm bone canvas, near-white panels,
   the accent deepened so it stays legible as link text. */
:root[data-theme="light"] {
  --bg0:#efeae0; --bg1:#fbf8f2; --bg2:#f3eee3; --bg3:#e7e0d1;
  --hairline:rgba(60,48,24,.12); --hairline-strong:rgba(60,48,24,.2);
  --text:#23201a; --text2:#6b6456; --text3:#948c7a;
  --accent:#7c5cf6; --accent2:#6035d6;
  --accent-soft:rgba(124,92,246,.13); --accent-ring:rgba(124,92,246,.42);
  --on-accent:#ffffff;
  --ok:#12996b; --ok-soft:rgba(18,153,107,.13);
  --warn:#a86a00; --warn-soft:rgba(168,106,0,.15);
  --danger:#d13a2e; --danger-soft:rgba(209,58,46,.12);
  --live:#d13a2e;
  --rail-blur:rgba(251,248,242,.85);
  --sh-1:0 1px 2px rgba(60,48,24,.08);
  --sh-2:0 8px 24px rgba(60,48,24,.12);
  --sh-3:0 24px 64px rgba(60,48,24,.2);
  --glow:0 0 40px -12px rgba(124,92,246,.4);
}

* { box-sizing:border-box; margin:0; -webkit-tap-highlight-color:transparent; }
[hidden] { display:none !important; }
html { scrollbar-color:var(--bg3) transparent; }
/* Contain horizontal overflow so a too-wide descendant can never make the whole
   page pan sideways — which iOS renders as "slightly zoomed in". `clip` (not
   `hidden`) so neither element becomes a scroll container: the mobile sticky
   rail and the desktop sticky player keep working. Pairs with maximum-scale=1
   in index.html, which stops the zoom-on-input-focus half of the same bug. */
html, body { overflow-x:clip; }
body {
  /* Violet standby-glow — faint logo-spectrum washes over the graphite base. */
  background:
    radial-gradient(60rem 32rem at 50% -12rem, rgba(139,63,214,.14), transparent 66%),
    radial-gradient(44rem 30rem at 88% 2%, rgba(59,130,246,.12), transparent 62%),
    var(--bg0);
  background-repeat:no-repeat; background-attachment:fixed;
  color:var(--text); font:14px/1.55 var(--font); -webkit-font-smoothing:antialiased;
}
::selection { background:var(--accent-soft); color:var(--text); }
a { color:var(--accent); text-decoration:none; cursor:pointer; }
img { max-width:100%; }
::-webkit-scrollbar { width:10px; height:10px; }
::-webkit-scrollbar-thumb { background:var(--bg3); border-radius:6px; }
:focus-visible { outline:2px solid var(--accent-ring); outline-offset:2px; }
.i { width:18px; height:18px; flex-shrink:0; }
.i-sm { width:14px; height:14px; vertical-align:-2px; }
b { font-weight:650; }
.mono, .ts, .kbd, .meta-chip { font-family:var(--mono); font-variant-numeric:tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration:.01ms !important; transition-duration:.01ms !important; }
}

/* Touch hygiene: no double-tap-zoom delay heuristics on interactive elements
   (scroll/pinch unaffected), and inner scrollers keep their rubber-band to
   themselves instead of chaining it into the page. Press states (:active) live
   at the bottom of this sheet; every :hover is guarded behind @media(hover:hover). */
a, button, [data-action], label, select, summary { touch-action:manipulation; }
.strip, .chat-log, .ibx-list, .ap--compact .ap-list, .menu, .ce-card,
#quicklook, .confirm-wrap { overscroll-behavior:contain; }

/* ---- shell ---------------------------------------------------------------- */
/* The rail is position:fixed (out of flow) on desktop; a bottom tab bar takes
   over on mobile. Signed out (body.anon) the chrome hides entirely — the login
   card is the whole screen. */
#shell { min-height:100dvh; }
#rail {
  position:fixed; inset:0 auto 0 0; width:var(--rail-w); z-index:30;
  background:var(--bg1); border-right:1px solid var(--hairline);
  display:flex; flex-direction:column;
  padding:calc(18px + env(safe-area-inset-top)) 12px calc(14px + env(safe-area-inset-bottom)) calc(12px + env(safe-area-inset-left));
}
body.anon #rail, body.anon #tabbar { display:none; }
body.anon #content { margin-left:0; padding-bottom:24px; }
/* Public (logged-out) top bar — only on a public content view. */
#anon-bar { display:none; }
body.anon-pub #anon-bar {
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  position:sticky; top:0; z-index:30;
  padding:calc(10px + env(safe-area-inset-top)) 16px 10px;
  background:var(--rail-blur); backdrop-filter:blur(12px) saturate(1.2);
  border-bottom:1px solid var(--hairline);
}
body.anon-pub #anon-bar .brand-row { text-decoration:none; color:inherit; }
body.anon-pub #content { margin-left:0; }
.brand { padding:2px 10px 16px; }
.brand-row { display:flex; align-items:center; gap:9px; }
.brand-logo { width:28px; height:28px; border-radius:7px; flex-shrink:0; }
.wordmark {
  font-family:var(--font-display); font-size:19px; font-weight:600; letter-spacing:-.02em;
  color:var(--text);
}
.wm-dot { color:var(--accent); }
.tagline { color:var(--text3); font-size:11.5px; margin-top:3px; }

/* ---- theme toggle (rail footer) --------------------------------------------
   Both icons + labels are in the DOM; CSS shows whichever matches the state to
   switch TO, keyed off <html data-theme>, so core.js only flips the attribute. */
.theme-toggle {
  margin:10px 4px 0; display:flex; align-items:center; gap:9px; padding:8px 10px;
  border:1px solid var(--hairline); border-radius:9px; background:none; cursor:pointer;
  color:var(--text2); font:500 13px var(--font); text-align:left;
  transition:background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
@media (hover:hover) { .theme-toggle:hover { background:var(--bg3); color:var(--text); border-color:var(--hairline-strong); } }
.theme-toggle .i { width:16px; height:16px; }
.theme-toggle .theme-i-moon, .theme-toggle .tt-dark { display:none; }
:root[data-theme="light"] .theme-toggle .theme-i-sun,
:root[data-theme="light"] .theme-toggle .tt-light { display:none; }
:root[data-theme="light"] .theme-toggle .theme-i-moon { display:block; }
:root[data-theme="light"] .theme-toggle .tt-dark { display:inline; }

#nav { position:relative; display:flex; flex-direction:column; gap:2px; }
#nav a {
  display:flex; align-items:center; gap:11px; padding:9px 10px; border-radius:9px;
  color:var(--text2); font-weight:500; font-size:14px; position:relative;
  transition:color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out);
}
@media (hover:hover) { #nav a:hover { color:var(--text); background:var(--bg3); } }
#nav a.active { color:var(--text); background:var(--accent-soft); }
#nav-indicator {
  position:absolute; left:-6px; width:3px; height:16px; border-radius:3px;
  background:var(--grad); top:11px; opacity:0;
  transition:transform var(--t-med) var(--ease-out), opacity var(--t-med);
}
#nav .navbadge { margin-left:auto; }
.navbadge {
  min-width:18px; height:18px; padding:0 5px; border-radius:9px; background:var(--danger);
  color:#fff; font-size:10.5px; font-weight:700; line-height:18px; text-align:center;
  animation:pop .3s var(--ease-spring);
}
@keyframes pop { 0%{transform:scale(0)} 70%{transform:scale(1.18)} 100%{transform:scale(1)} }

.rail-add { margin:14px 4px 0; justify-content:center; }
/* An account that hasn't paid yet can browse but not add — hide spend CTAs. */
body.inactive .rail-add, body.inactive .tab-add { display:none !important; }

#queue {
  margin-top:auto; display:flex; gap:10px; align-items:center; padding:10px;
  border:1px solid var(--hairline); border-radius:var(--r-m); background:var(--bg2);
  cursor:pointer; transition:border-color var(--t-fast);
}
@media (hover:hover) { #queue:hover { border-color:var(--accent-ring); } }
.queue-ring {
  width:28px; height:28px; border-radius:50%; flex-shrink:0;
  background:conic-gradient(var(--accent) calc(var(--pct,0)*1%), var(--bg3) 0);
  display:flex; align-items:center; justify-content:center;
}
.queue-ring span { width:20px; height:20px; border-radius:50%; background:var(--bg2); }
#queue.idle .queue-ring { background:var(--ok-soft); }
#queue.failed .queue-ring { background:var(--danger-soft); }
.queue-text { min-width:0; }
.queue-text b { display:block; font-size:12.5px; }
.queue-text small { color:var(--text3); font-size:11.5px; display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

#content { margin-left:var(--rail-w); padding:28px calc(32px + env(safe-area-inset-right)) 64px 32px; max-width:1280px; }
#content > section { animation:viewin var(--t-med) var(--ease-out); }
@keyframes viewin { from { opacity:0; transform:translateY(8px); } }

.view-head { margin-bottom:18px; }
.view-head h1 { font-family:var(--font-display); font-size:19px; font-weight:700; letter-spacing:-.2px; }
.lead { color:var(--text2); font-size:13.5px; margin-top:3px; max-width:720px; }
.hint { color:var(--text3); font-size:12px; margin-top:6px; }
.section-title { font-size:15px; font-weight:650; margin:26px 0 12px; display:flex; align-items:baseline; gap:10px; }
.section-title small a { font-size:12.5px; font-weight:500; }

/* ---- mobile bottom tab bar --------------------------------------------------- */
#tabbar {
  display:none; position:fixed; left:0; right:0; bottom:0; z-index:40; height:var(--tabbar-h);
  padding:6px 8px calc(6px + env(safe-area-inset-bottom));
  background:var(--rail-blur); backdrop-filter:blur(14px);
  border-top:1px solid var(--hairline);
}
#tabbar a {
  flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  color:var(--text3); font-size:11px; font-weight:600; border-radius:10px;
  transition:color var(--t-fast);
}
#tabbar a span { max-width:100%; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
@media (max-width:360px) { #tabbar a { font-size:10px; } }
#tabbar a .i { width:23px; height:23px; }
#tabbar a.active { color:var(--accent); }
#tabbar .tab-add-btn {
  width:46px; height:32px; border-radius:10px; background:var(--grad); color:var(--on-accent);
  display:flex; align-items:center; justify-content:center; box-shadow:var(--glow);
}
#tabbar .tab-add-btn .i { width:18px; height:18px; }
#tabbar .tab-add.active .tab-add-btn { filter:brightness(1.12); }

/* ---- primitives ----------------------------------------------------------- */
.panel { background:var(--bg1); border:1px solid var(--hairline); border-radius:var(--r-l); padding:22px; }
.empty { color:var(--text2); padding:44px 16px; text-align:center; font-size:14px; }
.empty b { display:block; margin-bottom:4px; font-size:15px; color:var(--text); }
.kbd {
  font-size:11px; color:var(--text3); background:var(--bg3); border:1px solid var(--hairline);
  border-radius:5px; padding:1px 6px;
}

input[type=text], input[type=number], input[type=email], input[type=password], select, textarea {
  background:var(--bg2); border:1px solid var(--hairline-strong); border-radius:10px;
  color:var(--text); padding:11px 13px; width:100%; font-size:14px; font-family:var(--font);
  transition:border-color var(--t-fast);
}
input:focus, select:focus, textarea:focus { outline:none; border-color:var(--accent-ring); }
input::placeholder, textarea::placeholder { color:var(--text3); }
label { display:block; color:var(--text2); font-size:13px; margin:14px 0 6px; }
label small { color:var(--text3); }

.btn {
  display:inline-flex; align-items:center; gap:8px; border:1px solid transparent; cursor:pointer;
  border-radius:10px; padding:10px 16px; font-size:13.5px; font-weight:600; color:var(--text);
  background:var(--bg3); font-family:var(--font); text-decoration:none;
  transition:transform var(--t-fast) var(--ease-out), filter var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}
@media (hover:hover) { .btn:hover { transform:translateY(-1px); } }
.btn:active { transform:scale(.97); }
.btn--primary { background:var(--grad); color:var(--on-accent); box-shadow:var(--glow); }
@media (hover:hover) { .btn--primary:hover { filter:brightness(1.08); } }
.btn--ghost { background:var(--bg2); border-color:var(--hairline-strong); font-weight:500; }
@media (hover:hover) { .btn--ghost:hover { border-color:var(--accent-ring); } }
.btn--danger { background:var(--danger-soft); color:var(--danger); }
@media (hover:hover) { .btn--del:hover { color:var(--danger); border-color:var(--danger); } }
.btn--del[data-armed="1"] { color:var(--danger); border-color:var(--danger); background:var(--danger-soft); }
.btn--sm { padding:6px 11px; font-size:12.5px; border-radius:8px; }
.btn--xl { padding:14px 26px; font-size:15px; margin-top:20px; }
.btn[disabled] { opacity:.55; pointer-events:none; }
.btn .spin, .spin {
  width:14px; height:14px; border:2px solid currentColor; border-top-color:transparent;
  border-radius:50%; opacity:.85; animation:spin .7s linear infinite; display:inline-block;
}
.spin--lg { width:26px; height:26px; margin-bottom:14px; }
@keyframes spin { to { transform:rotate(360deg); } }

.searchbar { display:flex; gap:10px; align-items:center; }
.searchbar input { flex:1; }

.chips { display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
.chip {
  display:inline-flex; align-items:center; gap:6px; padding:7px 13px; border-radius:999px;
  background:var(--bg2); border:1px solid var(--hairline-strong); color:var(--text2);
  font-size:12.5px; cursor:pointer; user-select:none; font-family:var(--font); font-weight:500;
  transition:transform var(--t-fast) var(--ease-out), border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
}
@media (hover:hover) { .chip:hover { transform:translateY(-1px); color:var(--text); border-color:var(--accent-ring); } }
.chip.on { background:var(--accent-soft); border-color:var(--accent-ring); color:var(--text); animation:pop .3s var(--ease-spring); }
a.chip { text-decoration:none; }
.chip--locked { border-style:dashed; }
.chip--locked small { color:var(--text3); font-size:11px; font-weight:600; }
.chip .i-sm { color:var(--text3); }
.chip .x { color:var(--text3); font-size:13px; margin-left:2px; }
@media (hover:hover) { .chip .x:hover { color:var(--text); } }

.tag {
  display:inline-block; font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  color:var(--text3);
}
.tag--danger { color:var(--danger); } .tag--warn { color:var(--warn); }
.tag--ok { color:var(--ok); } .tag--accent { color:var(--accent); }

.status {
  padding:3px 11px; border-radius:20px; font-size:12px; font-weight:600; white-space:nowrap;
}
.status.completed { background:var(--ok-soft); color:var(--ok); }
.status.processing, .status.queued { background:var(--warn-soft); color:var(--warn); }
.status.failed { background:var(--danger-soft); color:var(--danger); }
.status.live { background:var(--danger-soft); color:var(--live); }

.seg { display:inline-flex; background:var(--bg2); border:1px solid var(--hairline-strong); border-radius:10px; padding:3px; gap:2px; }
.seg button {
  border:0; background:none; color:var(--text2); padding:7px 14px; border-radius:8px;
  font-size:13px; font-weight:500; cursor:pointer; font-family:var(--font);
  transition:background var(--t-fast), color var(--t-fast);
}
@media (hover:hover) { .seg button:hover { color:var(--text); } }
.seg button.on { background:var(--bg3); color:var(--text); }
.seg button:disabled { opacity:.45; cursor:not-allowed; }
@media (hover:hover) { .seg button:disabled:hover { color:var(--text2); } }

.toolbar { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-bottom:16px; }
.toolbar input[type=text] { width:220px; flex:none; }
.toolbar select { width:auto; max-width:100%; text-overflow:ellipsis; }
.toolbar .spacer { flex:1; }

/* ---- stats (Home) ----------------------------------------------------------- */
.stats { display:grid; grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); gap:14px; margin-bottom:26px; }
.stat {
  background:var(--bg1); border:1px solid var(--hairline); border-radius:var(--r-l);
  padding:18px 20px; cursor:pointer;
  transition:transform var(--t-fast) var(--ease-out), border-color var(--t-fast);
}
@media (hover:hover) { .stat:hover { transform:translateY(-1px); border-color:var(--hairline-strong); } }
.stat b { display:block; font-family:var(--font-display); font-size:27px; font-weight:700; line-height:1.25; font-variant-numeric:tabular-nums; }
.stat small { color:var(--text3); font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; }
.stat .sub { color:var(--text2); font-size:12px; margin-top:2px; }

/* ---- cards & grids --------------------------------------------------------- */
.grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(270px,1fr)); gap:16px; margin-top:18px; }
.grid > .empty, .grid > .panel { grid-column:1/-1; }
/* Search results: masonry so a portrait and a landscape clip sit side by side,
   each card thumbnail keeping its own aspect ratio (set from the frame's natural
   dimensions in library.js) instead of being cropped to a fixed 16:9. */
.search-grid { column-width:280px; column-gap:16px; margin-top:18px; }
.search-grid > .card { break-inside:avoid; margin:0 0 16px; }
.search-grid > .card .thumb { aspect-ratio:var(--ar, 16 / 9); }
.card {
  background:var(--bg2); border:1px solid var(--hairline); border-radius:var(--r-m);
  overflow:hidden; cursor:pointer;
  transition:transform var(--t-med) var(--ease-out), border-color var(--t-med), box-shadow var(--t-med);
  animation:cardin var(--t-med) var(--ease-out) backwards;
  animation-delay:calc(min(var(--i,0), 10) * 22ms);
}
@keyframes cardin { from { opacity:0; transform:translateY(8px); } }
@media (hover:hover) { .card:hover { transform:translateY(-2px); border-color:var(--accent-ring); box-shadow:var(--sh-2); } }
.thumb { position:relative; aspect-ratio:16/9; background:#000; overflow:hidden; }
.thumb img { width:100%; height:100%; object-fit:cover; display:block; transition:transform .4s var(--ease-out); }
@media (hover:hover) { .card:hover .thumb img { transform:scale(1.04); } }
.thumb::after {
  content:"▶"; position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  font-size:30px; color:#fff; opacity:0; background:rgba(0,0,0,.35); transition:opacity var(--t-fast);
}
@media (hover:hover) { .card:hover .thumb::after { opacity:1; } }
.ts {
  position:absolute; bottom:6px; right:6px; z-index:2; font-size:11.5px; color:#fff;
  background:rgba(0,0,0,.72); border-radius:5px; padding:1px 6px;
}
/* Count of matched moments on a grouped (ranged) search result. */
.match-n {
  position:absolute; top:6px; left:6px; z-index:2; min-width:18px; height:18px; padding:0 5px;
  display:inline-flex; align-items:center; justify-content:center; gap:3px;
  font-size:11px; font-weight:650; color:var(--on-accent); background:var(--accent2);
  border-radius:999px; box-shadow:0 1px 4px rgba(0,0,0,.45);
}
.match-n::before {
  content:""; width:8px; height:8px; border-radius:2px; border:1.5px solid currentColor;
  box-shadow:2px 2px 0 -0.5px var(--accent2), 2px 2px 0 1px currentColor;
}
.card .body { padding:12px 14px; }
.card .meta { color:var(--text3); font-size:12px; margin-bottom:4px; }
.card b { font-size:14px; display:block; margin-bottom:3px; }
.card p { font-size:13px; color:var(--text2); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.rel-bar { height:3px; background:var(--bg3); }
.rel-bar span { display:block; height:100%; background:var(--grad); border-radius:0 2px 2px 0; }

/* ---- Library: Finder-style browser ------------------------------------------- */
.lib-search {
  background:var(--bg2); border:1px solid var(--hairline-strong); border-radius:var(--r-l);
  padding:4px 8px 4px 16px; margin-bottom:14px;
  transition:border-color var(--t-fast), box-shadow var(--t-fast);
}
.lib-search:focus-within { border-color:var(--accent-ring); box-shadow:0 0 0 1px var(--accent-ring); }
.lib-search .i { color:var(--text3); }
.lib-search input { background:none; border:0; padding:11px 6px; font-size:14.5px; }
.lib-search input:focus { border:0; }
.lib-search-x {
  border:0; background:none; color:var(--text3); cursor:pointer; border-radius:8px;
  width:32px; height:32px; display:flex; align-items:center; justify-content:center; flex-shrink:0;
}
@media (hover:hover) { .lib-search-x:hover { background:var(--bg3); color:var(--text); } }

.lib-bar { display:flex; align-items:center; gap:10px; margin-bottom:14px; flex-wrap:wrap; }
.lib-tools { display:flex; gap:8px; margin-left:auto; }

.crumbs { display:flex; flex-wrap:wrap; align-items:center; gap:2px; font-size:13.5px; min-width:0; }
.crumb { padding:5px 9px; border-radius:8px; color:var(--text2); cursor:pointer; white-space:nowrap; font-weight:500; }
@media (hover:hover) { .crumb:hover { background:var(--bg2); color:var(--text); } }
.crumb.on { color:var(--text); font-weight:650; }
.crumb-sep { color:var(--text3); opacity:.6; }

.dir-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:12px; margin-bottom:18px; }
.dir-card {
  position:relative; background:var(--bg1); border:1px solid var(--hairline); border-radius:var(--r-m);
  padding:16px 14px 13px; cursor:pointer; text-align:center;
  transition:transform var(--t-fast) var(--ease-out), border-color var(--t-fast), background var(--t-fast);
}
@media (hover:hover) { .dir-card:hover { transform:translateY(-2px); border-color:var(--accent-ring); } }
.dir-card .dir-i { width:34px; height:34px; color:var(--accent); margin:0 auto 8px; display:block; }
.dir-card .dir-name { font-size:13.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dir-card .dir-meta { color:var(--text3); font-size:11.5px; margin-top:2px; }
.dir-card .dir-menu { position:absolute; top:6px; right:6px; opacity:0; transition:opacity var(--t-fast); }
.dir-card:focus-within .dir-menu { opacity:1; }
@media (hover:hover) { .dir-card:hover .dir-menu { opacity:1; } }

/* drag & drop: folders and breadcrumbs highlight while a drag hovers them */
[draggable="true"] { cursor:grab; }
.drop-hot { outline:2px solid var(--accent); outline-offset:-2px; background:var(--accent-soft) !important; }

/* grip that signals draggability + is the touch-drag grab point */
.drag-handle {
  flex-shrink:0; display:inline-flex; align-items:center; justify-content:center;
  width:20px; color:var(--text3); cursor:grab; touch-action:none;
  -webkit-user-select:none; user-select:none;
}
.drag-handle:active { cursor:grabbing; }
.drag-handle-i { width:20px; height:20px; fill:currentColor; }
.dir-card .drag-handle { position:absolute; bottom:6px; right:6px; }

/* ghost that follows the finger during a touch drag */
.drag-ghost {
  position:fixed; top:0; left:0; z-index:1000; pointer-events:none;
  max-width:60vw; padding:7px 11px; border-radius:9px;
  background:var(--bg1); border:1px solid var(--accent-ring); color:var(--text1);
  font-size:13px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  box-shadow:var(--sh-3, 0 8px 24px rgba(0,0,0,.28)); opacity:.95;
}
/* Whole-card variant: a clone of the real row rides under the finger, so
   what's being moved is unmistakable. The original dims while it travels. */
.drag-ghost--card { max-width:94vw; white-space:normal; font-weight:inherit; font-size:inherit; }
.drag-ghost--card.vrow, .drag-ghost--card.drow { padding:8px; background:var(--bg2); }
.drag-ghost--card .drag-handle, .drag-ghost--card .row-actions, .drag-ghost--card .drow-menu { display:none; }
.drag-src { opacity:.35; }

/* ---- video rows -------------------------------------------------------------- */
.vrow {
  display:flex; align-items:center; gap:13px; padding:10px 8px; border-radius:10px;
  border:1px solid transparent; position:relative; cursor:pointer;
  transition:background var(--t-fast), border-color var(--t-fast);
}
@media (hover:hover) { .vrow:hover { background:var(--bg2); border-color:var(--hairline); } }
.vrow + .vrow { margin-top:2px; }
.vrow .vthumb { position:relative; width:92px; height:52px; border-radius:7px; background:#000; overflow:hidden; flex-shrink:0; }
.vrow .vthumb img { width:100%; height:100%; object-fit:cover; }
.vrow .vname { flex:0 1 auto; min-width:0; }
.vrow .vname b {
  font-size:13.5px; display:inline-block; max-width:100%;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; vertical-align:bottom;
}
.vrow .vname:has(.title-more:not([hidden])) b { max-width:calc(100% - 46px); }
.vrow.expanded .vname b { white-space:normal; }
/* Truncated titles reveal a tap-to-expand affordance. */
.title-more {
  border:0; background:none; color:var(--accent); font-size:12px; font-weight:650;
  cursor:pointer; padding:0 2px; font-family:var(--font); vertical-align:bottom;
}
/* The whole area right of the title toggles selection — no precision tapping. */
.vrow .row-tap { flex:1 1 24px; min-width:24px; align-self:stretch; }
.vrow .vsub { color:var(--text3); font-size:12px; margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* "completed" reads as a quiet green check, not a word. */
.status.status--ok {
  padding:0; width:24px; height:24px; border-radius:50%;
  display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
  background:var(--ok-soft); color:var(--ok);
}
.status.status--ok .i { width:14px; height:14px; }
.vrow .prog { position:absolute; left:8px; right:8px; bottom:2px; height:2px; background:var(--bg3); border-radius:2px; overflow:hidden; }
.vrow .prog span { display:block; height:100%; background:var(--grad); transform-origin:left; transition:transform .5s linear; }
@keyframes rowpulse { 0%,100% { background:transparent; } 40% { background:var(--accent-soft); } }
.vrow.pulse { animation:rowpulse 1.4s ease-out 2; }

/* inline rename */
.vrow input.rename { padding:5px 9px; font-size:13.5px; border-radius:7px; width:auto; min-width:220px; }
/* The title rename input matches .vd-title h1 exactly (22px / 650) so editing a
   title never jumps the font size — a seamless underline field, no box reflow. */
.vd-title input.rename {
  font-size:22px; font-weight:650; font-family:var(--font-display); line-height:1.15;
  padding:0 2px; margin:-1px 0; border:0; border-bottom:2px solid var(--accent);
  border-radius:0; background:none; color:var(--text); width:100%; min-width:0; max-width:100%;
}
.vd-title input.rename:focus { outline:none; }
@media (max-width:560px){ .vd-title input.rename { font-size:18px; } }

/* ---- row action buttons (always visible — no hidden menus on rows) ----------- */
.row-actions { display:flex; align-items:center; gap:2px; flex-shrink:0; }
.icon-btn {
  border:0; background:none; color:var(--text3); cursor:pointer; border-radius:7px;
  width:30px; height:30px; display:inline-flex; align-items:center; justify-content:center;
  font-family:var(--font); transition:background var(--t-fast), color var(--t-fast);
}
.icon-btn .i { width:16px; height:16px; }
@media (hover:hover) { .icon-btn:hover { background:var(--bg3); color:var(--text); } }
@media (hover:hover) { .icon-btn--danger:hover { color:var(--danger); background:var(--danger-soft); } }
.icon-btn.armed { width:auto; padding:0 9px; font-size:12px; font-weight:650; color:var(--danger); background:var(--danger-soft); }

/* ---- popover menu ----------------------------------------------------------- */
.menu-wrap { position:relative; }
.menu-btn {
  border:0; background:none; color:var(--text3); font-size:17px; cursor:pointer; border-radius:7px;
  width:30px; height:30px; line-height:1;
}
@media (hover:hover) { .menu-btn:hover { background:var(--bg3); color:var(--text); } }
.menu {
  position:absolute; right:0; top:calc(100% + 4px); z-index:50; min-width:190px;
  max-width:calc(100vw - 24px);
  background:var(--bg3); border:1px solid var(--hairline-strong); border-radius:var(--r-m);
  box-shadow:var(--sh-3); padding:5px; animation:menuin var(--t-fast) var(--ease-out);
}
@keyframes menuin { from { opacity:0; transform:translateY(-4px); } }
.menu button {
  display:flex; align-items:center; gap:9px; width:100%; text-align:left; border:0; background:none;
  color:var(--text); padding:8px 10px; border-radius:8px; font-size:13px; cursor:pointer; font-family:var(--font);
}
@media (hover:hover) { .menu button:hover { background:var(--bg2); } }
.menu button.danger { color:var(--danger); }
.menu button.danger[data-armed="1"] { background:var(--danger-soft); font-weight:650; }
.menu .i { width:15px; height:15px; color:var(--text2); }
.menu button.danger .i { color:var(--danger); }
.menu .menu-inline { padding:6px 10px; }
.menu .menu-title { padding:8px 10px 4px; font-size:12px; font-weight:650; color:var(--text2); }
/* floating popover: positioned by JS (fixed), not anchored to a ⋯ button */
.menu-float { position:fixed; z-index:60; }
.menu-float > .menu { position:static; margin:0; }

/* ---- alerts ------------------------------------------------------------------ */
/* Filters: adapter as underline tabs (same .ap-tabs language as the checks
   picker — no bubbles), video/folder as popover buttons (search + flat list,
   not a native <select>). */
.alert-filters { display:flex; flex-direction:column; gap:10px; margin-bottom:16px; }
.alert-filters .ap-tabs { margin:0; }
.alert-filter-row { display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
.alert-filter-row .chev { color:var(--text3); }
/* These buttons sit at the content's left edge — a right-anchored .menu would
   open leftward, off the column and under the fixed rail. Anchor left instead. */
.alert-filter-row .menu { left:0; right:auto; }
/* Folder popover tree: indented rows, a twisty per folder revealing its
   subfolders and videos, alert counts right-aligned. */
.ap-row.ap-tree { gap:7px; padding-left:calc(8px + var(--d, 0)*16px); }
.ap-tree .ap-tw {
  display:flex; align-items:center; justify-content:center; width:18px; height:18px;
  flex-shrink:0; color:var(--text3); border-radius:5px;
}
.ap-tree .ap-tw .i { transition:transform var(--t-fast) var(--ease-out); }
.ap-tree .ap-tw.open .i { transform:rotate(90deg); }
@media (hover:hover) { .ap-tree .ap-tw[data-toggle]:hover { background:var(--bg2); color:var(--text); } }
.ap-tree > .i { flex-shrink:0; }
.ap-row.ap-tree.on, .ap-row.ap-tree.on > .i { color:var(--accent); }
.ap-tree .n {
  flex-shrink:0; min-width:18px; text-align:center; font-size:11px; color:var(--text3);
  background:var(--bg2); border-radius:9px; padding:1px 5px;
}
.alert-card {
  display:flex; gap:13px; align-items:center; background:var(--bg2); border:1px solid var(--hairline);
  border-left:3px solid var(--warn); border-radius:var(--r-m); padding:10px 14px 10px 11px;
  margin-bottom:8px; cursor:pointer;
  transition:transform var(--t-fast) var(--ease-out), border-color var(--t-fast);
  animation:cardin var(--t-med) var(--ease-out) backwards;
  animation-delay:calc(min(var(--i,0), 10) * 22ms);
}
@media (hover:hover) { .alert-card:hover { transform:translateX(3px); border-color:var(--accent-ring); } }
.alert-card.crit { border-left-color:var(--danger); }
.alert-card.kb-focus { border-color:var(--accent); background:var(--bg3); }
.alert-card .athumb {
  position:relative; width:96px; height:54px; border-radius:7px; overflow:hidden; background:#000;
  flex-shrink:0; display:flex; align-items:center; justify-content:center; color:var(--text3);
}
.alert-card .athumb img { width:100%; height:100%; object-fit:cover; }
.alert-card .abody { flex:1; min-width:0; }
.alert-card .atop { display:flex; align-items:baseline; gap:10px; margin-bottom:2px; }
.alert-card .atop small { color:var(--text3); font-size:12px; margin-left:auto; white-space:nowrap; min-width:0; overflow:hidden; text-overflow:ellipsis; }
.alert-card p { font-size:13.5px; color:var(--text2); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.alert-card .avideo { color:var(--text2); font-size:12px; }
@media (hover:hover) { .alert-card .avideo:hover { color:var(--accent); } }

/* Alert detail modal (core.alertDetail): the full flagged text, un-clamped. */
.alert-detail { max-width:560px; text-align:left; }
.alert-detail .ad-head { display:flex; align-items:baseline; gap:10px; margin-bottom:12px; }
.alert-detail .ad-head small { color:var(--text3); font-size:12.5px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.alert-detail .ad-text {
  font-size:14px; line-height:1.55; color:var(--text); white-space:pre-wrap;
  overflow-wrap:anywhere; max-height:52vh; overflow:auto; margin-bottom:16px;
}
@keyframes alertin {
  0% { opacity:0; transform:translateY(-8px); box-shadow:0 0 0 0 rgba(255,90,77,.5); }
  40% { box-shadow:0 0 24px 2px rgba(255,90,77,.35); }
  100% { opacity:1; transform:none; box-shadow:none; }
}
.alert-card.fresh { animation:alertin 1.1s var(--ease-out); }

.path-motif { color:var(--accent); vertical-align:-2px; margin:0 2px; flex-shrink:0; }

/* ---- video detail page -------------------------------------------------------- */
.vd-head { display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:6px; }
.vd-actions { display:flex; gap:8px; flex-wrap:wrap; margin-left:auto; }
.vd-back { color:var(--text2); font-size:13px; display:inline-flex; align-items:center; gap:5px; }
@media (hover:hover) { .vd-back:hover { color:var(--accent); } }
.vd-title { display:flex; align-items:center; gap:9px; min-width:0; }
.vd-title h1 { font-size:22px; font-weight:650; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.vd-title .edit { color:var(--text3); cursor:pointer; border-radius:6px; padding:4px; display:inline-flex; }
@media (hover:hover) { .vd-title .edit:hover { color:var(--text); background:var(--bg3); } }
.dir-chip {
  display:inline-flex; align-items:center; gap:5px; font-size:11.5px; color:var(--text2);
  background:var(--bg3); border-radius:999px; padding:2px 10px; white-space:nowrap;
}
@media (hover:hover) { .dir-chip:hover { color:var(--text); } }
.meta-strip { display:flex; flex-wrap:wrap; gap:7px; margin:10px 0 0; }
.meta-chip {
  font-size:11.5px; color:var(--text2); background:var(--bg2); border:1px solid var(--hairline);
  border-radius:6px; padding:3px 9px;
}
.meta-chip.alerting { color:var(--warn); border-color:rgba(230,161,47,.3); }
/* Active checks get their own row, visually distinct from the muted technical
   stats above — this is "what's watching", not "what this file is". */
.vd-checks { display:flex; flex-wrap:wrap; gap:6px; margin:10px 0 18px; }
.check-chip {
  font-size:11.5px; font-weight:600; color:var(--accent); background:var(--accent-soft);
  border:1px solid var(--accent-ring); border-radius:20px; padding:3px 11px;
}
.check-chip.alerting { color:var(--warn); background:var(--warn-soft); border-color:rgba(230,161,47,.3); }
.vd-cols { display:grid; grid-template-columns:minmax(0,1.5fr) minmax(340px,1fr); gap:26px; align-items:start; }
/* Grid items must be allowed to shrink below their content, or the horizontally
   scrolling filmstrip (.strip) blows the column out to its full width instead of
   scrolling — catastrophic once the grid collapses to one column on mobile. */
.vd-cols > * { min-width:0; }
.vd-player { position:sticky; top:24px; }
.vd-player .player-stage { max-height:60dvh; box-shadow:var(--sh-2); }

.heat { position:relative; height:10px; margin-top:10px; background:var(--bg2); border-radius:5px; cursor:pointer; }
.heat i {
  position:absolute; top:-2px; bottom:-2px; width:3px; border-radius:2px; background:var(--warn);
  transition:transform var(--t-fast);
}
.heat i.crit { background:var(--danger); }
@media (hover:hover) { .heat i:hover { transform:scaleY(1.35); } }
.heat .playhead { position:absolute; top:-3px; bottom:-3px; width:2px; background:var(--text); border-radius:1px; pointer-events:none; }

.strip { display:flex; gap:5px; overflow-x:auto; margin-top:10px; padding-bottom:6px; scrollbar-width:thin; }
.strip .fthumb {
  position:relative; width:68px; height:38px; flex-shrink:0; border-radius:6px; overflow:hidden;
  background:#000; cursor:pointer; border:2px solid transparent; transition:border-color var(--t-fast);
}
.strip .fthumb img { width:100%; height:100%; object-fit:cover; }
.strip .fthumb.active { border-color:var(--accent); }
.strip .fthumb .ts { bottom:3px; right:3px; }

/* Shared hover tooltip (full frame descriptions on the filmstrip + timeline).
   Fixed + body-level so it escapes overflow clipping; core.js keeps it inside
   the viewport. */
.tip {
  position:fixed; z-index:60; left:0; top:0;
  max-width:min(340px, calc(100vw - 16px));
  padding:8px 11px;
  font-size:12.5px; line-height:1.45; color:var(--text);
  background:var(--bg3); border:1px solid var(--hairline-strong);
  border-radius:var(--r-s); box-shadow:var(--sh-2);
  white-space:pre-wrap; overflow-wrap:anywhere;
  pointer-events:none; opacity:0; transition:opacity var(--t-fast) var(--ease-out);
}
.tip.on { opacity:1; }

.tabs { position:relative; display:flex; gap:2px; border-bottom:1px solid var(--hairline); margin-bottom:16px; }
.tabs button {
  border:0; background:none; color:var(--text2); padding:9px 14px; font-size:13.5px; font-weight:550;
  cursor:pointer; font-family:var(--font); transition:color var(--t-fast);
}
@media (hover:hover) { .tabs button:hover { color:var(--text); } }
.tabs button.on { color:var(--text); }
.tabs .tab-underline {
  position:absolute; left:0; bottom:-1px; height:2px; background:var(--grad); border-radius:2px;
  transition:transform var(--t-med) var(--ease-out), width var(--t-med) var(--ease-out);
}
/* letterhead: masthead (adapter + camera/folder + date) over a hairline rule,
   reading body, actions to take the document off-screen (copy / print). */
.report-card { background:var(--bg2); border:1px solid var(--hairline); border-radius:var(--r-m); margin-bottom:12px; overflow:hidden; }
.report-card .rl-head { display:flex; align-items:flex-start; justify-content:space-between; gap:14px; padding:14px 17px 11px; }
.report-card .rl-head > div { min-width:0; }
.report-card .rl-brand { font-family:var(--font-display); font-size:10.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--text3); margin-bottom:3px; }
.report-card .rl-head b { font-size:14.5px; }
.report-card .rl-meta { text-align:right; font-size:11.5px; color:var(--text3); flex-shrink:1; }
.report-card .rl-meta b { display:block; font-size:13px; color:var(--text); font-weight:650; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.report-card .rl-rule { border:0; border-top:1px solid var(--hairline-strong); margin:0 17px; }
.report-card .rbody { color:var(--text2); font-size:13.5px; line-height:1.65; white-space:pre-wrap; overflow-wrap:anywhere; padding:13px 17px 2px; }
.report-card .rbody ul { margin:4px 0 4px 18px; padding:0; white-space:normal; }
.report-card .rbody li { margin:2px 0; }
.report-card .rfoot { display:flex; gap:8px; padding:11px 17px 15px; }

/* print: the report is the deliverable — everything else drops out and the
   card becomes a plain paper page. */
@media print {
  body * { visibility:hidden; }
  #vd-content, #vd-content * { visibility:visible; }
  #vd-content { position:absolute; left:0; top:0; width:100%; }
  /* Reports now render as .disc disclosures inside #vd-content — strip the
     surrounding chrome and un-clamp the body so the whole report prints. */
  #vd-content .vd-sec > .vd-sec-h, #vd-content .vd-drawer, #vd-content .vd-info,
  #vd-content .disc--alert, #vd-content .disc-foot, #vd-content .disc-chev { display:none; }
  #vd-content .disc { border:0; }
  #vd-content .disc-body {
    -webkit-line-clamp:unset !important; overflow:visible !important;
    -webkit-mask-image:none !important; color:#111;
  }
  /* Printing from one specific report card (vd-print's data-i) isolates just
     that card — the others get this class for the duration of the print. */
  #vd-content .disc.print-hide { display:none; }
}

.frame-card { animation:none; }

/* ---- timeline tab: compact list, thumb + a description that expands in place ----
   Collapsed rows all read at the same height (2-line clamp) so the list scans
   evenly regardless of description length; clicking the text (or its chevron)
   expands just that row. The thumb is its own seek target so reading and
   jumping never fight over one click. */
.tl-list { display:flex; flex-direction:column; gap:4px; margin-top:10px; }
.tl-row { display:flex; gap:11px; align-items:flex-start; padding:8px; border-radius:9px; }
.tl-thumb {
  position:relative; width:64px; height:36px; flex-shrink:0; border-radius:6px; overflow:hidden;
  background:#000; cursor:pointer; transition:transform var(--t-fast) var(--ease-spring);
}
@media (hover:hover) { .tl-thumb:hover { transform:scale(1.06); } }
.tl-thumb img { width:100%; height:100%; object-fit:cover; }
.tl-thumb .ts { font-size:9px; padding:0 4px; bottom:2px; right:2px; }
.tl-body {
  flex:1; min-width:0; display:flex; align-items:flex-start; gap:8px; cursor:pointer;
  padding:2px 4px; border-radius:7px; transition:background var(--t-fast);
}
@media (hover:hover) { .tl-body:hover { background:var(--bg2); } }
.tl-text {
  flex:1; min-width:0; margin:0; font-size:13px; color:var(--text2); line-height:1.5;
  white-space:pre-wrap; overflow-wrap:anywhere;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.tl-row.open .tl-text { -webkit-line-clamp:unset; overflow:visible; }
.tl-chev { flex-shrink:0; margin-top:3px; color:var(--text3); transition:transform var(--t-fast); }
.tl-row.open .tl-chev { transform:rotate(90deg); }

/* ---- transcript tab: timestamped spoken-audio lines, click to seek -------------- */
.transcript { display:flex; flex-direction:column; gap:2px; margin-top:10px; }
.tr-line {
  display:flex; gap:10px; align-items:flex-start; padding:8px; border-radius:9px; cursor:pointer;
  transition:background var(--t-fast);
}
.tr-line:focus-visible { background:var(--bg2); }
@media (hover:hover) { .tr-line:hover { background:var(--bg2); } }
.tr-ts { flex-shrink:0; font-size:12px; color:var(--text3); font-variant-numeric:tabular-nums; padding-top:1px; }
.tr-text { flex:1; min-width:0; font-size:13px; color:var(--text2); line-height:1.5; white-space:pre-wrap; overflow-wrap:anywhere; }

/* ---- edits: prompt-across-videos clip editor ------------------------------------ */
.edit-sources-row {
  display:flex; align-items:center; gap:9px; cursor:pointer; font-size:13.5px; margin-bottom:14px;
}
.edit-sources-row .lead { margin:0; }
#edit-prompt {
  width:100%; resize:vertical; font:inherit; padding:10px 12px; border-radius:var(--r-m);
  border:1px solid var(--hairline); background:var(--bg2); color:var(--text); line-height:1.5;
}

/* Timeline studio: preview stage + transport + a scrubbable, zoomable clip
   track. edits.js does all track x-maths in px assuming border-box blocks laid
   out flex with NO gap — separate clips visually with borders, never gaps. */
.edit-studio, .edit-studio-skel { margin-top:14px; }
.edit-studio { padding:0; overflow:hidden; }
.edit-stage { position:relative; aspect-ratio:16/9; max-height:46vh; width:100%; background:#000; cursor:pointer; }
.edit-stage video { position:absolute; inset:0; width:100%; height:100%; object-fit:contain; background:#000; }
.edit-stage-clip {
  position:absolute; left:10px; top:8px; max-width:70%; padding:3px 9px; border-radius:7px;
  font-size:11.5px; color:#fff; background:rgba(0,0,0,.55); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; pointer-events:none;
}
.edit-stage-clip:empty { display:none; }
.edit-bigplay { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; color:#fff; pointer-events:none; }
.edit-bigplay .i { width:52px; height:52px; filter:drop-shadow(0 2px 12px rgba(0,0,0,.55)); }
.edit-stage.playing .edit-bigplay { display:none; }
.edit-transport { display:flex; align-items:center; flex-wrap:wrap; gap:6px; padding:10px 12px; border-top:1px solid var(--hairline); }
.edit-transport .btn { display:inline-flex; align-items:center; gap:6px; }
.edit-clock { font-size:12.5px; color:var(--text2); font-variant-numeric:tabular-nums; white-space:nowrap; }
.edit-tspace { flex:1; }
@media (max-width:560px) { .edit-tlabel { display:none; } }
.edit-timeline { overflow-x:auto; overflow-y:hidden; padding:2px 12px 12px; -webkit-overflow-scrolling:touch; }
.tl-track { position:relative; touch-action:none; -webkit-user-select:none; user-select:none; }
.tl-ruler { position:relative; height:20px; border-bottom:1px solid var(--hairline); cursor:col-resize; }
.tl-ruler span {
  position:absolute; top:3px; transform:translateX(-50%); font-size:10px; color:var(--text3);
  font-variant-numeric:tabular-nums; pointer-events:none;
}
.tl-clips { display:flex; height:56px; margin-top:6px; }
.tl-clip {
  position:relative; flex:0 0 auto; height:100%; border-radius:7px; overflow:hidden;
  background:var(--bg3); border:1px solid var(--bg1); cursor:pointer;
}
.tl-clip.sel { cursor:grab; }
.tl-clip.sel::after { content:""; position:absolute; inset:0; border:2px solid var(--accent); border-radius:7px; pointer-events:none; }
.tl-clip.off { opacity:.35; }
.tl-clip.dragging { opacity:.8; z-index:3; box-shadow:var(--sh-2); cursor:grabbing; }
.tl-thumbs { display:flex; width:100%; height:100%; pointer-events:none; }
.tl-thumbs img { flex:1 1 0; min-width:0; height:100%; object-fit:cover; }
.tl-clip-t {
  position:absolute; left:5px; right:5px; bottom:3px; font-size:10px; color:#fff;
  text-shadow:0 1px 2px rgba(0,0,0,.85); overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; pointer-events:none;
}
.tl-h { position:absolute; top:0; bottom:0; width:16px; cursor:ew-resize; z-index:2; }
.tl-h--l { left:0; } .tl-h--r { right:0; }
.tl-h::before {
  content:""; position:absolute; top:12px; bottom:12px; width:4px; border-radius:2px;
  background:#fff; box-shadow:0 0 0 1px rgba(0,0,0,.3);
}
.tl-h--l::before { left:3px; } .tl-h--r::before { right:3px; }
.tl-playhead { position:absolute; top:0; bottom:0; left:0; width:2px; background:var(--accent); pointer-events:none; z-index:4; }
.tl-playhead span { position:absolute; top:-1px; left:50%; transform:translateX(-50%); width:11px; height:11px; border-radius:50%; background:var(--accent); }
.edit-hint { padding:0 12px 12px; font-size:11.5px; }

/* The AI's own account of its choices (edits.summary / refine notes). */
.edit-summary { display:flex; gap:10px; align-items:flex-start; margin-top:14px;
  padding:14px 16px; font-size:13px; color:var(--text2); line-height:1.55; }
.edit-summary .i { color:var(--accent); flex-shrink:0; margin-top:2px; }

/* Selected-clip bar: clip number, the AI's reason, tap-to-seek word chips. */
.edit-selbar { padding:0 12px 10px; }
.edit-selinfo { font-size:12.5px; color:var(--text2); padding:2px 0 7px; }
.edit-selinfo b { color:var(--text); }
.edit-words { display:flex; gap:3px; overflow-x:auto; padding-bottom:4px; -webkit-overflow-scrolling:touch; }
.edit-word { flex:0 0 auto; border:1px solid var(--hairline); background:var(--bg2); color:var(--text2);
  font:inherit; font-size:12px; padding:3px 8px; border-radius:7px; cursor:pointer; }
@media (hover:hover) { .edit-word:hover { background:var(--bg3); color:var(--text); } }

/* Refine: the conversational edit bar under the timeline. */
.edit-refine { display:flex; gap:8px; padding:0 12px 10px; }
.edit-refine input { flex:1; min-width:0; font:inherit; font-size:13px; padding:9px 12px;
  border-radius:var(--r-m); border:1px solid var(--hairline); background:var(--bg2); color:var(--text); }
.edit-refine .btn { flex-shrink:0; }

.edit-footer { display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-top:14px; }
.edit-footer > div:first-child { flex:1; min-width:120px; font-size:13px; color:var(--text2); }
.edit-progress { flex:1 1 100%; height:4px; background:var(--bg3); border-radius:2px; overflow:hidden; order:3; }
.edit-progress span { display:block; height:100%; background:var(--grad); transition:width .5s linear; }

/* The source picker is a little Library: folder rows drill in, the big leading
   .sel-zone (44px+) toggles selection for a video or a whole subtree. */
.edit-pick-list { display:flex; flex-direction:column; gap:2px; max-height:52vh; overflow:auto; margin:8px 0; }
.edit-pick-row { display:flex; align-items:center; gap:8px; padding:3px 4px 3px 0; border-radius:10px; cursor:pointer; }
@media (hover:hover) { .edit-pick-row:hover { background:var(--bg2); } }
.edit-pick-row .sel-zone {
  flex-shrink:0; width:48px; min-height:44px;
  display:flex; align-items:center; justify-content:center; border-radius:10px;
}
.edit-pick-row .sel-dot { opacity:1; transform:scale(1); pointer-events:none; }
.edit-pick-emoji { font-size:20px; flex-shrink:0; }
.edit-pick-thumb { width:56px; height:32px; border-radius:6px; background:#000; overflow:hidden; flex-shrink:0; }
.edit-pick-thumb img { width:100%; height:100%; object-fit:cover; }
.edit-pick-title { flex:1; min-width:0; font-size:13.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.edit-pick-title small { font-size:11.5px; }
.edit-pick-folder .drow-chev { color:var(--text3); flex-shrink:0; }
.edit-pick-crumbs { display:flex; align-items:center; gap:8px; margin:4px 0 2px; min-height:32px; }
.edit-pick-here { font-size:13.5px; }

/* Drafting-model tier picker under the prompt. */
.edit-model-row { display:flex; align-items:center; gap:8px; margin-top:10px; flex-wrap:wrap; }
.edit-model-row label { margin:0; font-size:12.5px; color:var(--text2); }
.edit-model-row select { width:auto; max-width:60%; }
.edit-model-row .lead { font-size:12px; }

.banner {
  display:flex; align-items:center; gap:12px; background:var(--bg2); border:1px solid var(--hairline);
  border-radius:var(--r-m); padding:13px 16px; margin-bottom:16px; font-size:13.5px; color:var(--text2);
}
.banner.danger { border-color:rgba(255,90,77,.35); background:var(--danger-soft); color:var(--text); }
.banner .prog { flex:1; height:4px; background:var(--bg3); border-radius:2px; overflow:hidden; }
.banner .prog span { display:block; height:100%; background:var(--grad); transform-origin:left; transition:transform .5s linear; }

/* Out-of-credits: the one banner that sits above EVERY view (core.renderCreditBanner).
   Louder than .banner.danger — cameras are actually stopped while this shows. */
.credit-banner {
  display:flex; align-items:center; gap:12px;
  background:var(--danger-soft); border:1.5px solid var(--danger);
  border-radius:var(--r-m); padding:13px 16px; margin-bottom:18px;
  font-size:13.5px; color:var(--text);
}
.credit-banner .i { width:20px; height:20px; flex:0 0 auto; color:var(--danger); }
.credit-banner > div { flex:1; }
.credit-banner .btn { flex:0 0 auto; }

/* ---- zero-signup demo (core.renderDemoBanner / openDemoWall) --------------------
   Sits above every view under body.demo. The budget meter is the core signal, so
   it reads as an accent-tinted panel, escalating to danger tint when spent out. */
.demo-banner {
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  background:var(--accent-soft); border:1px solid var(--accent-ring);
  border-radius:var(--r-m); padding:13px 16px; margin-bottom:18px; color:var(--text);
}
.demo-banner--empty { background:var(--warn-soft); border-color:var(--warn); }
.demo-banner-main { flex:1 1 260px; min-width:0; display:flex; flex-direction:column; gap:7px; }
.demo-banner-head { display:flex; align-items:center; gap:9px; font-size:14px; }
.demo-chip {
  font-size:11px; font-weight:600; letter-spacing:.02em; padding:2px 8px;
  border-radius:999px; background:var(--bg3); color:var(--text2); white-space:nowrap;
}
.demo-meter { height:5px; background:var(--bg3); border-radius:3px; overflow:hidden; }
.demo-meter > span {
  display:block; height:100%; background:var(--grad);
  transform-origin:left; transition:transform .5s linear;
}
.demo-banner--empty .demo-meter > span { background:var(--warn); }
.demo-banner-sub {
  display:flex; align-items:center; gap:7px; flex-wrap:wrap;
  font-size:12.5px; color:var(--text2);
}
.demo-banner-note { font-size:11.5px; color:var(--text3); }
.demo-banner-auth { flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:6px; }
.demo-banner-cta { flex:0 0 auto; }
.demo-banner-signin { font-size:12px; color:var(--text2); }
.demo-banner-signin:hover { color:var(--text); }
@media (max-width:520px) { .demo-banner-auth, .demo-banner-cta { width:100%; } }

/* Conversion wall reuses .confirm-wrap/.confirm-card; only its labels are new. */
.dw-lbl { display:block; font-size:13px; color:var(--text2); margin-top:12px; }
.dw-lbl small { color:var(--text3); }
.dw-lbl input { margin-top:6px; }

/* ---- add footage ---------------------------------------------------------------- */
.add-source-seg { margin:0 0 20px; flex-wrap:wrap; }
.add-cols { display:grid; grid-template-columns:minmax(300px,1fr) minmax(340px,1.2fr); gap:20px; align-items:start; }

/* ---- Add wizard: big type choice, step dots, per-step nav -------------------------
   A binary "which path" decision gets the centered, oversized-panel treatment —
   the one deliberate choice fills the screen, unlike the data-dense views around
   it (library/alerts/etc.) which stay full-width and left-aligned. */
/* The type choice is the whole point of this screen — give it the room to be
   the visual center, not a header-then-content stack pinned to the top. */
#view-add.step-type { display:flex; flex-direction:column; justify-content:center;
  align-items:center; min-height:calc(100dvh - 180px); }
#view-add.step-type .view-head { text-align:center; }
#view-add.step-type .view-head .lead { max-width:44ch; margin:4px auto 0; }
#stage-type { display:flex; justify-content:center; width:100%; }
.add-type-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(260px, 1fr)); gap:20px; max-width:820px; width:100%; }
.add-type-card {
  display:flex; flex-direction:column; align-items:flex-start; gap:12px; text-align:left;
  padding:34px 28px; border:1.5px solid var(--hairline-strong); border-radius:var(--r-l);
  background:var(--bg2); color:inherit; cursor:pointer; font:inherit;
  transition:border-color var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-spring), box-shadow var(--t-fast);
}
@media (hover:hover) { .add-type-card:hover { border-color:var(--accent); transform:translateY(-3px); box-shadow:var(--sh-2); } }
.add-type-card .i { width:34px; height:34px; color:var(--accent); }
.add-type-card b { font-size:19px; }
.add-type-card span { font-size:13.5px; color:var(--text3); line-height:1.5; }
.add-progress { display:flex; gap:6px; flex-wrap:wrap; margin:0 0 18px; }
.add-dot {
  display:inline-flex; align-items:center; gap:7px; font:inherit; font-size:12px; font-weight:650;
  color:var(--text3); background:var(--bg2); border:1px solid var(--hairline);
  border-radius:999px; padding:5px 12px 5px 6px; cursor:default;
}
.add-dot span {
  width:18px; height:18px; border-radius:50%; background:var(--bg3); color:var(--text3);
  font-size:11px; display:inline-flex; align-items:center; justify-content:center;
}
.add-dot.on { color:var(--text); border-color:var(--accent-ring); }
.add-dot.on span, .add-dot.done span { background:var(--grad); color:var(--on-accent); }
.add-dot.done { cursor:pointer; }
@media (hover:hover) { .add-dot.done:hover { border-color:var(--accent-ring); } }
.add-stage > .panel { max-width:760px; }
.add-nav { display:flex; justify-content:space-between; gap:10px; max-width:760px; margin-top:16px; }
.url-row { display:flex; gap:8px; }
.url-row input { flex:1; }
.q-reco {
  font-size:13px; background:var(--accent-soft); border:1px solid var(--accent-ring);
  border-radius:var(--r-s); padding:10px 12px; margin-bottom:14px;
}
.add-summary { font-size:14px; margin-bottom:14px; color:var(--text2); }
#vdir-select { width:100%; }
/* Pin the primary action to the bottom of the viewport so it stays reachable
   without scrolling past the whole check list — just the centered button, no bar. */
.add-actions {
  position:sticky; bottom:0; z-index:20;
  display:flex; flex-direction:column; align-items:center;
  margin:22px 0 -64px; padding:0 0 calc(14px + env(safe-area-inset-bottom));
  pointer-events:none;   /* let clicks fall through the gaps to content behind */
}
.add-actions > * { pointer-events:auto; }
.add-actions .btn--xl { margin-top:0; }
/* Upload progress: a real bar pinned with the launch button — percent text
   inside the button alone is easy to miss mid-upload on a phone. */
.up-progress { display:flex; flex-direction:column; align-items:center; gap:5px;
  width:min(340px, 88vw); margin-bottom:10px; pointer-events:none; }
.up-track { width:100%; height:5px; border-radius:3px; background:var(--bg3);
  border:1px solid var(--hairline); overflow:hidden; }
.up-track span { display:block; height:100%; background:var(--grad);
  transform:scaleX(0); transform-origin:left; transition:transform var(--t-fast) linear; }
.up-progress small { font-size:12px; font-weight:600; color:var(--text);
  font-variant-numeric:tabular-nums; background:var(--rail-blur);
  border:1px solid var(--hairline); padding:2px 10px; border-radius:999px; }
.add-step { display:flex; align-items:center; gap:10px; font-weight:650; font-size:14.5px; margin:4px 0 12px; }
.add-step:not(:first-child) { margin-top:24px; }
.step-dot {
  width:22px; height:22px; border-radius:50%; background:var(--grad); color:var(--on-accent);
  font-size:12px; font-weight:700; display:inline-flex; align-items:center; justify-content:center;
}
.dropzone {
  border:1.5px dashed var(--hairline-strong); border-radius:var(--r-m); padding:26px 18px;
  text-align:center; color:var(--text2); cursor:pointer;
  transition:border-color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
@media (hover:hover) { .dropzone:hover { border-color:var(--accent-ring); } }
.dropzone.over { border-color:var(--accent); background:var(--accent-soft); transform:scale(1.01); }
.dropzone .i { width:26px; height:26px; color:var(--text3); margin-bottom:8px; }
.dropzone.muted, .muted-input { opacity:.45; }
/* Waiting for the OS to hand over a picked video (phone export) — see add.js. */
.dropzone.busy { border-color:var(--accent-ring); }
#dz-busy { display:flex; align-items:center; justify-content:center; gap:9px;
  color:var(--text); font-weight:600; }
.drop-files { display:flex; flex-wrap:wrap; gap:6px; margin-top:10px; }
.drop-files .drop-file {
  display:inline-flex; gap:8px; align-items:center; background:var(--bg3);
  border-radius:999px; padding:5px 8px 5px 14px; font-size:12.5px; color:var(--text);
}
.drop-files .drop-file .x { cursor:pointer; color:var(--text3); padding:2px 6px; border-radius:999px; }
@media (hover:hover) { .drop-files .drop-file .x:hover { color:var(--text); background:var(--bg2); } }
.or-divider { display:flex; align-items:center; gap:12px; color:var(--text3); font-size:12px; margin:14px 0 2px; }
.or-divider::before, .or-divider::after { content:""; flex:1; height:1px; background:var(--hairline); }

/* Category tabs (adapters-picker.js, full mode) — one category on screen at a
   time instead of a long stacked list, so the picker never grows into a big
   scroll. A quiet dot marks a category that already has picks. */
.ap-tabs { display:flex; gap:4px; overflow-x:auto; scrollbar-width:none; margin:14px 0 2px;
  border-bottom:1px solid var(--hairline); }
.ap-tabs::-webkit-scrollbar { display:none; }
.ap-tab {
  flex-shrink:0; display:flex; align-items:center; gap:6px; background:none; border:0;
  border-bottom:2px solid transparent; color:var(--text3); font:inherit; font-size:12.5px;
  font-weight:600; padding:8px 10px 7px; cursor:pointer; white-space:nowrap;
  transition:color var(--t-fast), border-color var(--t-fast);
}
@media (hover:hover) { .ap-tab:hover { color:var(--text2); } }
.ap-tab.on { color:var(--text); border-color:var(--accent); }
.ap-tab .n { font-size:10.5px; color:var(--text3); font-weight:500; }
.ap-tab.has-sel:not(.on)::before { content:""; width:5px; height:5px; border-radius:50%; background:var(--accent); }
.ap-empty { padding:18px 4px; font-size:12.5px; color:var(--text3); text-align:center; }
.adapter-items { padding:0; }
.adapter-item {
  display:flex; gap:10px; align-items:flex-start; padding:8px 8px; border-radius:9px; cursor:pointer;
  transition:background var(--t-fast);
}
@media (hover:hover) { .adapter-item:hover { background:var(--bg2); } }
.adapter-item input { width:14px; height:14px; margin-top:3px; accent-color:var(--accent); flex-shrink:0; }
.adapter-item .al { font-size:13px; font-weight:600; }
.adapter-item .al .warn-dot { color:var(--danger); }
.adapter-item .kind { font-size:10.5px; color:var(--text3); border:1px solid var(--hairline-strong); border-radius:4px; padding:0 5px; margin-left:6px; letter-spacing:.05em; }
.adapter-item p { font-size:12px; color:var(--text3); margin-top:1px; }
/* Shared adapter picker (adapters-picker.js). */
.ap-filter { width:100%; margin-top:12px; }
.ap-full .ap-groups { margin-top:12px; }
/* The selected-tray sits at the TOP of the picker so what's ticked is always in
   view; checks are added one by one from the groups below (no auto-select). */
.ap-full .ap-tray { margin:0 0 4px; padding:0 0 12px; border-top:0; border-bottom:1px solid var(--hairline); }
.ap-tray-h { width:100%; margin-bottom:2px; font-size:11px; font-weight:700;
  letter-spacing:.04em; text-transform:uppercase; color:var(--text2); }
/* Custom checks: "My checks" group affordances + the CheckCreator sheet. */
.ap-create {
  display:block; width:100%; text-align:left; background:none; cursor:pointer;
  border:1px dashed var(--hairline-strong); border-radius:var(--r-s);
  color:var(--accent); font:inherit; font-size:12.5px; font-weight:600;
  padding:8px 10px; margin-top:4px; transition:background var(--t-fast);
}
@media (hover:hover) { .ap-create:hover { background:var(--bg2); } }
.ap-del {
  margin-left:auto; flex-shrink:0; background:none; border:0; cursor:pointer;
  color:var(--text3); font-size:12px; padding:2px 5px; border-radius:4px;
}
@media (hover:hover) { .ap-del:hover { color:var(--danger); background:var(--bg2); } }
.ck-card .ck-label { display:block; font-size:12px; font-weight:600; color:var(--text2); margin:14px 0 4px; }
.ck-card input[type=text], .ck-card textarea { width:100%; }
.ck-card textarea { resize:vertical; }
.ck-kinds { display:flex; gap:8px; margin-top:14px; }
.ck-kind {
  flex:1; text-align:left; background:var(--bg2); border:1px solid var(--hairline);
  border-radius:var(--r-m); padding:10px 12px; cursor:pointer; font:inherit; color:var(--text);
  transition:border-color var(--t-fast);
}
.ck-kind.on { border-color:var(--accent); background:var(--bg1); }
.ck-kind b { display:block; font-size:13px; }
.ck-kind span { font-size:11.5px; color:var(--text3); }
.ck-adv { margin-top:14px; }
.ck-adv summary { font-size:12.5px; color:var(--text3); cursor:pointer; }
.ck-adv summary::-webkit-details-marker { display:none; }
.ck-adv .ck-row { display:flex; align-items:center; gap:8px; font-size:12.5px; color:var(--text2); margin-top:10px; flex-wrap:wrap; }
.ck-adv .ck-row input[type=checkbox] { accent-color:var(--accent); }
.ck-adv .ck-row input[type=number] { width:64px; }
.ck-adv .ck-row select { width:auto; }
/* Minimal check editor (checks.js CheckEditor): Name, Alert/Report, Prompt, and
   a live phrasing shown only for an alert. The Alert/Report toggle flips the
   prompt label and hides the live phrasing on a report — via classes the editor
   sets on the .confirm-wrap (default state = alert/frame). */
.ce-card { max-width:560px; max-height:88dvh; overflow:auto; }
.ck-opt { color:var(--text3); font-weight:400; }
.ce-hint { font-size:11.5px; color:var(--text3); margin-top:6px; }
.ce-cond-agg { display:none; }
.ce-is-agg .ce-cond-agg { display:inline; }
.ce-is-agg .ce-cond-frame { display:none; }
/* The fixed, non-editable YES/NO lead shown for alerts (hidden on reports). */
.ce-lead { display:flex; align-items:center; gap:7px; font-size:11.5px; color:var(--text2);
  background:var(--bg1); border:1px solid var(--hairline); border-radius:8px; padding:6px 10px; margin:2px 0 8px; }
.ce-lead .i { color:var(--accent); flex-shrink:0; }
.ce-is-agg .ce-lead { display:none; }

/* Context-window picker + the calculated value price (checks editor). */
.ce-window-block { margin-top:10px; }
.ce-window { display:flex; gap:6px; margin:4px 0 6px; }
.ce-win { width:36px; height:30px; border:1px solid var(--hairline); border-radius:8px;
  background:var(--bg1); color:var(--text2); font-size:13px; font-weight:600; cursor:pointer; }
.ce-win.on { border-color:var(--accent); color:var(--text); background:var(--bg2); }
.ce-window-hint { font-size:11.5px; color:var(--text3); margin:0; max-width:52ch; }
.ce-price { font-size:12.5px; color:var(--text2); margin-top:10px; }
.ce-price b { color:var(--text); }

/* Checks manager view */
.check-head { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; }
.check-group { margin-bottom:8px; }
.check-row { display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:12px 14px; border:1px solid var(--hairline); border-radius:12px; margin-bottom:8px; background:var(--bg2); }
.check-row-main { min-width:0; }
.check-row-title { font-size:14px; font-weight:650; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.check-row-main p { font-size:12.5px; color:var(--text2); margin-top:3px; }
.check-row-main .check-how { font-size:11.5px; color:var(--text3); }
.check-row-actions { display:flex; gap:8px; flex-shrink:0; }
.check-row-actions .danger { color:var(--danger); }
.tag--mine { font-size:10.5px; font-weight:650; color:var(--accent); background:var(--bg1);
  border:1px solid var(--hairline); border-radius:20px; padding:1px 8px; }

/* Compact mode: the same row language as .adapter-item, just denser, inside
   a .menu popover — one visual system for picking checks everywhere. */
.ap--compact { min-width:240px; max-width:calc(100vw - 56px); }
.ap--compact .ap-filter { margin:0 0 6px; }
.ap--compact .ap-list { max-height:280px; overflow:auto; display:flex; flex-direction:column; }
.ap-row {
  display:flex; align-items:center; gap:9px; width:100%; text-align:left; border:0;
  background:none; color:var(--text2); padding:7px 8px; border-radius:8px; font-size:13px;
  cursor:pointer; font-family:var(--font); transition:background var(--t-fast), color var(--t-fast);
}
@media (hover:hover) { .ap-row:hover { background:var(--bg2); color:var(--text); } }
.ap-row-ck {
  display:flex; align-items:center; justify-content:center; width:16px; height:16px; flex-shrink:0;
  border:1.5px solid var(--hairline-strong); border-radius:5px; color:transparent;
  transition:background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
/* color:inherit so the check glyph tracks the box's own color (transparent when
   unticked = empty box) and isn't forced grey by the `.menu .i` popover override
   — which made unselected boxes look pre-ticked inside the Add-check popover. */
.ap-row-ck .i { width:11px; height:11px; color:inherit; }
.ap-row.on { color:var(--text); }
.ap-row.on .ap-row-ck { background:var(--accent); border-color:var(--accent); color:var(--bg0); animation:pop .3s var(--ease-spring); }
.ap-row-label { flex:1; min-width:0; }
.ap-row .kind {
  flex-shrink:0; font-size:10.5px; color:var(--text3); border:1px solid var(--hairline-strong);
  border-radius:4px; padding:0 5px; letter-spacing:.05em;
}
.tray { display:flex; flex-wrap:wrap; gap:7px; align-items:center; margin-top:14px; padding-top:14px; border-top:1px solid var(--hairline); }
.tray .none { color:var(--text3); font-size:12.5px; }
.form-msg { margin-top:12px; font-size:13.5px; color:var(--text2); }
.form-msg.error { color:var(--danger); }

/* ---- store ------------------------------------------------------------------------ */
.store-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); gap:14px; }
.store-card {
  display:flex; flex-direction:column; gap:8px; background:var(--bg1); border:1px solid var(--hairline);
  border-radius:var(--r-l); padding:16px 17px 14px;
  transition:transform var(--t-fast) var(--ease-out), border-color var(--t-fast);
}
@media (hover:hover) { .store-card:hover { transform:translateY(-2px); border-color:var(--hairline-strong); } }
.store-card.owned { border-color:var(--accent-ring); background:linear-gradient(180deg,var(--accent-soft),var(--bg1)); }
.store-head { display:flex; align-items:baseline; gap:10px; justify-content:space-between; }
.store-head b { font-size:14.5px; }
.store-card p { color:var(--text2); font-size:12.5px; }
.store-how { color:var(--text3) !important; font-size:11.5px !important; }
.store-rec { color:var(--text3) !important; font-size:11px !important; font-family:var(--font-mono, monospace); }
.store-foot { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:auto; padding-top:8px; }
.store-price { font-family:var(--font-display); font-size:17px; font-weight:700; }
.store-price small { color:var(--text3); font-size:11px; font-weight:500; font-family:var(--font); }
.store-owned { display:inline-flex; align-items:center; gap:6px; color:var(--ok); font-size:12.5px; font-weight:600; }
/* Native app: purchases happen on the web (App Store rules), so cards show a
   plain hint instead of a buy button. */
.store-onweb { color:var(--text3); font-size:12px; font-weight:600; white-space:nowrap; }
.onweb-note { background:var(--bg2); border:1px solid var(--hairline); border-radius:var(--r-m);
  padding:12px 14px; margin-bottom:16px; color:var(--text2); font-size:13px; }
.onweb-note b { color:var(--text); }
/* Pinned to the top of the Store on native — the only route to buying, so it
   must be the first thing seen, not just another card in the list. */
.onweb-note--pinned {
  position:sticky; top:0; z-index:5; background:var(--accent-soft);
  border-color:var(--accent-ring); font-weight:600; color:var(--text);
}

/* ---- store: multi-select checkout --------------------------------------------- */
/* Reserve a gutter on the right for the selection badge so it doesn't overlap
   the alerting/report/per-frame tag already sitting in that corner. */
.store-card.selectable { cursor:pointer; padding-right:38px; }
.store-card.sel { border-color:var(--accent); box-shadow:0 0 0 1px var(--accent); }
.store-card .store-sel-badge {
  position:absolute; top:16px; right:16px; width:20px; height:20px; border-radius:50%;
  border:1.5px solid var(--hairline-strong); background:var(--bg2); display:flex; align-items:center; justify-content:center;
}
.store-card.sel .store-sel-badge { background:var(--grad); border-color:transparent; }
.store-card.sel .store-sel-badge .i { color:var(--on-accent); }
.store-card { position:relative; }
.store-checkout-bar {
  position:fixed; left:50%; transform:translateX(-50%); bottom:calc(18px + env(safe-area-inset-bottom));
  z-index:45; display:flex; align-items:center; gap:14px; padding:10px 12px 10px 20px;
  background:var(--bg3); border:1px solid var(--hairline-strong); border-radius:999px;
  box-shadow:var(--sh-2); max-width:calc(100vw - 32px); animation:menuin var(--t-fast) var(--ease-out);
}
.store-checkout-bar b { font-size:13.5px; white-space:nowrap; }
@media (max-width:1024px) { .store-checkout-bar { bottom:calc(var(--tabbar-h) + 14px); } }

/* ---- onboarding --------------------------------------------------------------------- */
.ob-wrap { max-width:560px; margin:0 auto; padding:12px 0 32px; }
.ob-wrap--wide { max-width:980px; }

/* ---- plan trial picker (onboarding) ------------------------------------------- */
.ob-hero { text-align:center; margin-bottom:22px; }
.ob-hero .ob-sub { max-width:620px; margin:8px auto 0; }
.plan-freenote {
  max-width:640px; margin:14px auto 0; padding:12px 16px; font-size:13px; line-height:1.5;
  color:var(--text2); text-align:center; border-radius:var(--r-m);
  background:color-mix(in srgb, var(--ok) 8%, var(--bg2));
  border:1px solid color-mix(in srgb, var(--ok) 30%, transparent);
}
.plan-freenote b { color:var(--text); }
.plan-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:16px; align-items:stretch; }
.plan-card {
  position:relative; display:flex; flex-direction:column; gap:8px;
  background:var(--bg1); border:1px solid var(--hairline); border-radius:var(--r-l);
  padding:22px 20px; box-shadow:var(--sh-1); animation:rise var(--t-med) var(--ease-out);
}
.plan-card--pop { border-color:var(--accent); box-shadow:0 0 0 1px var(--accent), var(--sh-2); }
.plan-badge {
  position:absolute; top:-10px; left:50%; transform:translateX(-50%);
  background:var(--accent); color:#fff; font-size:11px; font-weight:700; letter-spacing:.04em;
  text-transform:uppercase; padding:3px 10px; border-radius:999px; white-space:nowrap;
}
.plan-name { font-family:var(--font-display); font-size:19px; font-weight:700; }
.plan-price { font-family:var(--font-display); font-size:32px; font-weight:800; line-height:1; }
.plan-price small { font-size:14px; font-weight:600; color:var(--text3); }
.plan-credits { font-size:13.5px; color:var(--text2); }
.plan-credits b { color:var(--text); font-variant-numeric:tabular-nums; }
.plan-blurb { font-size:12.5px; color:var(--text3); min-height:32px; }
.plan-features { list-style:none; display:flex; flex-direction:column; gap:6px; margin:4px 0; padding:0; }
.plan-features li { display:flex; align-items:flex-start; gap:8px; font-size:13px; color:var(--text2); }
.plan-features li .i { color:var(--ok); flex:0 0 auto; margin-top:1px; }
.plan-examples {
  background:var(--bg2); border:1px solid var(--hairline); border-radius:var(--r-m);
  padding:10px 12px; margin-top:auto; display:flex; flex-direction:column; gap:2px;
}
.plan-examples span { font-size:10px; text-transform:uppercase; letter-spacing:.06em; color:var(--text3); font-weight:600; }
.plan-examples b { font-size:13px; font-variant-numeric:tabular-nums; }
.plan-examples small { font-size:11px; color:var(--text3); }
.plan-cta { margin-top:6px; width:100%; }
.plan-autocharge {
  display:flex; align-items:flex-start; gap:10px; margin:20px auto 0; max-width:620px;
  font-size:13px; color:var(--text2); cursor:pointer;
}
.plan-autocharge input { width:17px; height:17px; margin-top:1px; accent-color:var(--accent); flex:0 0 auto; }
.ob-skip { text-align:center; margin-top:16px; }
.ob-skip a { color:var(--text3); font-size:13px; cursor:pointer; }
@media (hover:hover) { .ob-skip a:hover { color:var(--text); text-decoration:underline; } }
.usage-forecast {
  margin-top:10px; padding:9px 12px; font-size:12.5px; border-radius:var(--r-m);
  color:var(--warn); background:color-mix(in srgb, var(--warn) 9%, var(--bg2));
  border:1px solid color-mix(in srgb, var(--warn) 30%, transparent);
}
@media (max-width:820px) {
  .plan-grid { grid-template-columns:1fr; }
  .plan-examples { margin-top:8px; }
}

/* ---- Account: API keys & agent connections (MCP) ---- */
.api-keys { display:flex; flex-direction:column; gap:8px; margin-top:12px; }
.key-row {
  display:flex; align-items:center; gap:10px 14px; flex-wrap:wrap; padding:10px 12px;
  border:1px solid var(--hairline); border-radius:var(--r-m); background:var(--bg2);
}
.key-row .key-name { font-size:13px; font-weight:600; }
.key-row .key-prefix { font-family:var(--mono); font-size:11.5px; color:var(--text3); margin-top:2px; }
.key-row .key-meta { font-size:11.5px; color:var(--text3); margin-left:auto; }
.key-row .btn { flex:0 0 auto; }
.snippet-head { margin-top:18px; font-size:12.5px; font-weight:650; color:var(--text2); }
.api-snippet {
  margin:8px 0; padding:11px 13px; border:1px solid var(--hairline); border-radius:var(--r-m);
  background:var(--bg2); color:var(--text2); font-family:var(--mono); font-size:11.5px;
  line-height:1.55; white-space:pre-wrap; overflow-wrap:anywhere; user-select:all;
}
.api-connect { border-bottom:1px solid var(--hairline); padding:2px 0 10px; }
.api-connect summary {
  cursor:pointer; font-size:13px; font-weight:600; padding:8px 0; list-style-position:inside;
}
@media (hover:hover) { .api-connect summary:hover { color:var(--accent); } }
.key-once {
  margin:12px 0 4px; padding:12px; border:1px solid var(--hairline); border-radius:var(--r-m);
  background:var(--bg2); font-family:var(--mono); font-size:12.5px; word-break:break-all;
  user-select:all;
}
.ob-progress { height:4px; background:var(--bg2); border-radius:2px; margin-bottom:18px; overflow:hidden; }
.ob-progress span { display:block; height:100%; background:var(--grad); border-radius:2px; transition:width var(--t-slow) var(--ease-out); }
.ob-card {
  background:var(--bg1); border:1px solid var(--hairline); border-radius:var(--r-l);
  padding:28px 26px 24px; box-shadow:var(--sh-2); animation:rise var(--t-med) var(--ease-out);
}
.ob-title { font-family:var(--font-display); font-size:24px; font-weight:700; letter-spacing:-.3px; }
.ob-sub { color:var(--text2); font-size:14px; margin-top:6px; }
.ob-options { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:22px; }
.ob-opt {
  position:relative; display:flex; flex-direction:column; align-items:flex-start; gap:3px;
  background:var(--bg2); border:1px solid var(--hairline-strong); border-radius:var(--r-m);
  padding:14px 15px; cursor:pointer; text-align:left; font-family:var(--font); color:var(--text);
  transition:transform var(--t-fast) var(--ease-out), border-color var(--t-fast), background var(--t-fast);
}
@media (hover:hover) { .ob-opt:hover { transform:translateY(-1px); border-color:var(--accent-ring); } }
.ob-opt.on { background:var(--accent-soft); border-color:var(--accent-ring); }
.ob-ico { font-size:19px; }
.ob-opt-label { font-size:13.5px; font-weight:600; }
.ob-opt-hint { font-size:11.5px; color:var(--text3); }
.ob-tick { position:absolute; top:10px; right:10px; color:var(--accent); opacity:0; transform:scale(.6); transition:opacity var(--t-fast), transform var(--t-fast) var(--ease-spring); }
.ob-opt.on .ob-tick { opacity:1; transform:scale(1); }
.ob-nav { display:flex; justify-content:space-between; align-items:center; gap:12px; margin-top:26px; }
.ob-nav .btn--xl { margin-top:0; }
.ob-section { font-size:13px; font-weight:650; color:var(--text2); margin:26px 0 10px; }
.ob-section small { color:var(--text3); font-weight:400; }
.ob-adapters { display:flex; flex-wrap:wrap; gap:8px; }
.ob-adapter {
  display:inline-flex; align-items:center; gap:7px; padding:8px 14px; border-radius:999px;
  background:var(--bg2); border:1px solid var(--hairline-strong); color:var(--text3);
  font-size:13px; font-weight:600; cursor:pointer; font-family:var(--font);
  transition:border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
}
.ob-adapter.on { background:var(--accent-soft); border-color:var(--accent-ring); color:var(--text); }
.ob-presets { display:grid; grid-template-columns:repeat(3,1fr); gap:10px; }
.ob-preset {
  display:flex; flex-direction:column; gap:4px; align-items:flex-start; text-align:left;
  background:var(--bg2); border:1px solid var(--hairline-strong); border-radius:var(--r-m);
  padding:13px 14px; cursor:pointer; font-family:var(--font); color:var(--text);
  transition:border-color var(--t-fast), background var(--t-fast);
}
.ob-preset.on { background:var(--accent-soft); border-color:var(--accent-ring); }
.ob-preset b { font-size:13.5px; }
.ob-preset span { font-size:11.5px; color:var(--text2); }
.ob-preset-price { font-family:var(--font-display); font-weight:700; font-size:14px; color:var(--text) !important; margin-top:3px; }
.ob-math { border:1px solid var(--hairline); border-radius:var(--r-m); background:var(--bg2); padding:6px 16px; }
.ob-math-row { display:flex; justify-content:space-between; gap:14px; align-items:baseline; padding:9px 0; border-bottom:1px solid var(--hairline); font-size:13px; color:var(--text2); }
.ob-math-row b { font-family:var(--mono); font-size:12.5px; color:var(--text); white-space:nowrap; }
.ob-math-row.mult { color:var(--accent); font-weight:600; }
.ob-total { display:flex; justify-content:space-between; align-items:baseline; padding:13px 0 10px; font-size:14px; font-weight:650; }
.ob-total b { font-family:var(--font-display); font-size:28px; }
.ob-total b small { font-size:13px; color:var(--text2); font-weight:500; font-family:var(--font); }
.ob-stats { display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:12px; }
.ob-stat { background:var(--bg2); border:1px solid var(--hairline); border-radius:var(--r-m); padding:14px 15px; }
.ob-stat b { display:block; font-family:var(--font-display); font-size:21px; font-weight:700; margin-bottom:4px; }
.ob-stat p { font-size:12.5px; color:var(--text2); }
.ob-stat small { display:block; margin-top:6px; color:var(--text3); font-size:11px; }

/* Free-trial explainer on the onboarding review screen. */
.ob-trial { background:var(--bg2); border:1px solid var(--hairline); border-radius:var(--r-m);
  padding:13px 15px; font-size:13px; color:var(--text2); line-height:1.5; }
.ob-trial b { color:var(--text); font-weight:650; }

/* Home credit-balance banner (top of the usage card). */
.credit-bar { display:flex; justify-content:space-between; align-items:center; gap:14px; flex-wrap:wrap;
  padding:12px 14px; margin-bottom:14px; background:var(--bg2); border:1px solid var(--hairline); border-radius:var(--r-m); }
.credit-bar--paused { border-color:var(--danger); background:color-mix(in srgb, var(--danger) 8%, var(--bg2)); }
.credit-figure small { display:block; color:var(--text3); font-size:11px; }
.credit-figure b { font-family:var(--font-display); font-size:24px; font-weight:700; }
.credit-unit { font-size:13px; font-weight:500; color:var(--text3); }
.credit-state { display:flex; align-items:center; gap:10px; font-size:12.5px; color:var(--text2); }
.credit-state b { color:var(--text); }
.credit-warn { color:var(--danger); font-weight:650; }
.credit-link { color:var(--accent); font-weight:650; cursor:pointer; }
@media (hover:hover) { .credit-link:hover { text-decoration:underline; } }

/* ---- quick look ------------------------------------------------------------------- */
#quicklook {
  position:fixed; inset:0; z-index:100; display:none; align-items:center; justify-content:center;
  padding:24px; background:rgba(6,8,12,.72); backdrop-filter:blur(10px);
}
#quicklook.on { display:flex; animation:fade var(--t-fast) ease; }
@keyframes fade { from { opacity:0; } }
.ql-card {
  width:100%; max-width:920px; background:var(--bg1); border:1px solid var(--hairline-strong);
  border-radius:var(--r-l); overflow:hidden; box-shadow:var(--sh-3);
  animation:rise var(--t-med) var(--ease-out);
}
@keyframes rise { from { transform:translateY(14px) scale(.985); opacity:.6; } }
.ql-head { display:flex; align-items:center; gap:12px; padding:13px 18px; border-bottom:1px solid var(--hairline); }
.ql-titles { min-width:0; flex:1; }
.ql-titles b { display:block; font-size:15px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ql-sub { color:var(--text3); font-size:12.5px; font-family:var(--mono); }
.ql-x { border:0; background:none; color:var(--text3); cursor:pointer; border-radius:8px; width:32px; height:32px; display:flex; align-items:center; justify-content:center; }
@media (hover:hover) { .ql-x:hover { background:var(--bg3); color:var(--text); } }
/* Media stage: a stable 16:9 frame that contains any-aspect footage and fills
   the letterbox with a blurred zoom of the video instead of black bars, so a
   portrait clip reads as intentional and the surrounding layout never reflows. */
.player-stage { position:relative; width:100%; aspect-ratio:16/9; overflow:hidden; border-radius:var(--r-m); background:#000; }
.player-stage .player-blur { position:absolute; inset:0; z-index:0; background:#000 center/cover no-repeat; filter:blur(30px) saturate(1.3) brightness(.5); transform:scale(1.25); }
.player-stage > video, .player-stage > img { position:relative; z-index:1; width:100%; height:100%; object-fit:contain; display:block; background:transparent; }
/* Quick Look fits the CLIP's own aspect ratio — core.js `_qlFit` sets the card
   width from the video's real dimensions — so a portrait clip is a tall, snug
   card with NO side bars. The blurred-backdrop stage above is only for the fixed
   16:9 box on the full video page. */
#quicklook .ql-card { width:auto; max-width:min(96vw, 1100px); min-width:300px; }
#quicklook .player-stage { aspect-ratio:auto; width:100%; height:auto; max-height:84dvh; border-radius:0; background:#000; }
#quicklook .player-stage > video, #quicklook .player-stage > img { position:static; width:100%; height:auto; max-height:84dvh; object-fit:contain; }
#quicklook .player-blur { display:none; }

/* ---- toasts ------------------------------------------------------------------------ */
#toasts { position:fixed; right:22px; bottom:calc(22px + env(safe-area-inset-bottom)); z-index:110; display:flex; flex-direction:column; gap:8px; }
.toast {
  display:flex; gap:10px; align-items:center; background:var(--bg3); color:var(--text);
  border:1px solid var(--hairline-strong); border-left:3px solid var(--ok); border-radius:var(--r-m);
  padding:11px 16px; font-size:13.5px; box-shadow:var(--sh-3); max-width:380px;
  animation:toastin var(--t-med) var(--ease-spring);
}
.toast.warn { border-left-color:var(--warn); }
.toast.danger { border-left-color:var(--danger); }
.toast.out { opacity:0; transform:translateY(8px); transition:opacity var(--t-med), transform var(--t-med); }
@keyframes toastin { from { opacity:0; transform:translateY(12px); } }

/* ---- skeletons ---------------------------------------------------------------------- */
.skel {
  background:linear-gradient(100deg, var(--bg2) 40%, var(--bg3) 50%, var(--bg2) 60%);
  background-size:200% 100%; animation:shimmer 1.4s linear infinite; border-radius:var(--r-m);
}
@keyframes shimmer { to { background-position:-200% 0; } }
.skel--tile { height:92px; }
.skel--card { aspect-ratio:16/12; }
.skel--row { height:64px; margin-bottom:8px; }

/* Suppress entry animations on poll-driven re-renders (Home adds .settled
   after its first data paint) so processing ticks don't replay the stagger. */
#view-home.settled .card, #view-home.settled .alert-card { animation:none; }

/* ---- home extras ----------------------------------------------------------------------- */
.mini-row { display:flex; gap:11px; align-items:center; padding:7px 6px; border-radius:9px; cursor:pointer; transition:background var(--t-fast); }
@media (hover:hover) { .mini-row:hover { background:var(--bg2); } }
.mini-row img { width:72px; height:40px; object-fit:cover; border-radius:6px; background:#000; flex-shrink:0; }
.mini-row .mtitle { flex:1; min-width:0; font-size:13px; font-weight:550; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mini-row small { color:var(--text3); font-size:11.5px; }

/* ---- home hub: "This week" pulse (search moved to Library) ------------------- */
.home-week { margin-bottom:0; }
#home-bottom > .empty { margin-top:22px; }   /* first-run CTA gap (was on .home-cols) */

/* ---- rail account block ------------------------------------------------------------ */
.account { margin-top:14px; padding-top:12px; display:flex; align-items:center; gap:8px; }
.account-id { display:flex; align-items:center; gap:10px; min-width:0; flex:1; }
.account-avatar {
  width:30px; height:30px; border-radius:50%; flex-shrink:0;
  display:flex; align-items:center; justify-content:center;
  background:var(--grad); color:var(--on-accent); font-weight:700; font-size:13px; font-family:var(--font-display);
}
.account-meta { min-width:0; line-height:1.25; }
.account-meta b { display:block; font-size:12.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.account-meta small { color:var(--text3); font-size:11px; }
.account { position:relative; }
.account-id { border:0; background:none; padding:0; margin:0; cursor:pointer; font:inherit; color:inherit; }
/* Account menu — opens upward from the rail on desktop, downward from the top
   bar on mobile (see the ≤1023 override). Holds Delete account so it's reachable
   on every layout. */
.account-menu {
  position:absolute; bottom:calc(100% + 8px); left:0; z-index:60; min-width:200px;
  background:var(--bg2); border:1px solid var(--hairline-strong); border-radius:var(--r-m);
  box-shadow:var(--sh-2); padding:6px; display:flex; flex-direction:column; gap:2px;
}
.account-menu-head { font-size:11px; color:var(--text3); padding:6px 10px 4px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.account-menu-item {
  display:flex; align-items:center; gap:9px; width:100%; text-align:left; border:0; background:none; cursor:pointer;
  color:var(--text); font:inherit; font-size:13px; padding:8px 10px; border-radius:var(--r-s);
  transition:background var(--t-fast);
}
@media (hover:hover) { .account-menu-item:hover { background:var(--bg3); } }
.account-menu-item.danger { color:var(--danger); }

/* Confirm dialog (irreversible actions) */
.confirm-wrap {
  position:fixed; inset:0; z-index:100; display:flex; align-items:center; justify-content:center;
  padding:20px; background:rgba(0,0,0,.55); -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
}
.confirm-card {
  width:100%; max-width:400px; background:var(--bg1); border:1px solid var(--hairline-strong);
  border-radius:var(--r-l); box-shadow:var(--sh-3); padding:22px 20px 18px;
}
.confirm-card h2 { font-family:var(--font-display); font-size:18px; font-weight:650; letter-spacing:-.01em; }
.confirm-card p { color:var(--text2); font-size:13.5px; margin-top:8px; line-height:1.5; }
.confirm-card .prompt-label { display:block; color:var(--text3); font-size:12.5px; margin-top:10px; }
.confirm-card .prompt-input {
  width:100%; margin-top:8px; padding:10px 12px; font-size:14px;
  border:1px solid var(--hairline-strong); border-radius:9px; background:var(--bg2); color:var(--text1);
}
.confirm-card .prompt-input:focus { outline:none; border-color:var(--accent-ring); }
.confirm-actions { display:flex; gap:10px; justify-content:flex-end; margin-top:20px; }

/* ---- access gate: email-first sign-in / waitlist --------------------------- */
.auth-wrap {
  min-height:calc(100dvh - 120px); display:flex; align-items:center; justify-content:center; padding:16px 0;
}
.auth-card {
  width:100%; max-width:412px; background:var(--bg1); border:1px solid var(--hairline);
  border-radius:var(--r-l); padding:34px 32px 26px; box-shadow:var(--sh-2);
  animation:rise var(--t-med) var(--ease-out);
}
.auth-mark { display:flex; align-items:center; gap:10px; margin-bottom:22px; }
.auth-word {
  font-family:var(--font-display); font-size:20px; font-weight:600; letter-spacing:-.02em;
  color:var(--text);
}
.auth-word .wm-dot { color:var(--accent); }
.auth-motif { color:var(--accent); display:inline-flex; }
.auth-title { font-family:var(--font-display); font-size:22px; font-weight:700; letter-spacing:-.3px; }
.auth-sub { color:var(--text2); font-size:13.5px; margin-top:5px; }
.auth-card form { margin-top:20px; }
.auth-card label { margin:14px 0 6px; }
.auth-err {
  margin-top:12px; padding:9px 12px; border-radius:9px; font-size:12.5px; font-weight:550;
  color:var(--danger); background:var(--danger-soft); border:1px solid rgba(255,90,77,.28);
  animation:pop var(--t-med) var(--ease-spring);
}
.auth-submit { width:100%; justify-content:center; margin-top:18px; padding:12px 16px; font-size:14.5px; }
.auth-alt { margin-top:18px; font-size:13px; color:var(--text2); }
.auth-alt a { font-weight:600; cursor:pointer; }
/* Quiet tertiary links under the auth card (the guest-continue pattern): the
   card has ONE job — authenticate — so every escape hatch is a text link,
   never a button competing with the primary action. */
.auth-demo { margin-top:20px; font-size:13px; color:var(--text3); display:flex; flex-direction:column; gap:7px; }
.auth-demo a { font-weight:600; cursor:pointer; color:var(--text2); }
.auth-demo a:hover { color:var(--text); }
.auth-tick {
  width:40px; height:40px; margin-bottom:16px; border-radius:50%;
  display:flex; align-items:center; justify-content:center; font-size:20px; font-weight:700;
  color:var(--accent); background:var(--accent-soft); border:1px solid var(--accent);
  animation:pop var(--t-med) var(--ease-spring);
}

/* ---- admin Users view --------------------------------------------------------- */
.usr-list { display:flex; flex-direction:column; gap:8px; margin-top:12px; }
.usr-row { display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:10px 12px; background:var(--bg2); border:1px solid var(--hairline); border-radius:var(--r-m); }
.usr-id { display:flex; align-items:center; gap:10px; min-width:0; }
.usr-avatar { flex:0 0 auto; width:30px; height:30px; border-radius:50%; display:grid; place-items:center;
  background:var(--accent); color:#fff; font-weight:700; font-size:13px; }
.usr-email { font-size:13.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis; }
.usr-meta { display:flex; align-items:center; gap:6px; margin-top:2px; flex-wrap:wrap; }
.usr-scope { font-size:11px; color:var(--text3); border:1px solid var(--hairline-strong); border-radius:4px; padding:1px 6px; }
.usr-scope--all { color:var(--ok); border-color:var(--ok); }
.usr-actions { display:flex; gap:6px; flex-wrap:wrap; justify-content:flex-end; }
.usr-edit-panel { margin-top:-2px; }
.usr-toggle { display:flex; align-items:center; gap:10px; cursor:pointer; font-size:13.5px; }
.usr-toggle input { width:16px; height:16px; accent-color:var(--accent); }

/* The everything-about-this-account grid inside Manage: label-over-value
   cells that wrap to the viewport (mobile gets 2-up, desktop 4-up). */
.usr-detail { display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr));
  gap:10px 14px; margin-bottom:14px; padding-bottom:12px; border-bottom:1px solid var(--hairline); }
.usr-detail-cell { display:flex; flex-direction:column; gap:1px; min-width:0; }
.usr-detail-cell span { font-size:10px; color:var(--text3); font-weight:600;
  letter-spacing:.04em; text-transform:uppercase; }
.usr-detail-cell b { font-size:12.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; font-variant-numeric:tabular-nums; }

/* Danger zone: separated so "delete this customer" never sits beside a
   routine control. The arm button stays quiet until pressed. */
.usr-danger { margin-top:14px; padding-top:12px; border-top:1px solid var(--hairline); }
.usr-danger-arm { color:var(--danger); }
.usr-danger-note { font-size:12.5px; color:var(--text2); margin-bottom:8px; max-width:56ch; }

/* Player placeholder once the media-retention sweep has removed the bytes —
   the analysis (descriptions, checks, reports) below it survives. */
.vd-removed { display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:8px; min-height:220px; padding:24px; text-align:center; background:#000;
  border-radius:var(--r-m); box-shadow:var(--sh-2); color:#fff; }
.vd-removed .i { width:28px; height:28px; opacity:.45; }
.vd-removed b { font-size:14.5px; }
.vd-removed span { font-size:12.5px; color:rgba(255,255,255,.65); max-width:44ch; }

/* Monitoring dashboard row: identity · a strip of metric cells · actions. */
.usr-row--wide { align-items:center; gap:16px; }
.usr-row--wide .usr-id { flex:1 1 190px; }
.usr-stats { display:flex; gap:16px; flex-wrap:wrap; flex:2 1 auto; justify-content:flex-end; }
.usr-stat { display:flex; flex-direction:column; align-items:flex-end; min-width:52px; }
.usr-stat b { font-size:15px; font-weight:700; font-variant-numeric:tabular-nums; line-height:1.2; }
.usr-stat span { font-size:10px; color:var(--text3); font-weight:600; letter-spacing:.04em; text-transform:uppercase; }
.usr-stat--muted b { font-weight:600; color:var(--text2); }
.usr-plan { text-transform:capitalize; }
.usr-plan--free { color:var(--accent); border-color:var(--accent); }
.usr-plan--paid { color:var(--ok); border-color:var(--ok); }
.usr-plan--admin { color:var(--warn); border-color:var(--warn); }
.usr-credit-row { display:flex; gap:8px; margin-top:10px; }
.usr-credit-input { flex:1 1 auto; max-width:240px; }
.usr-plan-row { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:10px; }
.usr-plan-row select.usr-credit-input { flex:0 1 200px; }
.usr-toggle--inline { flex:0 0 auto; white-space:nowrap; }

@media (max-width:1024px) {
  /* Stack the row on phones so the metric strip wraps under the identity. */
  .usr-row--wide { flex-direction:column; align-items:stretch; gap:10px; }
  .usr-stats { justify-content:flex-start; gap:14px; }
  .usr-stat { align-items:flex-start; }
  .usr-row--wide .usr-actions { justify-content:flex-start; }
}

/* Admin-only nav (the Users view) — shown only once renderAccount() sees
   store.user.admin and toggles body.is-admin. */
.admin-only { display:none !important; }
body.is-admin .admin-only { display:flex !important; }

/* Not-yet-subscribed accounts are locked to the plan page — hide the app nav
   (rail links, Add footage, mobile tab bar). Sign-out stays in the header. */
body.no-plan #nav,
body.no-plan .rail-add,
body.no-plan #tabbar { display:none !important; }

/* ---- responsive --------------------------------------------------------------------------- */
@media (max-width:1023px) {
  /* Rail becomes a slim translucent top bar (brand + account + theme); primary
     navigation moves to the bottom tab bar. */
  #rail {
    position:sticky; inset:auto; top:0; z-index:30; width:100%; flex-direction:row; align-items:center;
    padding:calc(10px + env(safe-area-inset-top)) calc(14px + env(safe-area-inset-right)) 10px calc(14px + env(safe-area-inset-left));
    gap:8px; border-right:0; border-bottom:1px solid var(--hairline);
    background:var(--rail-blur); backdrop-filter:blur(12px);
  }
  .brand { padding:0 6px 0 0; margin-right:auto; }
  .tagline { display:none; }
  #nav, .rail-add, #queue { display:none; }
  #tabbar { display:flex; }
  .theme-toggle { margin:0; padding:8px; border:0; }
  .theme-toggle .tt-label { display:none; }
  :root[data-theme="light"] .theme-toggle .tt-dark { display:none; }
  .account { margin-top:0; padding-top:0; }
  .account-meta { display:none; }
  /* Top bar on mobile: drop the menu down and right-align it under the avatar. */
  .account-menu { bottom:auto; top:calc(100% + 10px); left:auto; right:0; }
  #content {
    margin-left:0;
    padding:16px calc(14px + env(safe-area-inset-right)) calc(24px + var(--tabbar-h)) calc(14px + env(safe-area-inset-left));
  }
  .vd-cols, .add-cols { grid-template-columns:minmax(0,1fr); }
  /* Sit above the fixed tab bar. */
  .add-actions {
    bottom:calc(var(--tabbar-h) + 12px);
    margin:18px 0 calc(-24px - var(--tabbar-h)); padding:0;
  }
  /* Let the fixed-width inputs shrink rather than push the row past the screen
     edge in the tablet/landscape-phone band (before the ≤640 single-column
     rules apply). */
  .toolbar input[type=text] { max-width:100%; }
  .vrow input.rename { min-width:0; }
  .vd-player { position:static; }
  .alert-card { scroll-margin-top:64px; }
  /* The toolbar icons fill the whole strip beside the breadcrumbs — big,
     evenly-spread targets instead of four tiny buttons hugging the edge. */
  .lib-bar { flex-wrap:nowrap; gap:6px; }
  .lib-tools { flex:1; gap:6px; }
  .lib-tools .btn { flex:1; justify-content:center; min-height:42px; }
  .lib-tools .btn .i { width:19px; height:19px; }
  .lib-tools .btn span { display:none; }
  #toasts { bottom:calc(10px + var(--tabbar-h)); }
}
@media (max-width:640px) {
  .stats { grid-template-columns:1fr 1fr; gap:10px; }
  .stat { padding:14px 15px; }
  .stat b { font-size:22px; }
  .toolbar input[type=text] { width:100%; }
  .searchbar { flex-wrap:nowrap; }
  .dir-grid { grid-template-columns:repeat(auto-fill,minmax(105px,1fr)); gap:9px; }
  .dir-card { padding:12px 8px 10px; }
  .dir-card .dir-i { width:28px; height:28px; margin-bottom:5px; }
  .dir-card .dir-menu { opacity:1; }   /* no hover on touch — always reachable */
  .grid { grid-template-columns:1fr; }
  .store-grid { grid-template-columns:1fr; }
  /* Portrait clips at full phone width waste most of the screen on empty
     letterboxing either side — two columns keep results dense and scannable,
     each card still free to be as tall as its own aspect ratio needs. */
  .search-grid { column-width:150px; column-gap:10px; }
  .search-grid > .card { margin:0 0 10px; }
  .search-grid > .card .body { padding:8px 9px; }
  .search-grid > .card .meta { font-size:10.5px; }
  .search-grid > .card b { font-size:12.5px; margin-bottom:1px; }
  .ob-card { padding:20px 16px 18px; }
  .ob-options { grid-template-columns:1fr 1fr; gap:8px; }
  .ob-presets { grid-template-columns:1fr; }
  .ob-nav .btn--xl { padding:12px 16px; font-size:14px; flex:1; justify-content:center; }
  .vrow .vthumb { width:74px; height:44px; }
  /* The row taps straight through to the video detail page, where Watch, Rename,
     Move and Delete all live — so on a phone drop the inline icon rail that was
     otherwise crushing the title down to a couple of letters. */
  .vrow .row-actions { display:none; }
  /* ONE line: thumb · title (single line, "more" expands) · green check. The
     whole right side is the tap-to-select zone; the drag handle grips the full
     right edge as a tall touch target. */
  .vrow { padding:7px 30px 7px 4px; gap:10px; }
  .vrow .drag-handle { position:absolute; top:0; bottom:0; right:0; transform:none; height:auto; width:30px; }
  .dir-card .drag-handle { width:30px; height:30px; }
  /* Keep the alert time visible: let the meta line wrap onto its own row instead
     of end-truncating (which hid the timestamp and "x ago" off the right edge). */
  .alert-card .atop { flex-wrap:wrap; gap:2px 8px; }
  .alert-card .atop small { margin-left:0; flex-basis:100%; white-space:normal; overflow:visible; text-overflow:clip; }
  .vd-title h1 { font-size:18px; }
  /* Balance the header actions into one full-width, evenly-spaced row rather
     than three unevenly wrapping buttons crowding the title. */
  .vd-actions { width:100%; margin-left:0; }
  .vd-actions > .menu-wrap, .vd-actions > .btn { flex:1; }
  .vd-actions .menu-wrap .btn { width:100%; }
  .vd-actions .btn { justify-content:center; }
  .strip .fthumb { width:56px; height:32px; }
  #toasts { left:12px; right:12px; align-items:flex-end; }
  .toast { max-width:min(380px, 100%); }
  #quicklook { padding:10px; }
  .ql-head .btn { display:none; }   /* keep the head tight; ✕ still closes */
}

/* ---- Live monitoring grid (live.js) --------------------------------------------- */
.live-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(280px, 1fr));
  gap:16px; margin-top:4px; }
.live-tile { display:block; border:1px solid var(--hairline); border-radius:14px;
  overflow:hidden; background:var(--bg2); color:inherit;
  transition:border-color .15s var(--ease-out); }
@media (hover:hover) { .live-tile:hover { border-color:var(--accent-ring); } }
.live-tile-media { display:block; text-decoration:none; color:inherit; }
.live-tile-vid { position:relative; aspect-ratio:16/9; background:#000; overflow:hidden; }
.live-tile-vid img, .live-tile-vid video, .cap-preview { width:100%; height:100%; object-fit:cover; display:block; }
/* Real-time live players (livevideo.js) overlay the fallback frame — the img
   stays underneath as poster and reappears the instant the player tears down;
   badges keep a z-index so they stay on top of it. In the detail page's
   player-stage the video is CONTAINED above the blur backdrop — never
   stretched or cropped ("zoomed") — while grid tiles cover like any tile
   media; z-index clears the stage's poster img (z 1). */
.live-rt { position:absolute; inset:0; }
.player-stage .live-rt { z-index:2; object-fit:contain; background:transparent; }
.live-tile-vid .live-rt { object-fit:cover; }
.live-badge, .live-alerts { z-index:1; }
/* DVR scrub bar (detail page only): sits above the native control strip so a
   live session can be reviewed back to its start and snapped back to live. */
.live-dvr { position:absolute; left:10px; right:10px; bottom:52px; z-index:3;
  display:flex; align-items:center; gap:10px; padding:6px 10px;
  background:rgba(0,0,0,.55); border-radius:8px; backdrop-filter:blur(6px); }
.live-dvr input[type="range"] { flex:1; min-width:0; accent-color:var(--danger); height:18px; }
.live-dvr-time { font-size:11px; font-weight:650; color:#fff; font-variant-numeric:tabular-nums; white-space:nowrap; }
.live-dvr-live { border:0; border-radius:6px; padding:3px 8px; cursor:pointer;
  font-size:10.5px; font-weight:700; letter-spacing:.06em;
  color:#fff; background:rgba(255,255,255,.18); }
.live-dvr-live.on { background:var(--danger); }
.live-badge { position:absolute; top:8px; left:8px; display:flex; align-items:center; gap:5px;
  font-size:10.5px; font-weight:700; letter-spacing:.06em; color:#fff;
  background:rgba(0,0,0,.55); border-radius:6px; padding:3px 7px; }
.live-dot { width:7px; height:7px; border-radius:50%; background:var(--danger);
  box-shadow:0 0 0 0 rgba(229,57,53,.6); animation:livepulse 1.6s infinite; }
@keyframes livepulse { 0% { box-shadow:0 0 0 0 rgba(229,57,53,.55); } 70% { box-shadow:0 0 0 7px rgba(229,57,53,0); } 100% { box-shadow:0 0 0 0 rgba(229,57,53,0); } }
@media (prefers-reduced-motion: reduce) { .live-dot { animation:none; } }
.live-alerts { position:absolute; top:8px; right:8px; font-size:10.5px; font-weight:700;
  color:#fff; background:var(--danger); border-radius:6px; padding:3px 7px; }
.live-tile-meta { padding:10px 12px; }
.live-tile-title { font-size:13.5px; font-weight:650; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.live-watch-row { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.live-watch-row .chip { font-size:10.5px; padding:2px 8px; }
.live-watch-row .chip.crit { color:var(--danger); border-color:var(--danger); }
.live-none { font-size:11.5px; color:var(--text3); align-self:center; }

/* ---- Live tile controls (stop + inline quality/checks editing) ------------------- */
.live-tile-actions { display:flex; gap:8px; margin-top:10px; }
.live-tile-actions .btn { flex:0 0 auto; }
.live-panel { margin-top:12px; padding-top:12px; border-top:1px solid var(--hairline); }
.live-set-row { display:flex; flex-wrap:wrap; gap:12px; }
.live-set-row label { flex:1 1 130px; font-size:11.5px; color:var(--text3); display:flex; flex-direction:column; gap:4px; }
.live-set { width:100%; }
.live-set-label { font-size:11.5px; color:var(--text3); margin:12px 0 6px; }
.live-checks { display:flex; flex-wrap:wrap; gap:6px; }
.live-ck { cursor:pointer; border:1px solid var(--hairline-strong); background:var(--bg2);
  color:var(--text2); font-size:11px; padding:3px 9px; border-radius:999px; }
.live-ck.on { background:var(--grad); color:var(--on-accent); border-color:transparent; }
.cap-preview { background:#000; }

/* Add-footage: device picker (share any detected camera + the screen). */
.live-devices { display:flex; flex-direction:column; gap:8px; }
.live-dev { display:flex; align-items:center; gap:9px; font-size:13px; padding:8px 11px;
  border:1px solid var(--hairline-strong); border-radius:10px; cursor:pointer; background:var(--bg2); }
.live-dev input { width:16px; height:16px; accent-color:var(--accent); }

/* Add-footage: in-app service browser (search via the extension). */
.ext-results { display:flex; flex-direction:column; gap:8px; margin-top:10px;
  max-height:340px; overflow:auto; }
.ext-r { display:flex; align-items:center; gap:10px; padding:7px; font-size:13px;
  border:1px solid var(--hairline); border-radius:var(--r-m); background:var(--bg2); }
.ext-r img { width:88px; height:50px; object-fit:cover; border-radius:var(--r-s);
  background:#000; flex:none; }
.ext-r-meta { min-width:0; flex:1; }
.ext-r-title { font-weight:600; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; }
.ext-r-sub { color:var(--text2); font-size:12px; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.ext-r .live-dot-badge { color:var(--live); font-weight:700; font-size:11px; }

/* Cost figure in the quality estimate — red so a pricey setting is obvious. */
.cost-hi { color:var(--danger); font-weight:650; }

/* Itemised per-camera cost calculation — the actual $ math, shown at add time. */
.cost-card { border:1px solid var(--hairline-strong); border-radius:12px; padding:12px 14px;
  margin-top:10px; background:var(--bg2); }
.cost-head { font-size:12.5px; font-weight:650; }
.cost-calc { font-family:var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size:11.5px; color:var(--text2); line-height:1.7; margin:8px 0; }
.cost-totals { font-size:14px; }
.cost-note { font-size:11.5px; color:var(--text3); margin-top:4px; }
.cost-dim { color:var(--text3); }

/* Home: monthly compute meter + plan cards (credits are dollars). */
.usage-card { margin-top:18px; }
.usage-hint { font-size:11.5px; color:var(--text3); margin-top:10px; }

/* Notification preferences: one row per event, push/email checkboxes each. */
.notif-card { margin-top:18px; }
.notif-lead { font-size:12.5px; color:var(--text3); margin-bottom:14px; }
.notif-row { display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:12px 0; border-top:1px solid var(--hairline); flex-wrap:wrap; }
.notif-what { display:flex; flex-direction:column; gap:2px; min-width:0; }
.notif-what small { font-size:11.5px; color:var(--text3); }
.notif-cells { display:flex; gap:10px; flex-shrink:0; }
.notif-toggle { display:inline-flex; align-items:center; gap:6px; font-size:13px;
  padding:6px 12px; border:1px solid var(--hairline); border-radius:var(--r-m);
  cursor:pointer; user-select:none; }
.notif-toggle input { accent-color:var(--accent); cursor:pointer; }
.notif-toggle.is-disabled { opacity:.5; cursor:not-allowed; }
.notif-toggle.is-disabled input { cursor:not-allowed; }

/* Add-footage: two quality dials (resolution + frame rate). */
.q-dials { display:flex; flex-wrap:wrap; gap:12px; }
.q-dial { flex:1 1 150px; display:flex; flex-direction:column; gap:4px; }
.q-dial small { font-size:11.5px; color:var(--text3); }
.q-dial select { width:100%; }

/* Persistent "recording now" pill — fixed, centred, above the mobile tab bar. */
#rec-pill { position:fixed; left:50%; transform:translateX(-50%); bottom:calc(18px + env(safe-area-inset-bottom));
  z-index:45; display:inline-flex; align-items:center; gap:9px; padding:10px 18px; cursor:pointer;
  background:var(--bg3); color:var(--text); border:1px solid var(--hairline-strong); border-radius:999px;
  font-family:var(--font); font-size:13px; font-weight:600; box-shadow:var(--sh-2);
  animation:menuin var(--t-fast) var(--ease-out); }
@media (hover:hover) { #rec-pill:hover { border-color:var(--accent-ring); } }
.rec-dot { width:9px; height:9px; border-radius:50%; background:var(--danger);
  box-shadow:0 0 0 0 rgba(229,57,53,.6); animation:livepulse 1.6s infinite; }
@media (prefers-reduced-motion: reduce) { .rec-dot { animation:none; } }
@media (max-width:1024px) { #rec-pill { bottom:calc(var(--tabbar-h) + 14px); } }

/* ============================ Support chat ============================ */
/* Floating launcher (a signed-in customer reaching support) + the message
   panel. The owner answers from the Inbox view below. Shares the message-bubble
   look between the two. Built in js/chat.js. */
#chat-widget { position:fixed; right:20px; bottom:calc(20px + env(safe-area-inset-bottom));
  z-index:60; display:flex; flex-direction:column; align-items:flex-end; gap:12px; }
@media (max-width:1024px) { #chat-widget { right:14px; bottom:calc(var(--tabbar-h) + 14px); } }

.chat-fab { position:relative; width:56px; height:56px; border-radius:50%; border:none; cursor:pointer;
  background:var(--grad); color:var(--on-accent); box-shadow:var(--glow), var(--sh-2);
  display:grid; place-items:center;
  transition:transform var(--t-fast) var(--ease-spring), filter var(--t-fast); }
@media (hover:hover) { .chat-fab:hover { filter:brightness(1.08); transform:translateY(-1px); } }
.chat-fab .i { width:24px; height:24px; grid-area:1/1;
  transition:opacity var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out); }
.chat-fab .chat-fab-close { opacity:0; transform:rotate(-90deg) scale(.5); }
.chat-fab.on .chat-fab-open { opacity:0; transform:rotate(90deg) scale(.5); }
.chat-fab.on .chat-fab-close { opacity:1; transform:none; }
.chat-badge { position:absolute; top:-1px; right:-1px; width:14px; height:14px; border-radius:50%;
  background:var(--live); border:2px solid var(--bg0); }

.chat-greet { position:relative; max-width:230px; background:var(--bg2); color:var(--text);
  border:1px solid var(--hairline-strong); border-radius:var(--r-l); padding:11px 15px;
  font-size:13.5px; font-weight:600; box-shadow:var(--sh-2);
  animation:menuin var(--t-med) var(--ease-spring); }
.chat-greet-x { position:absolute; top:-9px; right:-9px; width:21px; height:21px; border-radius:50%;
  border:1px solid var(--hairline-strong); background:var(--bg3); color:var(--text2);
  cursor:pointer; font-size:14px;
  /* Center the × glyph properly: the UA's default button padding + line-height
     metrics sat it visibly off-centre in the 21px circle. */
  padding:0; line-height:0; display:flex; align-items:center; justify-content:center; }
@media (hover:hover) { .chat-greet-x:hover { color:var(--text); } }

.chat-panel { width:min(372px, calc(100vw - 28px)); height:min(524px, calc(100dvh - 150px));
  background:var(--bg1); border:1px solid var(--hairline-strong); border-radius:var(--r-l);
  box-shadow:var(--sh-3); display:flex; flex-direction:column; overflow:hidden;
  animation:menuin var(--t-med) var(--ease-out); }
.chat-head { display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:14px 16px; border-bottom:1px solid var(--hairline); background:var(--bg2); }
.chat-head-id { display:flex; align-items:center; gap:11px; min-width:0; }
.chat-head-id b { font-size:14px; display:block; }
.chat-head-id small { color:var(--text2); font-size:11.5px; display:block; }
.chat-avatar { width:34px; height:34px; flex:none; border-radius:50%; display:grid; place-items:center;
  background:var(--accent-soft); color:var(--accent); }
.chat-avatar .i { width:18px; height:18px; }
/* Same shape as .ql-x (the known-good header close): a fixed 32px square,
   flex-centred — the old padding+grid combo drifted with the icon's inline
   metrics. flex-shrink:0 so a long title can't squeeze it. */
.chat-x { background:none; border:none; color:var(--text2); cursor:pointer; width:32px; height:32px;
  border-radius:8px; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
@media (hover:hover) { .chat-x:hover { color:var(--text); } }

.chat-log { flex:1; overflow-y:auto; padding:16px; display:flex; flex-direction:column; gap:8px; }
.chat-empty { margin:auto; text-align:center; color:var(--text3); font-size:13px; max-width:230px; line-height:1.5; }
.chat-msg { display:flex; }
.chat-msg--me { justify-content:flex-end; }
.chat-msg--them { justify-content:flex-start; }
.chat-bubble { max-width:80%; padding:9px 13px; border-radius:14px; font-size:13.5px; line-height:1.45;
  white-space:pre-wrap; overflow-wrap:anywhere; }
.chat-msg--me .chat-bubble { background:var(--grad); color:var(--on-accent); border-bottom-right-radius:5px; }
.chat-msg--them .chat-bubble { background:var(--bg3); color:var(--text); border-bottom-left-radius:5px; }
/* Proactive-nudge call to action (inside an incoming bubble). */
.chat-cta { display:flex; width:fit-content; margin-top:9px; padding:7px 13px; border:none; cursor:pointer;
  border-radius:999px; background:var(--grad); color:var(--on-accent); font-family:var(--font); font-size:12.5px; font-weight:600; }
@media (hover:hover) { .chat-cta:hover { filter:brightness(1.08); } }

.chat-composer { display:flex; align-items:center; gap:8px; padding:12px;
  border-top:1px solid var(--hairline); background:var(--bg2); }
.chat-composer input { flex:1; min-width:0; background:var(--bg0); border:1px solid var(--hairline-strong);
  border-radius:999px; padding:10px 15px; color:var(--text); font-family:var(--font); font-size:13.5px; }
.chat-composer input:focus { outline:none; border-color:var(--accent-ring); }
.chat-send { width:38px; height:38px; flex:none; border-radius:50%; border:none; cursor:pointer;
  background:var(--grad); color:var(--on-accent); display:grid; place-items:center; transition:filter var(--t-fast); }
@media (hover:hover) { .chat-send:hover { filter:brightness(1.08); } }
.chat-send .i { width:18px; height:18px; }

/* ---- Owner inbox (#view-inbox) ---- */
#view-inbox .ibx { display:grid; grid-template-columns:322px 1fr; gap:16px; align-items:start; }
#view-inbox .ibx-list { padding:8px; max-height:calc(100dvh - 220px); overflow-y:auto;
  display:flex; flex-direction:column; gap:2px; }
#view-inbox .ibx-detail { padding:0; overflow:hidden; min-height:min(64dvh, 560px); display:flex; flex-direction:column; }
.ibx-row { display:flex; align-items:center; gap:11px; width:100%; text-align:left; cursor:pointer;
  background:none; border:none; padding:11px 12px; border-radius:var(--r-m); color:var(--text); font-family:var(--font); }
@media (hover:hover) { .ibx-row:hover { background:var(--bg2); } }
.ibx-row.on { background:var(--accent-soft); }
.ibx-avatar { width:36px; height:36px; flex:none; border-radius:50%; display:grid; place-items:center;
  background:var(--bg3); color:var(--text2); font-weight:700; font-size:14px; }
.ibx-row.unread .ibx-avatar { background:var(--accent-soft); color:var(--accent); }
.ibx-row-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.ibx-row-top { display:flex; justify-content:space-between; gap:8px; align-items:baseline; }
.ibx-row-top b { font-size:13.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ibx-time { color:var(--text3); font-size:11px; flex:none; }
.ibx-preview { color:var(--text2); font-size:12.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ibx-row.unread .ibx-preview { color:var(--text); font-weight:600; }
.ibx-dot { width:9px; height:9px; flex:none; border-radius:50%; background:var(--accent); }
.ibx-thread-head { display:flex; align-items:center; gap:10px; padding:14px 16px;
  border-bottom:1px solid var(--hairline); background:var(--bg2); }
.ibx-thread-head b { font-size:14px; display:block; }
.ibx-thread-head small { color:var(--text2); font-size:11.5px; display:block;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Owner-started chat: the New-chat button atop the list + the compose pane. */
.ibx-new { margin:2px 4px 8px; align-self:flex-start; }
.ibx-compose { padding:14px 16px; }
.ibx-compose label { margin:0 0 6px; }
.ibx-compose select { width:100%; }

.ibx-back { display:none; background:none; border:none; color:var(--text2); cursor:pointer;
  padding:4px; transform:rotate(180deg); place-items:center; }
@media (hover:hover) { .ibx-back:hover { color:var(--text); } }
.ibx-log { flex:1; max-height:none; }
.ibx-empty { margin:auto; display:flex; flex-direction:column; align-items:center; gap:10px;
  color:var(--text3); padding:40px 24px; text-align:center; }
.ibx-empty .i { width:32px; height:32px; opacity:.5; }

/* Inbox nav unread dot (rail nav + the mobile top-bar shortcut). */
#nav a[data-nav="inbox"], .rail-inbox { position:relative; }
[data-nav="inbox"].has-unread::after { content:""; position:absolute; top:7px; right:12px;
  width:8px; height:8px; border-radius:50%; background:var(--live); }
.rail-inbox.has-unread::after { top:4px; right:4px; }

/* Mobile top-bar Inbox shortcut: only exists <1024px (the rail nav's Inbox link
   covers desktop) and only for admins. Both display rules carry !important to
   arbitrate with .admin-only's display:flex !important at equal specificity. */
body.is-admin .rail-inbox { display:none !important; }
@media (max-width:1023px) {
  body.is-admin .rail-inbox {
    display:flex !important; align-items:center; justify-content:center;
    width:38px; height:38px; border-radius:9px; color:var(--text2);
    transition:background var(--t-fast), color var(--t-fast);
  }
  .rail-inbox .i { width:20px; height:20px; }
  .rail-inbox.active { color:var(--accent); }
  .rail-inbox:active { background:var(--bg3); }
}

/* Mobile top-bar Alerts bell: on phones Alerts leaves the tab bar (so Add sits
   dead-centre) and rides the header top-right, carrying its unread badge. Hidden
   on desktop — the rail nav's Alerts link covers it there. */
.rail-alerts { display:none; }
#tabbar a[data-nav="alerts"] { display:none; }   /* Alerts lives in the top bar on mobile */
@media (max-width:1023px) {
  .rail-alerts {
    display:flex; position:relative; align-items:center; justify-content:center;
    width:38px; height:38px; border-radius:9px; color:var(--text2);
    transition:background var(--t-fast), color var(--t-fast);
  }
  .rail-alerts .i { width:20px; height:20px; }
  .rail-alerts.active { color:var(--accent); }
  .rail-alerts:active { background:var(--bg3); }
  .rail-alerts .navbadge { position:absolute; top:-3px; right:-3px; }
}

@media (max-width:860px) {
  #view-inbox .ibx { grid-template-columns:1fr; }
  #view-inbox .ibx-list { max-height:none; }
  #view-inbox .ibx-detail { display:none; }
  #view-inbox .ibx--detail .ibx-list { display:none; }
  #view-inbox .ibx--detail .ibx-detail { display:flex; min-height:calc(100dvh - 190px); }
  .ibx-back { display:grid; }
}

/* ============================ press feel (touch-first) ============================
   Every :hover above is guarded behind @media(hover:hover); these :active states
   are the tap replacement — an instant 60ms press-down, released at each
   element's own transition speed. Last in the sheet so they win the cascade.
   Transform/opacity/background only. */
.card:active, .stat:active, .dir-card:active, .add-type-card:active,
.store-card.selectable:active, .ob-opt:active, .ob-preset:active, .chip:active,
.live-tile:active { transform:scale(.985); transition-duration:60ms; }
.alert-card:active { transform:translateX(2px) scale(.99); transition-duration:60ms; }
.vrow:active, .mini-row:active, .tl-body:active, .ibx-row:active, .adapter-item:active,
.menu button:active, .account-menu-item:active, .crumb:active,
.ap-row:active, .check-row:active, .theme-toggle:active, #queue:active { background:var(--bg3); }
.icon-btn:active, .menu-btn:active, .ql-x:active, .lib-search-x:active,
.chat-x:active {
  background:var(--bg3); color:var(--text); transform:scale(.9); transition-duration:60ms;
}
.chat-fab:active, .chat-send:active, .chat-cta:active, #rec-pill:active,
#tabbar .tab-add-btn:active { transform:scale(.96); transition-duration:60ms; }
#tabbar a:active .i { transform:scale(.86); }

/* Fingertip-sized hit areas for the 30px icon buttons — the visual stays small,
   the target grows to ~44px via an invisible hit-extension. */
@media (pointer:coarse) {
  .icon-btn, .menu-btn, .ql-x, .lib-search-x, .chat-x,
  .chat-greet-x, .vd-title .edit { position:relative; }
  .icon-btn::after, .menu-btn::after, .ql-x::after, .lib-search-x::after,
  .chat-x::after, .chat-greet-x::after, .vd-title .edit::after {
    content:""; position:absolute; inset:-7px;
  }
  .crumb { padding:8px 10px; }
}

/* Tab bar: a one-shot spring pop + accent dot when a tab becomes active. The
   gradient Add pill is its own signal, so it skips the dot. Inert under
   prefers-reduced-motion via the global kill at the top of the sheet. */
#tabbar a { position:relative; }
#tabbar a .i { transition:transform var(--t-fast) var(--ease-out); }
#tabbar a.active { font-weight:650; }
#tabbar a.active .i { animation:tabpop var(--t-slow) var(--ease-spring); }
@keyframes tabpop { 50% { transform:scale(1.18) translateY(-1px); } }
#tabbar a.active:not(.tab-add)::after {
  content:""; position:absolute; bottom:3px; left:calc(50% - 2px);
  width:4px; height:4px; border-radius:50%; background:var(--accent);
  animation:pop var(--t-med) var(--ease-spring);
}

/* ============================ navigation transitions ============================
   View Transitions path (Chromium, WKWebView from iOS 18). The router stamps
   <html data-navdir> per navigation: tab-bar neighbours slide laterally, a
   video drill rises in and sinks back out, everything else cross-fades.
   Browsers without VT keep the plain `viewin` entry fade above. The fixed
   chrome snapshots under its own names so the blur never flashes mid-swap. */
@supports (view-transition-name: content) {
  #content > section { animation:none; }   /* VT owns the swap in these browsers */
  #content { view-transition-name:content; }
  #rail { view-transition-name:rail; }
  #tabbar { view-transition-name:tabbar; }
  ::view-transition-old(content) { animation:vt-fade-out var(--t-med) var(--ease-out) both; }
  ::view-transition-new(content) { animation:vt-fade-in var(--t-med) var(--ease-out) both; }
  html[data-navdir="fwd"] ::view-transition-old(content) { animation-name:vt-out-left; }
  html[data-navdir="fwd"] ::view-transition-new(content) { animation-name:vt-in-right; }
  html[data-navdir="back"] ::view-transition-old(content) { animation-name:vt-out-right; }
  html[data-navdir="back"] ::view-transition-new(content) { animation-name:vt-in-left; }
  html[data-navdir="drill"] ::view-transition-new(content) { animation-name:vt-in-rise; }
  html[data-navdir="pop"] ::view-transition-new(content) { animation-name:vt-in-sink; }
}
@keyframes vt-fade-out { to { opacity:0; } }
@keyframes vt-fade-in { from { opacity:0; } }
@keyframes vt-out-left { to { opacity:0; transform:translateX(-20px); } }
@keyframes vt-in-right { from { opacity:0; transform:translateX(20px); } }
@keyframes vt-out-right { to { opacity:0; transform:translateX(20px); } }
@keyframes vt-in-left { from { opacity:0; transform:translateX(-20px); } }
@keyframes vt-in-rise { from { opacity:0; transform:translateY(12px); } }
@keyframes vt-in-sink { from { opacity:0; transform:translateY(-8px); } }

/* ---- bottom sheet: the touch presentation of the popover menus ---------------
   Same inner markup as the floats (openSheet in core.js); the wrap is the
   backdrop. The .sheet-stack holds a dedicated grab strip (touch-action:none —
   what makes swipe-to-dismiss actually work) ABOVE the .menu.sheet, as a
   sibling, so callers' innerHTML writes can't remove it. */
.sheet-wrap {
  position:fixed; inset:0; z-index:70; display:flex; flex-direction:column;
  justify-content:flex-end; background:rgba(6,8,12,.45); animation:fade var(--t-fast) ease;
}
.sheet-stack {
  width:100%; max-height:82dvh; display:flex; flex-direction:column;
  animation:sheetin var(--t-med) var(--ease-out);
  transition:transform var(--t-fast) var(--ease-out);
}
.sheet-grab {
  flex-shrink:0; touch-action:none; cursor:grab;
  background:var(--bg3); border:1px solid var(--hairline-strong); border-bottom:0;
  border-radius:16px 16px 0 0; padding:10px 0 8px;
  display:flex; justify-content:center;
}
.sheet-grab:active { cursor:grabbing; }
.sheet-grab span { width:40px; height:4.5px; border-radius:3px; background:var(--hairline-strong); display:block; }
.sheet-wrap .menu.sheet {
  position:static; width:100%; flex:1; min-height:0; overflow:auto; overscroll-behavior:contain;
  border-radius:0; border-top:0; border-bottom:0; margin:0;
  padding:2px 12px calc(14px + env(safe-area-inset-bottom));
}
.sheet .menu-inline { padding:8px 4px; }
/* .menu button's background:none out-specifies .btn--primary — restore the
   primary look for real CTAs inside menus/sheets (e.g. the picker's Apply). */
.menu .menu-inline .btn--primary {
  background:var(--grad); color:var(--on-accent); justify-content:center; font-weight:650;
}
.sheet > button, .sheet .menu-inline .btn { padding:13px 12px; font-size:14px; }
.sheet-wrap.out { animation:vt-fade-out var(--t-fast) ease both; }
.sheet-wrap.out .sheet-stack { animation:sheetout var(--t-fast) ease-in both; }
@keyframes sheetin { from { transform:translateY(100%); } }
@keyframes sheetout { to { transform:translateY(100%); } }

/* Full-page handoffs (SPA → live.html in the native shell) fade the shell out
   instead of cutting to a blank page mid-load. */
html.page-exit #shell { opacity:0; transition:opacity 150ms ease; }

/* ============================ mobile type & touch scale ============================
   Phones get a size bump across the highest-traffic surfaces: the 14px desktop
   base reads small in the hand, and 30px controls are fiddly. Type up ~1px,
   interactive rows and icon buttons to ≥36px visual (44px effective with the
   coarse-pointer hit extensions above). Inputs at 16px — comfortable, and the
   iOS no-zoom-on-focus size. */
@media (max-width:640px) {
  body { font-size:15px; }
  .btn { padding:12px 18px; font-size:14.5px; }
  .btn--sm { padding:8px 13px; font-size:13.5px; }
  .btn--xl { padding:15px 28px; font-size:15.5px; }
  input[type=text], input[type=number], input[type=email], input[type=password],
  select, textarea, .lib-search input { padding:12px 14px; font-size:16px; }
  .lib-search input { padding:11px 6px; }
  .view-head h1 { font-size:21px; }
  .lead { font-size:14.5px; }
  .section-title { font-size:16px; }
  .empty { font-size:14.5px; }
  .chip { padding:9px 15px; font-size:13.5px; }
  .status { font-size:12.5px; }
  .icon-btn, .menu-btn { width:36px; height:36px; }
  .icon-btn .i { width:18px; height:18px; }
  .account-avatar { width:34px; height:34px; font-size:14px; }
  .menu button, .account-menu-item { padding:12px; font-size:14px; }
  .menu .i { width:17px; height:17px; }
  .vrow .vname b { font-size:14.5px; }
  .vrow .vsub { font-size:12.5px; }
  .card b { font-size:15px; }
  .card p, .alert-card p { font-size:14px; }
  .mini-row .mtitle { font-size:14px; }
  .tl-text { font-size:14px; }
  .tabs button { padding:11px 16px; font-size:14.5px; }
  .adapter-item .al { font-size:14px; }
  .adapter-item p { font-size:12.5px; }
  .adapter-item input { width:17px; height:17px; }
  .add-type-card b { font-size:18px; }
  .add-type-card span { font-size:14px; }
  .crumbs { font-size:14.5px; }
  .toast { font-size:14px; }
}

/* Quick Look: fast exit (backdrop fade + card sink) and the swipe-down drag
   surface — the header owns the gesture so the video keeps scrubbing. */
#quicklook .ql-head { touch-action:none; }
#quicklook.out { animation:vt-fade-out var(--t-fast) ease both; }
#quicklook.out .ql-card { animation:ql-sink var(--t-fast) var(--ease-out) both; }
@keyframes ql-sink { to { transform:translateY(12px) scale(.985); opacity:0; } }

/* ---- Share sheet -------------------------------------------------------------
   Rides the body-mounted sheet (openSheet): a bottom sheet on phones, a centred
   dialog >=1024px. Compact: audience is a segmented control, perms a single
   grouped list. Sticky header (x) + sticky footer (CTA); the sheet is the one
   scroller. The Shared *view* styles (.share-card etc.) live further below. */
@media (min-width:1024px) {
  .sheet-wrap:has(.share-sheet) { justify-content:center; align-items:center; }
  .sheet-wrap:has(.share-sheet) .sheet-stack { max-width:440px; max-height:88dvh; }
  .sheet-wrap:has(.share-sheet) .sheet-grab { display:none; }   /* no grab handle in the desktop dialog */
  .share-sheet { border-radius:16px !important; }
}
.share-sheet { text-align:left; padding:0 !important; }   /* inner header/body/foot own the padding */

.share-head {
  position:sticky; top:0; z-index:2; display:flex; align-items:flex-start; gap:10px;
  padding:6px 14px 10px; background:var(--bg3);
}
.share-head-txt { flex:1; min-width:0; }
.share-head h3 { margin:0; font-family:var(--font-display); font-size:18px; line-height:1.2; }
.share-what { display:flex; align-items:center; gap:8px; margin-top:3px; min-width:0; }
.share-what-name { color:var(--text2); font-size:12.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.share-head .share-x {
  flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px;
  padding:0; border:0; border-radius:50%; background:var(--bg2); color:var(--text2); cursor:pointer;
  transition:background var(--t-fast), color var(--t-fast), transform var(--t-fast) var(--ease-out);
}
.share-head .share-x .i { width:18px; height:18px; }
.share-head .share-x:active { transform:scale(.92); }
@media (hover:hover){ .share-head .share-x:hover { background:var(--bg1); color:var(--text); } }

.share-body { padding:0 14px 4px; }
.share-foot {
  position:sticky; bottom:0; padding:10px 14px calc(12px + env(safe-area-inset-bottom));
  background:linear-gradient(to top, var(--bg3) 76%, transparent);
}
.share-do { width:100%; }

.share-sub {
  color:var(--text3); font-size:11px; text-transform:uppercase; letter-spacing:.05em;
  margin:14px 2px 7px; display:flex; align-items:center; gap:8px;
}
.share-view-pill {
  text-transform:none; letter-spacing:0; color:var(--ok); background:var(--ok-soft);
  border-radius:999px; padding:2px 8px; font-size:10px; font-weight:600;
}

/* Audience: full-width segmented control (reuses .seg look; overrides beat .menu button). */
.share-auds { display:flex; width:100%; margin-top:2px; }
.share-auds button {
  flex:1; width:auto; display:inline-flex; align-items:center; justify-content:center; gap:6px;
  padding:8px 6px; font-size:13px; text-align:center;
}
.share-auds .i { width:15px; height:15px; }
.share-auds button.on { color:var(--accent); }
@media (max-width:360px){ .share-auds button span { display:none; } }
.share-aud-hint { color:var(--text2); font-size:12px; line-height:1.45; margin:8px 2px 0; }
#share-email { margin-top:8px; }

/* Perms: one grouped, hairline-divided list — compact and tidy. */
.share-perms { border:1px solid var(--hairline); border-radius:var(--r-m); background:var(--bg2); overflow:hidden; }
.share-perm { display:flex; align-items:center; gap:12px; padding:9px 13px; cursor:pointer; border-top:1px solid var(--hairline); }
.share-perm:first-child { border-top:0; }
@media (hover:hover){ .share-perm:hover { background:var(--bg3); } }
.share-perm input { width:19px; height:19px; flex-shrink:0; accent-color:var(--accent2); cursor:pointer; }
.share-perm-txt { display:flex; flex-direction:column; gap:1px; min-width:0; }
.share-perm-b { font-size:13.5px; font-weight:550; }
.share-perm-s { color:var(--text3); font-size:11.5px; line-height:1.3; }
.share-perm--warn .share-perm-b { color:var(--danger); }

/* Created link — highlighted pill, readable mono URL + copy w/ success 'Copied'. */
.share-linkbox {
  display:flex; align-items:center; gap:8px; margin-top:12px; padding:6px 6px 6px 12px;
  border:1px solid var(--accent-ring); border-radius:12px; background:var(--accent-soft);
  animation:pop .3s var(--ease-spring);
}
.share-link-url {
  flex:1; min-width:0; width:auto; border:0; background:none; padding:0; color:var(--text);
  font-family:var(--mono); font-size:13px; text-overflow:ellipsis;
}
.share-link-url:focus { outline:none; }
.share-link-copy { flex-shrink:0; width:auto; transition:background var(--t-fast), color var(--t-fast); }
.share-link-copy.copied { background:var(--ok); color:#fff; box-shadow:none; }

/* Existing shares. */
.share-existing { margin-top:14px; border-top:1px solid var(--hairline); padding-top:2px; }
.share-existing-row { display:flex; align-items:center; justify-content:space-between; gap:10px; padding:9px 2px; border-bottom:1px solid var(--hairline); }
.share-existing-row:last-child { border-bottom:0; }
.share-existing-who { min-width:0; }
.share-existing-who b { font-size:13px; display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.share-existing-who small { color:var(--text3); font-size:11px; }
.share-existing-act { display:flex; gap:6px; flex-shrink:0; }
.share-existing-act .btn { width:auto; }        /* undo .menu button width:100% for inline row btns */
.share-revoke { color:var(--danger); }

/* Shared view: a feed of cards linking into the normal video detail. */
#view-shared .view-head h1 { font-family:var(--font-display); font-size:22px; margin:4px 2px 2px; }
.share-grid { display:grid; gap:12px; grid-template-columns:repeat(auto-fill,minmax(180px,1fr)); margin-bottom:8px; }
.share-card { display:flex; flex-direction:column; border:1px solid var(--hairline);
  border-radius:var(--r-l); overflow:hidden; background:var(--bg1); text-decoration:none;
  color:inherit; transition:border-color var(--t-fast), transform var(--t-fast); }
.share-card:hover { border-color:var(--accent-ring); transform:translateY(-2px); }
.share-card-thumb { position:relative; aspect-ratio:16/9; background:var(--bg3); }
.share-card-thumb img { width:100%; height:100%; object-fit:cover; }
.share-card-perms { position:absolute; left:6px; bottom:6px; font-size:10px; color:var(--text);
  background:rgba(6,8,12,.6); border-radius:999px; padding:2px 8px; backdrop-filter:blur(4px); }
.share-card-body { padding:9px 11px; }
.share-card-body b { font-size:13.5px; display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.share-card-owner { color:var(--text3); font-size:11px; }

/* Advanced-search scope chips (Everything / What was seen / What was said). */
.search-scope { display:flex; gap:8px; flex-wrap:wrap; margin:0 0 14px; }
.scope-chip { border:1px solid var(--hairline); background:var(--bg2); color:var(--text2);
  border-radius:999px; padding:6px 13px; font-size:12.5px; cursor:pointer;
  font-family:var(--font); transition:border-color var(--t-fast), color var(--t-fast), background var(--t-fast); }
.scope-chip:hover { color:var(--text); }
.scope-chip.on { border-color:var(--accent-ring); background:var(--accent-soft); color:var(--accent); font-weight:600; }

/* Shared-tab edit card thumbnail (no frame image — a play glyph). */
.share-card-thumb--edit { display:flex; align-items:center; justify-content:center; }
.share-card-thumb--edit .i { width:34px; height:34px; color:var(--text3); }

/* Share-notification badge on the mobile Shared tab (the rail reuses the
   Alerts #nav .navbadge layout; tabbar items are position:relative, so the
   badge floats over the icon's top-right corner). */
#tabbar .navbadge { position:absolute; top:2px; right:calc(50% - 24px); }

/* Live edit-collaboration presence pill. */
.edit-presence { display:inline-flex; align-items:center; gap:6px; font-size:12px;
  color:var(--text2); background:var(--accent-soft); border-radius:999px; padding:3px 10px; }
.edit-presence-dot { width:7px; height:7px; border-radius:50%; background:var(--ok);
  box-shadow:0 0 0 0 var(--ok); animation:presence-pulse 2s var(--ease-out) infinite; }
@keyframes presence-pulse { 0%{box-shadow:0 0 0 0 rgba(52,201,142,.5);} 70%{box-shadow:0 0 0 6px rgba(52,201,142,0);} 100%{box-shadow:0 0 0 0 rgba(52,201,142,0);} }

/* ============================================================================
   SHARED VISUAL PRIMITIVES (design-system additions) — the single definition of
   the custom player, unified progress meter, disclosure card, selection
   affordance, animated placeholder, visibility badge, context-menu separator,
   folder emoji, and the Video·Audio·Both scope control. Every redesigned surface
   (video / library / store / share / shared) reuses these.
   ========================================================================== */

/* ---- 1. custom player chrome ---------------------------------------------------- */
/* Aspect-fit variant of .player-stage: the stage becomes the clip's own shape
   (no pillar/letterbox bars), capped so a portrait clip stays snug. The blurred
   backdrop (.player-blur) is still painted underneath for one visual language. */
.player-stage--fit { aspect-ratio:var(--ar, 16/9); max-height:70dvh; margin-inline:auto; }
@media (max-width:1024px){ .player-stage--fit { max-height:64dvh; } }

.pl-chrome {
  position:absolute; inset:auto 0 0 0; z-index:3; padding:26px 12px 10px;
  display:flex; flex-direction:column; gap:7px;
  background:linear-gradient(to top, rgba(0,0,0,.62), rgba(0,0,0,.28) 55%, transparent);
  opacity:0; transform:translateY(6px); pointer-events:none;
  transition:opacity var(--t-med) var(--ease-out), transform var(--t-med) var(--ease-out);
}
@media (hover:hover){ .player-stage:hover .pl-chrome { opacity:1; transform:none; pointer-events:auto; } }
.player-stage.pl-show .pl-chrome,
.player-stage.pl-scrub .pl-chrome,
.player-stage.pl-paused .pl-chrome { opacity:1; transform:none; pointer-events:auto; }

.pl-big { position:absolute; inset:0; z-index:2; display:flex; align-items:center; justify-content:center;
  background:none; border:0; cursor:pointer; color:#fff; }
.pl-big .i { width:64px; height:64px; filter:drop-shadow(0 2px 14px rgba(0,0,0,.6));
  transition:transform var(--t-fast) var(--ease-spring), opacity var(--t-fast); }
.player-stage.pl-paused .pl-big .i { transform:scale(1); opacity:1; }
.player-stage:not(.pl-paused) .pl-big { pointer-events:none; }
.player-stage:not(.pl-paused) .pl-big .i { opacity:0; transform:scale(.6); }

.pl-scrubber { position:relative; height:26px; display:flex; align-items:center; cursor:pointer; touch-action:none; }
.pl-track { position:relative; width:100%; height:4px; border-radius:3px; background:rgba(255,255,255,.22);
  transition:height var(--t-fast) var(--ease-out); }
.player-stage.pl-scrub .pl-track,
.pl-scrubber:hover .pl-track { height:6px; }
.pl-buffered { position:absolute; inset:0 auto 0 0; height:100%; border-radius:3px; background:rgba(255,255,255,.30);
  transform-origin:left; transform:scaleX(0); }
.pl-fill { position:absolute; inset:0 auto 0 0; height:100%; border-radius:3px; background:var(--grad);
  transform-origin:left; transform:scaleX(0); }
.pl-handle { position:absolute; top:50%; left:0; width:14px; height:14px; border-radius:50%;
  background:#fff; box-shadow:0 1px 4px rgba(0,0,0,.5); transform:translate(-50%,-50%) scale(0);
  transition:transform var(--t-fast) var(--ease-spring); will-change:left; }
@media (hover:hover){ .pl-scrubber:hover .pl-handle { transform:translate(-50%,-50%) scale(1); } }
.player-stage.pl-scrub .pl-handle { transform:translate(-50%,-50%) scale(1.25); }

.pl-preview { position:absolute; bottom:22px; left:50%; transform:translateX(-50%); width:132px;
  border-radius:var(--r-s); overflow:hidden; background:#000; border:1px solid rgba(255,255,255,.25);
  box-shadow:var(--sh-2); opacity:0; transition:opacity var(--t-fast); pointer-events:none; }
.pl-preview.on { opacity:1; }
.pl-preview img { display:block; width:100%; aspect-ratio:16/9; object-fit:cover; }
.pl-preview b { display:block; text-align:center; font:600 10.5px var(--mono); color:#fff;
  padding:2px 0 3px; background:rgba(0,0,0,.7); }
@media (hover:none){ .pl-preview { display:none; } }

.pl-bar { display:flex; align-items:center; gap:4px; }
.pl-btn { display:inline-flex; align-items:center; justify-content:center; width:40px; height:40px;
  border:0; background:none; color:#fff; cursor:pointer; border-radius:8px; flex-shrink:0;
  transition:background var(--t-fast), transform var(--t-fast) var(--ease-out); }
.pl-btn .i { width:22px; height:22px; }
@media (hover:hover){ .pl-btn:hover { background:rgba(255,255,255,.16); } }
.pl-btn:active { transform:scale(.9); }
.pl-time { font:600 12px var(--mono); color:#fff; font-variant-numeric:tabular-nums; padding:0 6px; white-space:nowrap; }
.pl-time .sep { opacity:.6; margin:0 2px; }
.pl-spacer { flex:1; }

.pl-vol { display:flex; align-items:center; }
.pl-vol-slider { width:0; opacity:0; overflow:hidden; transition:width var(--t-med) var(--ease-out), opacity var(--t-fast); }
@media (hover:hover){ .pl-vol:hover .pl-vol-slider { width:74px; opacity:1; } }
.pl-vol-slider input[type=range] { width:70px; margin:0 6px 0 2px; accent-color:#fff; height:4px; background:transparent; }
@media (hover:none){ .pl-vol-slider { display:none; } }

@media (max-width:560px){ .pl-chrome { padding:22px 8px 8px; } .pl-btn { width:44px; height:44px; } }

/* ---- 2. unified progress meter -------------------------------------------------- */
.umeter { display:flex; flex-direction:column; gap:6px; }
.umeter-head { display:flex; align-items:baseline; justify-content:space-between; gap:10px; }
.umeter-label { font-size:12.5px; font-weight:600; color:var(--text2); }
.umeter-pct { font:600 12px var(--mono); color:var(--text2); font-variant-numeric:tabular-nums; }
.umeter-track { position:relative; height:8px; border-radius:999px; background:var(--bg3); overflow:hidden; }
.umeter-fill {
  position:absolute; inset:0 auto 0 0; height:100%; border-radius:999px;
  background:var(--grad); background-size:200% 100%;
  transform-origin:left; transform:scaleX(var(--p,0));
  transition:transform var(--t-slow) var(--ease-out), background-color var(--t-med);
}
.umeter.active .umeter-fill { animation:umeter-shimmer 1.5s linear infinite; }
@keyframes umeter-shimmer { to { background-position:-200% 0; } }
.umeter.done .umeter-fill { background:var(--ok); animation:umeter-pop .5s var(--ease-spring); }
@keyframes umeter-pop { 0%{transform:scaleX(1)} 40%{transform:scaleX(1.015)} 100%{transform:scaleX(1)} }
.umeter.done .umeter-label { color:var(--ok); }
.umeter-sub { display:flex; gap:10px; flex-wrap:wrap; font-size:11px; color:var(--text3); }
.umeter-sub .lag { color:var(--warn); }

/* ---- 3. disclosure / expandable card -------------------------------------------- */
.disc { background:var(--bg2); border:1px solid var(--hairline); border-radius:var(--r-m);
  overflow:hidden; transition:border-color var(--t-fast); margin-bottom:10px; }
@media (hover:hover){ .disc:hover { border-color:var(--hairline-strong); } }
.disc-head { display:flex; align-items:flex-start; gap:10px; padding:12px 14px; cursor:pointer; }
.disc-head-main { flex:1; min-width:0; }
.disc-title { font-size:13.5px; font-weight:650; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.disc-title small { color:var(--text3); font-weight:500; font-size:11.5px; }
.disc-body {
  margin:4px 0 0; font-size:13px; line-height:1.6; color:var(--text2);
  white-space:pre-wrap; overflow-wrap:anywhere;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.disc.open .disc-body { -webkit-line-clamp:unset; overflow:visible; }
.disc:not(.open) .disc-body { -webkit-mask-image:linear-gradient(to bottom, #000 60%, transparent); }
.disc-body ul { margin:4px 0 4px 18px; padding:0; white-space:normal; }
.disc-body li { margin:2px 0; }
.disc-chev { flex-shrink:0; margin-top:1px; color:var(--text3); transition:transform var(--t-fast) var(--ease-out); }
.disc.open .disc-chev { transform:rotate(90deg); }
.disc-foot { display:flex; gap:8px; padding:0 14px 12px; opacity:0; max-height:0; overflow:hidden;
  transition:opacity var(--t-med); }
.disc.open .disc-foot { opacity:1; max-height:none; }

/* ---- 4. selection affordance ---------------------------------------------------- */
.sel-dot {
  flex-shrink:0; width:22px; height:22px; border-radius:50%; cursor:pointer;
  border:1.5px solid var(--hairline-strong); background:var(--bg2);
  display:inline-flex; align-items:center; justify-content:center; color:transparent;
  opacity:0; transform:scale(.85);
  transition:opacity var(--t-fast), transform var(--t-fast) var(--ease-spring),
             background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.sel-dot .i { width:13px; height:13px; }
@media (hover:hover){ .selectable-row:hover .sel-dot { opacity:1; transform:scale(1); } }
.selecting .sel-dot,
.sel-dot.on { opacity:1; transform:scale(1); }
.sel-dot.on { background:var(--grad); border-color:transparent; color:var(--on-accent); }
.selectable-row.sel { background:var(--accent-soft); }
@media (hover:none){ .sel-dot { opacity:1; transform:scale(1); } }

.sel-bar {
  position:fixed; left:50%; transform:translateX(-50%); bottom:calc(18px + env(safe-area-inset-bottom));
  z-index:45; display:flex; align-items:center; gap:8px; padding:8px 10px 8px 16px;
  background:var(--bg3); border:1px solid var(--hairline-strong); border-radius:999px;
  box-shadow:var(--sh-3); max-width:calc(100vw - 24px); animation:menuin var(--t-med) var(--ease-spring);
}
.sel-bar b { font-size:13px; white-space:nowrap; margin-right:4px; font-variant-numeric:tabular-nums; }
.sel-bar .btn { flex-shrink:0; }
.sel-bar .sel-x { color:var(--text3); }
@media (max-width:1024px){ .sel-bar { bottom:calc(var(--tabbar-h) + 12px); } }
@media (max-width:520px){ .sel-bar .btn span { display:none; } }

/* ---- 5. animated placeholder (typewriter) --------------------------------------- */
.type-ph::placeholder { color:var(--text3); opacity:.72; }
.type-ph:focus::placeholder { opacity:.4; }

/* ---- 6. visibility badge -------------------------------------------------------- */
.vbadge {
  display:inline-flex; align-items:center; gap:5px; padding:2px 9px 2px 7px; border-radius:999px;
  font-size:11px; font-weight:650; letter-spacing:.01em; white-space:nowrap;
  border:1px solid transparent; line-height:1.6;
}
.vbadge .i { width:12px; height:12px; }
.vbadge--public   { color:var(--ok);     background:var(--ok-soft);     border-color:color-mix(in srgb, var(--ok) 30%, transparent); }
.vbadge--unlisted { color:var(--accent); background:var(--accent-soft); border-color:var(--accent-ring); }
.vbadge--shared   { color:var(--warn);   background:var(--warn-soft);   border-color:color-mix(in srgb, var(--warn) 30%, transparent); }
.vbadge--private  { color:var(--text3);  background:var(--bg3);         border-color:var(--hairline); }

/* ---- 7. context-menu separator -------------------------------------------------- */
.menu .menu-sep { height:1px; margin:5px 6px; background:var(--hairline); }

/* ---- 8. folder emoji ------------------------------------------------------------ */
.dir-emoji { display:block; font-size:30px; line-height:1; margin:2px auto 8px; }

/* ---- 9. Video · Audio · Both scope control -------------------------------------- */
.seg--scope { flex-shrink:0; }
.seg--scope button { padding:6px 12px; font-size:12.5px; display:inline-flex; align-items:center; gap:6px; }
.seg--scope .i { width:14px; height:14px; }
@media (max-width:420px){ .seg--scope button .lbl { display:none; } }

/* ============================================================================
   STORE — the two-pane "aisle" shop (store.js). A search over the whole catalog,
   a sticky category rail, and one aisle's checks at a time.
   ========================================================================== */
.store-search { position:relative; margin-bottom:18px; }
.store-search > .i { position:absolute; left:15px; top:50%; transform:translateY(-50%);
  width:18px; height:18px; color:var(--text3); pointer-events:none; }
.store-search input {
  width:100%; padding:12px 44px 12px 44px; font-size:14.5px; font-family:var(--font);
  color:var(--text); background:var(--bg2); border:1px solid var(--hairline-strong);
  border-radius:999px; transition:border-color var(--t-fast), background var(--t-fast); }
.store-search input:focus { outline:none; border-color:var(--accent-ring); background:var(--bg1); }
.store-search input::-webkit-search-decoration,
.store-search input::-webkit-search-cancel-button { -webkit-appearance:none; }
.store-search-x { position:absolute; right:8px; top:50%; transform:translateY(-50%);
  display:none; align-items:center; justify-content:center; width:32px; height:32px;
  border:0; background:none; color:var(--text3); cursor:pointer; border-radius:50%; }
.store-search.has-q .store-search-x { display:inline-flex; }
@media (hover:hover){ .store-search-x:hover { color:var(--text); background:var(--bg3); } }

.store-shell { display:grid; grid-template-columns:236px 1fr; gap:24px; align-items:start; }
.store-rail { position:sticky; top:16px; display:flex; flex-direction:column; gap:2px; }
.store-rail-sep { height:1px; background:var(--hairline); margin:8px 8px; }
.store-cat { display:flex; align-items:center; gap:11px; width:100%; text-align:left;
  border:0; background:none; color:var(--text2); padding:9px 12px; border-radius:10px;
  font:550 13.5px/1.25 var(--font); cursor:pointer;
  transition:background var(--t-fast), color var(--t-fast); }
.store-cat-emoji { flex-shrink:0; width:22px; text-align:center; font-size:16px; line-height:1;
  display:inline-flex; align-items:center; justify-content:center; }
.store-cat-emoji .i { width:16px; height:16px; }
.store-cat-name { flex:1; min-width:0; }
.store-cat-name small { display:block; font-size:11px; font-weight:500; opacity:.82; margin-top:1px; }
.store-cat-count { flex-shrink:0; font:600 11px var(--mono); color:var(--text3);
  background:var(--bg2); border-radius:999px; padding:1px 8px; font-variant-numeric:tabular-nums; }
@media (hover:hover){ .store-cat:hover { background:var(--bg2); color:var(--text); } }
.store-cat.on { background:var(--accent-soft); color:var(--text); }
.store-cat.on .store-cat-count { color:var(--accent); background:var(--bg1); }

/* Create hero — the one dramatic gradient moment on this surface */
.store-cat--create { color:var(--on-accent); background:var(--grad); box-shadow:var(--glow);
  padding:12px 13px; border-radius:var(--r-l); margin-bottom:2px; }
.store-cat--create .store-cat-emoji, .store-cat--create .store-cat-name { color:var(--on-accent); }
.store-cat--create .store-cat-name { font-weight:700; }
.store-cat--create .store-cat-name small { opacity:.9; }
.store-cat--create.on { box-shadow:var(--glow), 0 0 0 2px rgba(255,255,255,.55); }
@media (hover:hover){ .store-cat--create:hover { filter:brightness(1.06); background:var(--grad); } }

.store-main { min-width:0; }
.store-cat-head { margin-bottom:16px; }
.store-cat-head h2 { font-family:var(--font-display); font-size:18px; font-weight:700;
  display:flex; align-items:center; gap:9px; }
.store-cat-head p { color:var(--text2); font-size:13px; margin-top:4px; max-width:62ch; }
.store-results-head { display:flex; align-items:center; justify-content:space-between;
  gap:12px; margin-bottom:14px; }
.store-results-head b { font-size:14px; font-family:var(--font-display); }

.store-card-cat { font-size:10.5px; font-weight:650; letter-spacing:.05em; text-transform:uppercase;
  color:var(--text3); margin-bottom:-2px; }

.store-create-strip { display:flex; align-items:center; justify-content:space-between; gap:14px;
  margin-top:20px; padding:15px 18px; border:1px dashed var(--accent-ring);
  background:var(--accent-soft); border-radius:var(--r-l); cursor:pointer;
  transition:border-color var(--t-fast), transform var(--t-fast) var(--ease-out); }
.store-create-strip b { display:block; font-size:13.5px; }
.store-create-strip span:not(.btn) { font-size:12.5px; color:var(--text2); }
@media (hover:hover){ .store-create-strip:hover { transform:translateY(-1px); border-color:var(--accent); } }

/* create guide (State B) */
.store-guide { max-width:640px; }
.store-guide-hero { text-align:center; color:var(--on-accent); background:var(--grad);
  box-shadow:var(--glow); border-radius:var(--r-l); padding:30px 26px 28px; }
.store-guide-kicker { font-size:11px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; opacity:.85; }
.store-guide-hero h2 { font-family:var(--font-display); font-size:23px; font-weight:800;
  letter-spacing:-.3px; margin:8px 0 8px; }
.store-guide-hero p { font-size:13.5px; opacity:.92; max-width:44ch; margin:0 auto; }
.store-guide-demo { display:block; width:100%; max-width:420px; margin:20px auto 6px; text-align:center;
  padding:12px 16px; font-size:14px; font-family:var(--font); color:var(--text);
  background:var(--bg1); border:0; border-radius:999px; cursor:pointer; box-shadow:var(--sh-1); }
.store-guide-demo::placeholder { color:var(--text3); opacity:.8; }
.store-guide-hero .btn--xl { margin-top:14px; }
.store-guide-web { display:block; margin-top:16px; font-size:13px; font-weight:600; opacity:.95; }
.store-steps { list-style:none; margin:22px 0 0; padding:0; display:grid; gap:12px; }
.store-step { display:flex; gap:14px; align-items:flex-start; padding:15px 17px;
  background:var(--bg1); border:1px solid var(--hairline); border-radius:var(--r-m); }
.store-step-n { flex-shrink:0; width:28px; height:28px; border-radius:50%;
  background:var(--accent-soft); color:var(--accent); display:flex; align-items:center;
  justify-content:center; font:700 14px var(--font-display); }
.store-step b { font-size:13.5px; }
.store-step p { font-size:12.5px; color:var(--text2); margin-top:3px; line-height:1.5; }

/* mobile — rail becomes a horizontal chip scroller */
@media (max-width:1024px){
  .store-shell { grid-template-columns:1fr; gap:16px; }
  .store-rail { position:static; flex-direction:row; gap:8px; overflow-x:auto;
    scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch;
    margin:0 -16px; padding:2px 16px 10px; scrollbar-width:none; }
  .store-rail::-webkit-scrollbar { display:none; }
  .store-rail-sep { display:none; }
  .store-cat { flex:0 0 auto; scroll-snap-align:start; border:1px solid var(--hairline-strong);
    background:var(--bg2); border-radius:999px; padding:9px 15px; }
  .store-cat.on { border-color:var(--accent-ring); }
  .store-cat-count { display:none; }
  .store-cat-name small { display:none; }
  .store-cat--create { border:0; padding:9px 15px; }
  .store-guide-hero { padding:26px 18px; }
  .store-guide-hero h2 { font-size:20px; }
}

/* ============================================================================
   SHARED VIEW — centred, tabbed hub (shared.js): Public Videos / Shared with me /
   Unlisted. Reuses .tabs + .tab-underline (video page) and .share-card grid.
   ========================================================================== */
.shared-head { text-align:center; }
.shared-tabs { display:flex; justify-content:center; margin-bottom:16px;
  overflow-x:auto; scrollbar-width:none; }
.shared-tabs::-webkit-scrollbar { display:none; }
.tabs--center { justify-content:center; min-width:max-content; }

.tabs .tab-count { display:inline-flex; align-items:center; justify-content:center;
  min-width:18px; height:18px; padding:0 5px; margin-left:6px; border-radius:999px;
  font:600 11px var(--mono); background:var(--bg3); color:var(--text2);
  vertical-align:1px; font-variant-numeric:tabular-nums; }
.tabs button.on .tab-count { background:var(--accent-soft); color:var(--accent); }

.share-card-sub { display:flex; align-items:center; gap:8px; margin-top:5px; flex-wrap:wrap; }

.share-card-open { display:flex; flex-direction:column; text-decoration:none; color:inherit; }
.share-card-emoji { position:absolute; inset:0; display:flex; align-items:center;
  justify-content:center; font-size:40px; line-height:1; }
.share-card-manage { display:flex; align-items:center; gap:6px; padding:8px 10px;
  border-top:1px solid var(--hairline); }
.share-card-manage .share-card-spacer { flex:1; }
.share-card-manage .share-revoke { color:var(--danger); }
@media (max-width:520px){ .share-card-manage .btn span.lbl { display:none; } }

/* ============================================================================
   LIBRARY redesign (library.js) — prominent gradient search + scope, folder ROWS
   with emoji icons, selection dots + floating action bar, sort, drag guidance.
   Reuses shared primitives (.type-ph, .seg--scope, .sel-dot, .sel-bar).
   ========================================================================== */
.lib-hero { display:flex; align-items:stretch; gap:10px; margin-bottom:14px; }
.lib-hero .lib-search { flex:1; min-width:0; margin-bottom:0; }
.lib-hero .seg--scope { align-self:center; }

/* Coloured gradient border — the ONE vibrant accent of the surface. */
.lib-search {
  border:1.5px solid transparent; border-radius:var(--r-l);
  background:linear-gradient(var(--bg2),var(--bg2)) padding-box, var(--grad) border-box;
  box-shadow:var(--sh-1);
  transition:box-shadow var(--t-med) var(--ease-out);
}
.lib-search:focus-within { box-shadow:0 0 0 3px var(--accent-ring), var(--glow); }
.lib-search .i { color:var(--text3); }
.lib-sort-label { font-variant-numeric:tabular-nums; }

/* ---- folder ROWS (replace the old .dir-grid squares) ---------------------- */
.lib-folders { margin-bottom:4px; }
.drow {
  display:flex; align-items:center; gap:13px; padding:9px 8px; border-radius:10px;
  border:1px solid transparent; position:relative; cursor:pointer;
  transition:background var(--t-fast), border-color var(--t-fast), transform var(--t-fast) var(--ease-out);
}
@media (hover:hover){ .drow:hover { background:var(--bg2); border-color:var(--hairline); } }
.drow + .drow { margin-top:2px; }
.drow-emoji {
  flex-shrink:0; width:46px; height:46px; border-radius:11px; background:var(--bg2);
  border:1px solid var(--hairline); display:flex; align-items:center; justify-content:center;
  font-size:24px; line-height:1; cursor:pointer;
  transition:transform var(--t-fast) var(--ease-out), border-color var(--t-fast);
}
@media (hover:hover){ .drow-emoji:hover { border-color:var(--accent-ring); transform:scale(1.05); } }
.drow-name { flex:1; min-width:0; }
.drow-name b { font-size:13.5px; display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.drow-sub { color:var(--text3); font-size:12px; margin-top:2px; }
.drow-chev { color:var(--text3); flex-shrink:0; width:16px; height:16px; }
.drow-menu { color:var(--text3); }
.drow-menu.icon-btn { width:30px; height:30px; }

/* Drag guidance: while a drag is in flight, folder rows read as valid targets. */
.lib-dragging .drow { border-color:var(--accent-ring); }
.lib-dragging .drow .drow-emoji { transform:scale(1.06); }

/* One-time dashed hint teaching drag-to-file. */
.lib-hint {
  display:flex; align-items:center; gap:9px; margin:0 0 12px; padding:8px 12px;
  border:1px dashed var(--hairline-strong); border-radius:var(--r-m);
  color:var(--text3); font-size:12.5px; background:var(--bg1);
}
.lib-hint .i { width:16px; height:16px; color:var(--accent); flex-shrink:0; }
.lib-hint b { color:var(--text2); font-weight:600; }
.lib-hint .lib-hint-x { margin-left:auto; width:26px; height:26px; }

/* Selection dot at the video row's leading edge (system-spec .sel-dot). */
.vrow.selectable-row { padding-left:6px; }
.vrow .sel-dot { margin-right:-2px; }

@media (max-width:640px){
  .lib-hero { flex-direction:column; gap:8px; }
  .lib-hero .seg--scope { align-self:stretch; }
  .lib-hero .seg--scope button { flex:1; justify-content:center; }
  .drow-emoji { width:40px; height:40px; font-size:21px; }
  .drow .drag-handle { position:absolute; top:50%; right:2px; transform:translateY(-50%); width:28px; height:44px; }
  .drow-menu { display:none; }   /* long-press / right-click gives the menu on touch */
}

/* ============================================================================
   VIDEO DETAIL — redesign (video.js). Custom player, prominent search, Reports +
   Flagged as .disc disclosures, a tucked Transcript & timeline drawer with
   playhead-follow, Info & stats fold-away. The appended .vd-cols/.vd-stage-col
   win over the legacy rules above by source order.
   ========================================================================== */
.vd-head { align-items:flex-start; }
.vd-head .vd-back { flex:0 0 100%; margin-bottom:2px; }
.vd-titlebar { display:flex; align-items:center; gap:10px; flex:1; min-width:0; flex-wrap:wrap; }
.vd-titlebar .vd-actions { margin-left:auto; }
#vd-vbadge { flex-shrink:0; }

#vd-progress:empty { display:none; }
#vd-progress { margin:14px 0 6px; }

/* Two columns; the left player is sticky so the page keeps ONE (window) scrollbar. */
.vd-cols { display:grid; grid-template-columns:minmax(0,1.4fr) minmax(360px,1fr); gap:26px; align-items:start; margin-top:12px; }
.vd-cols > * { min-width:0; }
.vd-stage-col { position:sticky; top:20px; display:flex; flex-direction:column; gap:10px; }
.vd-stage-col .player-stage { box-shadow:var(--sh-2); }
.vd-under { display:flex; gap:8px; flex-wrap:wrap; }
.vd-stage-col .heat { height:8px; }

/* Search toolbar — prominent, at the top of the content column. */
.vd-search { display:flex; gap:10px; align-items:center; margin-bottom:14px; }
.vd-search-in { flex:1; min-width:0; display:flex; align-items:center; gap:8px; padding:0 10px;
  background:var(--bg2); border:1px solid var(--hairline-strong); border-radius:var(--r-m);
  transition:border-color var(--t-fast), box-shadow var(--t-fast); }
.vd-search-in:focus-within { border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); }
.vd-search-in > .i { color:var(--text3); flex-shrink:0; }
.vd-search-in input { flex:1; min-width:0; border:0; background:none; color:var(--text); padding:10px 0; font-size:14px; font-family:var(--font); }
.vd-search-in input:focus { outline:none; }
.vd-search-clear { border:0; background:none; color:var(--text3); cursor:pointer; display:inline-flex; padding:4px; border-radius:6px; flex-shrink:0; }
@media (hover:hover){ .vd-search-clear:hover { color:var(--text); background:var(--bg3); } }

/* Section header (Reports / Flagged). */
.vd-sec { margin-bottom:22px; }
.vd-sec-h { display:flex; align-items:center; gap:9px; margin:0 0 10px; }
.vd-sec-h h2 { font-size:13px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--text3); }
.vd-count { font:600 11px var(--mono); color:var(--text2); background:var(--bg3); border-radius:999px; padding:1px 8px; }
.vd-count.crit { color:var(--danger); background:var(--danger-soft); }
.vd-empty { color:var(--text3); font-size:13px; padding:10px 2px; }
.disc + .disc { margin-top:8px; }

/* Alert disclosure: a leading thumb (own seek target) + red left edge when critical. */
.disc--alert { animation:cardin var(--t-med) var(--ease-out) backwards; animation-delay:calc(min(var(--i,0),10)*22ms); }
.disc--alert.crit { border-left:3px solid var(--danger); }
.disc-athumb { position:relative; width:74px; height:44px; flex-shrink:0; border-radius:7px; overflow:hidden;
  background:#000; display:flex; align-items:center; justify-content:center; color:var(--text3); cursor:pointer; }
.disc-athumb img { width:100%; height:100%; object-fit:cover; }
.disc-athumb .i { width:20px; height:20px; }
@media (hover:hover){ .disc-athumb:hover { outline:2px solid var(--accent); outline-offset:-2px; } }

/* Search results. */
.vd-hit { display:flex; gap:11px; align-items:flex-start; padding:8px; border-radius:10px; cursor:pointer;
  transition:background var(--t-fast); }
@media (hover:hover){ .vd-hit:hover { background:var(--bg2); } }
.vd-hit-thumb { position:relative; width:74px; height:44px; flex-shrink:0; border-radius:7px; overflow:hidden; background:#000;
  display:flex; align-items:center; justify-content:center; color:var(--text3); }
.vd-hit-thumb img { width:100%; height:100%; object-fit:cover; }
.vd-hit-thumb .i { width:18px; height:18px; }
.vd-hit-b { flex:1; min-width:0; }
.vd-hit-top { display:flex; align-items:baseline; gap:8px; }
.vd-hit-kind { font-size:10px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--text3); }
.vd-hit-ts { font:600 11px var(--mono); color:var(--text3); margin-left:auto; }
.vd-hit p { font-size:13px; color:var(--text2); line-height:1.5; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.vd-hit mark { background:var(--accent-soft); color:var(--text); border-radius:3px; padding:0 1px; }
.vd-results-h { font-size:12.5px; color:var(--text3); margin:0 0 8px; }

/* Transcript & timeline drawer. */
.vd-drawer { border:1px solid var(--hairline); border-radius:var(--r-m); overflow:hidden; margin-bottom:12px; background:var(--bg2); }
.vd-drawer-h { display:flex; align-items:center; gap:9px; width:100%; text-align:left; border:0; background:none;
  color:var(--text); padding:12px 14px; cursor:pointer; font-family:var(--font); font-size:13.5px; }
.vd-drawer-h small { color:var(--text3); font-weight:400; font-size:11.5px; margin-left:auto; }
.vd-drawer-h .disc-chev { color:var(--text3); transition:transform var(--t-fast) var(--ease-out); flex-shrink:0; }
.vd-drawer.open .vd-drawer-h .disc-chev { transform:rotate(90deg); }
.vd-drawer-body { display:none; padding:0 12px 12px; }
.vd-drawer.open .vd-drawer-body { display:block; }
.vd-tt-switch { margin:2px 0 8px; }

/* Playhead-follow highlights (auto-scroll targets). */
.tl-row.now { background:var(--accent-soft); box-shadow:inset 0 0 0 2px var(--accent); }
.tr-line.now { background:var(--accent-soft); }
.tr-w { transition:color var(--t-fast); }
.tr-w.said { color:var(--text3); }
.tr-w.now { color:var(--text); font-weight:650; }

/* Info & stats — .disc whose foot is a block of stat chips. */
.vd-info .disc-foot { flex-direction:column; align-items:stretch; }
.vd-info .vd-checks { margin-bottom:0; }
.vd-stats { display:flex; flex-wrap:wrap; gap:7px; }
.vd-stat { display:inline-flex; align-items:center; gap:5px; font-size:11.5px; color:var(--text2);
  background:var(--bg3); border:1px solid var(--hairline); border-radius:6px; padding:3px 9px; white-space:nowrap; }
.vd-stat .i { width:13px; height:13px; color:var(--text3); }
.vd-stat--ok { color:var(--ok); border-color:color-mix(in srgb, var(--ok) 30%, transparent); }
.vd-stat--ok .i { color:var(--ok); }

/* Move menu — a proper labelled field, not autofilled-looking text. */
.vd-move { padding:10px 12px 12px; min-width:250px; }
.vd-move label { display:block; font-size:11.5px; font-weight:650; color:var(--text2); margin-bottom:6px; }
.vd-move-field { display:flex; align-items:center; gap:8px; background:var(--bg2); border:1px solid var(--hairline-strong);
  border-radius:var(--r-s); padding:0 10px; }
.vd-move-field:focus-within { border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); }
.vd-move-field .i { color:var(--text3); flex-shrink:0; }
.vd-move-field input { flex:1; min-width:0; border:0; background:none; color:var(--text); padding:9px 0; font-size:13.5px; font-family:var(--font); }
.vd-move-field input:focus { outline:none; }

@media (max-width:1024px){
  .vd-cols { grid-template-columns:minmax(0,1fr); gap:16px; }
  .vd-stage-col { position:static; }
}
@media (max-width:560px){
  .vd-search { flex-wrap:wrap; }
  .vd-search-in { order:1; flex-basis:100%; }
  .vd-search .seg--scope { order:2; }
  .disc-athumb, .vd-hit-thumb { width:64px; height:38px; }
}

/* Add wizard: the "what should we do with this footage?" analyse/transcribe group. */
.footage-do { border-top:1px solid var(--hairline); padding-top:12px; }
.footage-do .tag { margin-bottom:2px; }
.footage-do label span small { color:var(--text3); font-weight:400; }
