@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Inter:wght@400;500;600;700&display=swap');
:root{
  --bg:#070b16; --bg2:#0b1024; --panel:#0f1630; --panel2:#15203f; --line:#243156;
  --fg:#eaf0ff; --mut:#8c9cc6; --dim:#586691;
  --brand:#7c5cff; --brand2:#22d3ee; --branddim:#191e46;
  --blue:#3b82f6; --green:#22c55e; --purple:#a855f7; --pink:#f43f7e; --yellow:#eab308;
  --radius:14px; --shadow:0 12px 50px rgba(4,8,30,.6);
  --glow:0 0 24px rgba(124,92,255,.45);
  --font:'Inter','Segoe UI',system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;
  --font-head:'Space Grotesk','Inter',var(--font);

  /* ============ DESIGN SYSTEM v1 — one source of truth for every screen ============ */
  /* A committed dark product (like Linear/Vercel dashboards). Tokens below are the ONLY
     values pages should reach for; raw hex/px in templates is a smell. */

  /* line/surface variants for real depth instead of one flat panel */
  --line-soft:#1b2540; --line-strong:#2f3f6b;
  --panel-hi:#111a38;                 /* slightly lifted card on hover/active */
  --overlay:rgba(6,10,24,.66);        /* modal/scrim backdrop */

  /* spacing scale (4px base) — --sp-3 is the default gutter */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px;
  --sp-7:48px; --sp-8:64px; --sp-9:96px;

  /* type scale (~1.25 minor-third) */
  --fs-xs:.75rem; --fs-sm:.875rem; --fs-base:1rem; --fs-lg:1.125rem;
  --fs-xl:1.375rem; --fs-2xl:1.75rem; --fs-3xl:2.25rem; --fs-4xl:3rem; --fs-5xl:3.75rem;

  /* radius scale */
  --r-sm:8px; --r-md:12px; --r-lg:16px; --r-xl:22px; --r-full:999px;

  /* elevation — layered, soft, dark-tuned */
  --e-1:0 1px 2px rgba(2,5,20,.4);
  --e-2:0 4px 14px rgba(2,5,20,.45);
  --e-3:0 12px 34px rgba(2,5,20,.55);
  --e-4:0 24px 64px rgba(2,5,20,.65);

  /* motion — snappy, purposeful; honoured only when the user allows animation */
  --dur-1:120ms; --dur-2:200ms; --dur-3:340ms;
  --ease:cubic-bezier(.2,.7,.2,1); --ease-out:cubic-bezier(.16,1,.3,1);

  /* semantic surfaces + text (success / warning / danger / info) */
  --ok:#22c55e; --ok-fg:#86efac; --ok-bg:#0e2419; --ok-line:#1f4d33;
  --warn:#eab308; --warn-fg:#fcd34d; --warn-bg:#2a2109; --warn-line:#5a4a1a;
  --bad:#f43f5e; --bad-fg:#ff8a9c; --bad-bg:#2a0f16; --bad-line:#52262a;
  --info:#3b82f6; --info-fg:#93c5fd; --info-bg:#0c1a33; --info-line:#1e3a66;

  --ring:0 0 0 3px rgba(124,92,255,.5);   /* keyboard focus ring */
  --grad-brand:linear-gradient(135deg,var(--brand),var(--brand2));

  /* ═══════════ ART DIRECTION v2 — the ThreadVid visual language ═══════════
     What separates an expensive interface from a template is not colour, it's LIGHT.
     Four ideas, used consistently, are the whole identity:
       1. EDGE LIGHT   — a 1px highlight on the top edge of every surface, as if lit from above.
       2. GLASS        — real backdrop blur + saturation, never a flat panel.
       3. AMBIENT      — coloured light pooling behind content, not gradients painted on it.
       4. GRAIN        — a faint film grain that kills the "flat vector" look.
     Motion uses spring easing; nothing linear, nothing bouncy-for-fun. */

  /* surfaces: translucent, so ambient light reads THROUGH them */
  --glass:rgba(19,26,52,.62);
  --glass-hi:rgba(26,35,68,.74);
  --glass-line:rgba(255,255,255,.08);      /* the light-catching edge */
  --glass-line-hi:rgba(255,255,255,.14);
  --edge-top:inset 0 1px 0 rgba(255,255,255,.07);   /* THE signature detail */
  --edge-top-hi:inset 0 1px 0 rgba(255,255,255,.13);
  --blur:blur(22px) saturate(150%);
  --blur-lite:blur(12px) saturate(130%);

  /* glows — colour that bleeds, the way real light does */
  --glow-brand:0 0 0 1px rgba(124,92,255,.28), 0 8px 32px -6px rgba(124,92,255,.5);
  --glow-cyan:0 0 0 1px rgba(34,211,238,.26), 0 8px 30px -6px rgba(34,211,238,.42);
  --glow-soft:0 0 60px -12px rgba(124,92,255,.55);
  --glow-ok:0 0 0 1px rgba(34,197,94,.3), 0 8px 26px -8px rgba(34,197,94,.45);

  /* elevation, rebuilt: two shadows + an inner edge = depth, not a grey box */
  --lift-1:0 1px 2px rgba(2,4,16,.5), var(--edge-top);
  --lift-2:0 6px 18px -4px rgba(2,4,16,.6), 0 2px 6px rgba(2,4,16,.4), var(--edge-top);
  --lift-3:0 18px 44px -10px rgba(2,4,16,.72), 0 6px 14px rgba(2,4,16,.45), var(--edge-top-hi);
  --lift-4:0 36px 90px -16px rgba(2,4,16,.8), 0 10px 24px rgba(2,4,16,.5), var(--edge-top-hi);

  /* spring easing — the difference between "animated" and "designed" */
  --spring:cubic-bezier(.34,1.56,.64,1);
  --smooth:cubic-bezier(.4,0,.2,1);
  --swift:cubic-bezier(.16,1,.3,1);

  /* display type: oversized + tight, the way editorial does it */
  --tracking-tight:-.035em;
  --tracking-tighter:-.05em;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}

/* ---------- accessibility foundations ---------- */
/* Visible focus ONLY for keyboard users (not mouse clicks) — the mark of a considered product. */
:focus{outline:none}
:focus-visible{outline:none;box-shadow:var(--ring);border-radius:var(--r-sm)}
a:focus-visible,button:focus-visible,.btn:focus-visible,.chip:focus-visible{border-radius:var(--r-md)}
/* Respect users who ask for less motion: kill transitions/animations, keep everything usable. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* AMBIENT LIGHT: pools of colour sitting BEHIND the UI, plus a vignette that focuses the eye.
   Fixed attachment so the light stays put while content scrolls through it — the room is lit,
   the furniture moves. */
body{font-family:var(--font);color:var(--fg);line-height:1.55;-webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  background:
    radial-gradient(1200px 700px at 12% -8%, rgba(124,92,255,.20), transparent 60%),
    radial-gradient(1000px 620px at 100% 2%, rgba(34,211,238,.13), transparent 58%),
    radial-gradient(900px 700px at 50% 110%, rgba(168,85,247,.10), transparent 60%),
    radial-gradient(140% 120% at 50% 0%, transparent 40%, rgba(2,4,14,.6) 100%),  /* vignette */
    var(--bg);
  background-attachment:fixed}

/* FILM GRAIN: an SVG noise field at 0 cost, ~3% opacity. Invisible on its own; without it the
   dark surfaces band and read as flat vector. This is the cheapest "expensive" trick there is. */
body::before{content:"";position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:overlay}
body > *{position:relative;z-index:1}

h1,h2,h3,.brand,.amt{font-family:var(--font-head);letter-spacing:var(--tracking-tight);
  text-wrap:balance}
h1{letter-spacing:var(--tracking-tighter)}
p{text-wrap:pretty}
a{color:inherit;text-decoration:none}
.muted{color:var(--mut)} .dim{color:var(--dim)} .small{font-size:.85rem}
.center{text-align:center}

/* ---------- buttons ---------- */
/* ---------- buttons: physical objects, not rectangles ----------
   Lit top edge + real depth. The primary button carries a moving sheen so the most important
   action on any screen is quietly alive. */
.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  border:1px solid var(--glass-line);background:var(--glass-hi);color:var(--fg);
  padding:.62rem 1.15rem;border-radius:var(--r-md);font:inherit;font-weight:600;cursor:pointer;
  white-space:nowrap;box-shadow:var(--lift-1);overflow:hidden;
  transition:transform var(--dur-1) var(--spring), box-shadow var(--dur-2) var(--swift),
             background var(--dur-2) var(--smooth), border-color var(--dur-2) var(--smooth)}
.btn:hover{transform:translateY(-2px);box-shadow:var(--lift-3);border-color:var(--glass-line-hi)}
.btn:active{transform:translateY(0) scale(.985);box-shadow:var(--lift-1);transition-duration:80ms}

.btn-brand{background:var(--grad-brand);color:#fff;border-color:transparent;
  box-shadow:var(--glow-brand), var(--edge-top-hi)}
.btn-brand:hover{box-shadow:0 0 0 1px rgba(124,92,255,.4), 0 14px 40px -8px rgba(124,92,255,.65),
  var(--edge-top-hi)}
/* sheen: a slow specular highlight sweeping the primary CTA on hover */
.btn-brand::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 30%,rgba(255,255,255,.28) 48%,transparent 62%);
  transform:translateX(-120%);transition:transform var(--dur-3) var(--swift)}
.btn-brand:hover::before{transform:translateX(120%)}
.btn-ghost{background:transparent;border-color:var(--line)}
.btn-green{background:var(--green);color:#04210f}
.btn-blue{background:var(--blue);color:#fff}
.btn-danger{background:transparent;border-color:#52262a;color:#ff8a8a}
.btn-lg{padding:.85rem 1.6rem;font-size:1.05rem}
.btn-sm{padding:.35rem .7rem;font-size:.82rem;border-radius:8px}
.btn[disabled]{opacity:.5;cursor:not-allowed;transform:none}

/* ---------- chips / badges ----------
   `.badge` is the LEGACY status pill; `.tag` (design system v1) is the real primitive. Rather
   than churn 9 templates, .badge is now an ALIAS that renders exactly like .tag and maps its
   status variants onto the semantic tokens — one visual language everywhere, no template risk.
   New code should still use .tag; see UI_INVENTORY.md §17. */
.badge{display:inline-flex;align-items:center;gap:.3rem;padding:.15rem .5rem;border-radius:var(--r-sm);
  font-size:var(--fs-xs);font-weight:600;border:1px solid var(--line);color:var(--mut);background:var(--bg2)}
.badge.draft{color:var(--mut)}
.badge.scheduled{color:#cdbcff;border-color:rgba(124,92,255,.4);background:rgba(124,92,255,.14)}
.badge.posted{color:var(--ok-fg);border-color:var(--ok-line);background:var(--ok-bg)}
.badge.error,.badge.failed{color:var(--bad-fg);border-color:var(--bad-line);background:var(--bad-bg)}
.chip{display:inline-flex;align-items:center;gap:.3rem;padding:.18rem .55rem;border-radius:8px;
  font-size:.72rem;font-weight:600;border:1px solid var(--line);background:var(--bg2);color:var(--mut);
  cursor:pointer;transition:.12s}
.chip.on{background:var(--green);color:#04210f;border-color:transparent}
.chip:hover{filter:brightness(1.1)}
/* admin-only preview marker: this feature is visible to you because you're an admin */
.chip-preview{cursor:default;text-transform:uppercase;letter-spacing:.04em;font-size:.62rem;
  background:linear-gradient(135deg,rgba(124,92,255,.22),rgba(34,211,238,.18));
  border-color:rgba(124,92,255,.45);color:#cdbcff;margin-left:.45rem;vertical-align:middle}
.chip-preview:hover{filter:none}

/* ---------- surfaces: GLASS, not panels ----------
   Every card is a translucent pane of glass with a lit top edge, floating over the ambient
   light. The ::after is a hairline gradient on the top border — the single detail that most
   separates "expensive" from "template". */
/* PERFORMANCE: backdrop-filter is per-element and expensive; a page with 60+ cards (Media) was
   paying for 60 blurs. Plain cards use a translucent fill only — over the ambient light that
   reads as glass at a fraction of the cost. Real blur is reserved for surfaces that FLOAT over
   content and must be legible against anything: nav, modals, toasts, sidebar (.glass-blur). */
.card{position:relative;background:var(--glass);border:1px solid var(--glass-line);
  border-radius:var(--radius);padding:1.3rem;box-shadow:var(--lift-2)}
.glass-blur{backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur)}
.card::after{content:"";position:absolute;inset:0 0 auto 0;height:1px;border-radius:inherit;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.22),transparent);
  opacity:.7;pointer-events:none}

/* interactive card: rises toward the light, edge brightens, brand glow blooms underneath */
.card-hover{cursor:pointer;
  transition:transform var(--dur-2) var(--swift), box-shadow var(--dur-2) var(--swift),
             border-color var(--dur-2) var(--smooth), background var(--dur-2) var(--smooth)}
.card-hover:hover{transform:translateY(-4px);background:var(--glass-hi);
  border-color:rgba(124,92,255,.34);
  box-shadow:var(--lift-4), 0 0 44px -14px rgba(124,92,255,.5)}
.card-hover:active{transform:translateY(-1px);transition-duration:var(--dur-1)}
.grid{display:grid;gap:1.1rem}
.flex{display:flex;gap:1rem;align-items:center}
.between{display:flex;justify-content:space-between;align-items:center;gap:1rem}
.wrap{flex-wrap:wrap}

/* ---------- top brand ---------- */
.brand{display:flex;align-items:center;gap:.6rem;font-weight:800;font-size:1.15rem}
.brand .logo{width:34px;height:34px}

/* ================= AUTH ================= */
.auth-wrap{min-height:100vh;display:grid;place-items:center;padding:2rem;
  background:radial-gradient(900px 500px at 20% -10%,rgba(124,92,255,.18),transparent),
             radial-gradient(700px 500px at 100% 0%,rgba(59,130,246,.14),transparent),var(--bg)}
.auth-card{width:100%;max-width:430px;background:var(--panel);border:1px solid var(--line);
  border-radius:18px;padding:2.2rem;box-shadow:var(--shadow)}
.auth-card h1{font-size:1.6rem;margin:.4rem 0 .2rem}
.field{margin:.9rem 0}
.field label{display:block;font-size:.85rem;color:var(--mut);margin-bottom:.35rem;font-weight:600}
.input,textarea,select{width:100%;background:var(--bg2);border:1px solid var(--line);color:var(--fg);
  padding:.7rem .85rem;border-radius:var(--r-md);font:inherit;
  transition:border-color var(--dur-1) var(--ease),box-shadow var(--dur-1) var(--ease)}
.input::placeholder,textarea::placeholder{color:var(--dim)}
.input:hover:not(:focus),textarea:hover:not(:focus),select:hover:not(:focus){border-color:var(--line-strong)}
.input:focus,textarea:focus,select:focus{outline:none;border-color:var(--brand);box-shadow:var(--ring)}
textarea{min-height:90px;resize:vertical;font-family:ui-monospace,Consolas,monospace;font-size:.85rem}
.flash{padding:.7rem 1rem;border-radius:10px;margin:.6rem 0;font-size:.9rem}
.flash.error{background:#2a1416;color:#ffb4b4;border:1px solid #52262a}
.flash.ok{background:#0e2419;color:#86efac;border:1px solid #1f4d33}

/* ================= APP SHELL ================= */
.shell{display:grid;grid-template-columns:252px 1fr;min-height:100vh}
/* the rail is glass too — ambient light shows through it, so it reads as part of the room */
.side{background:linear-gradient(180deg,rgba(11,16,36,.72),rgba(7,11,22,.86));
  border-right:1px solid var(--glass-line);padding:1.1rem;position:sticky;top:0;
  height:100vh;display:flex;flex-direction:column;gap:.3rem;
  backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur)}
.side .brand{padding:.4rem .5rem 1rem}
.nav a{display:flex;align-items:center;gap:.7rem;padding:.55rem .7rem;border-radius:var(--r-md);color:var(--mut);
  font-weight:600;font-size:.92rem;transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease);position:relative}
.nav a:hover{background:var(--panel);color:var(--fg)}
.nav a.active{background:linear-gradient(135deg,rgba(124,92,255,.22),rgba(124,92,255,.06));color:#fff}
/* left accent bar on the active item — clearer "you are here" than a full border */
.nav a.active::before{content:"";position:absolute;left:-.55rem;top:50%;transform:translateY(-50%);
  width:3px;height:1.15rem;border-radius:0 3px 3px 0;background:var(--grad-brand)}
.nav .ico{width:20px;text-align:center;font-size:1.02rem}
/* grouped sections: a quiet label separates Create / Library / Account */
.nav-group{font-size:.66rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--dim);padding:.9rem .7rem .3rem}
.nav-group:first-child{padding-top:.3rem}
.nav a .nav-badge{margin-left:auto;font-size:.66rem;font-weight:700;padding:.05rem .4rem;border-radius:var(--r-full);
  background:var(--panel2);color:var(--mut)}
.nav a.active .nav-badge{background:rgba(124,92,255,.3);color:#fff}
.side .grow{flex:1}
.userbox{border-top:1px solid var(--line);padding-top:.9rem;font-size:.85rem}
.userbox .avatar{width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,var(--brand),var(--purple));
  display:grid;place-items:center;font-weight:800;color:#fff}

.main{padding:1.8rem 2.2rem;max-width:1200px;width:100%}
/* legacy header classes now inherit the design-system header treatment so every not-yet-rewritten
   page (storyboard, characters, media, opportunities, admin…) is visually consistent for free */
.page-head{margin-bottom:var(--sp-5)}
.page-head h1{font-size:var(--fs-2xl);line-height:1.1;letter-spacing:-.01em}
.page-head .muted,.page-head p{font-size:var(--fs-sm);margin-top:var(--sp-1)}
.topbar{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--sp-4);
  flex-wrap:wrap;margin-bottom:var(--sp-5)}
.topbar h1{font-size:var(--fs-2xl);line-height:1.1;letter-spacing:-.01em}

/* stat cards */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1.1rem}
.stat{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:1.2rem;position:relative;overflow:hidden;box-shadow:var(--e-1);
  transition:transform var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease)}
.stat:hover{transform:translateY(-2px);box-shadow:var(--e-2);border-color:var(--line-strong)}
.stat .n{font-size:2rem;font-weight:800;line-height:1}
.stat .l{color:var(--mut);font-size:.85rem;margin-top:.3rem}
.stat .ic{position:absolute;right:1rem;top:1rem;font-size:1.4rem;opacity:.5}
.stat.brand{border-color:#2c2a66;background:linear-gradient(135deg,rgba(124,92,255,.14),var(--panel))}

/* video grid */
.vgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:1.1rem}
.vcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;transition:.15s}
.vcard:hover{transform:translateY(-3px);border-color:#34465a}
.vthumb{aspect-ratio:9/16;display:grid;place-items:center;position:relative;color:#fff}
.vthumb .play{width:46px;height:46px;border-radius:50%;background:rgba(0,0,0,.45);display:grid;place-items:center;font-size:1.1rem;backdrop-filter:blur(2px)}
.vthumb .dur{position:absolute;bottom:.5rem;right:.5rem;background:rgba(0,0,0,.6);padding:.1rem .45rem;border-radius:6px;font-size:.72rem}
.vcard .body{padding:.8rem}
.vcard .t{font-size:.84rem;font-weight:600;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:2.4em}

/* tables */
table{width:100%;border-collapse:collapse}
th,td{text-align:left;padding:.7rem .6rem;border-bottom:1px solid var(--line);font-size:.9rem}
th{color:var(--mut);font-weight:600;font-size:.8rem;text-transform:uppercase;letter-spacing:.04em}

/* progress */
.bar{height:9px;background:var(--bg2);border-radius:999px;overflow:hidden;border:1px solid var(--line)}
.bar > i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--brand),var(--brand2));transition:width .4s}
.job{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:1rem;margin-bottom:.8rem}

/* ================= LANDING ================= */
/* ═══════════════ LANDING — ART DIRECTION v2 ═══════════════
   Built around one idea: the page is a dark room, and ThreadVid is the light source in it.
   Aurora drifts behind everything, a cursor-tracked spotlight follows the visitor, and the
   product floats above the page on real shadow. */

/* AURORA: slow drifting colour fields behind everything.
   PERFORMANCE: deliberately NO filter:blur(). A radial-gradient is already soft, so the blur
   bought almost nothing visually while forcing the compositor to rasterise ~3 full-screen
   surfaces every frame — it hung the renderer outright. Only `transform` is animated (GPU
   compositor, no repaint), the layers are promoted with will-change, and the whole thing is
   disabled for reduced-motion. Same look, a fraction of the cost. */
.aurora{position:fixed;inset:-25% -10%;z-index:0;pointer-events:none;opacity:.6;
  contain:strict}
.aurora i{position:absolute;display:block;border-radius:50%;will-change:transform;
  transform:translate3d(0,0,0)}
.aurora i:nth-child(1){width:60vw;height:60vw;left:-10vw;top:-12vw;
  background:radial-gradient(circle closest-side,rgba(124,92,255,.42),transparent 100%);
  animation:drift1 30s var(--smooth) infinite alternate}
.aurora i:nth-child(2){width:52vw;height:52vw;right:-10vw;top:0;
  background:radial-gradient(circle closest-side,rgba(34,211,238,.30),transparent 100%);
  animation:drift2 38s var(--smooth) infinite alternate}
.aurora i:nth-child(3){width:48vw;height:48vw;left:26vw;top:36vw;
  background:radial-gradient(circle closest-side,rgba(244,63,126,.20),transparent 100%);
  animation:drift3 46s var(--smooth) infinite alternate}
@keyframes drift1{to{transform:translate3d(7vw,5vw,0) scale(1.12)}}
@keyframes drift2{to{transform:translate3d(-6vw,8vw,0) scale(1.15)}}
@keyframes drift3{to{transform:translate3d(4vw,-7vw,0) scale(.92)}}
@media (prefers-reduced-motion:reduce){ .aurora i{animation:none} .spotlight{display:none} }

/* SPOTLIGHT: a soft light that follows the cursor. --mx/--my set by JS. */
.spotlight{position:fixed;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(520px circle at var(--mx,50%) var(--my,0%),
    rgba(124,92,255,.13),transparent 65%);
  transition:background .18s var(--smooth)}

/* NAV: glass that only materialises once you scroll (.stuck added by JS) */
.lnav{position:sticky;top:0;z-index:20;display:flex;justify-content:space-between;align-items:center;
  padding:1rem 2.2rem;background:transparent;border-bottom:1px solid transparent;
  transition:background var(--dur-3) var(--smooth),border-color var(--dur-3) var(--smooth),
             backdrop-filter var(--dur-3) var(--smooth)}
.lnav.stuck{background:rgba(8,12,26,.6);border-bottom-color:var(--glass-line);
  backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur)}
.lnav .links{display:flex;gap:1.6rem;align-items:center}
.lnav .links a{color:var(--mut);font-weight:600;position:relative;transition:color var(--dur-1) var(--smooth)}
.lnav .links a:not(.btn):hover{color:var(--fg)}
/* underline that grows from the centre — small, but it's the kind of detail people feel */
.lnav .links a:not(.btn)::after{content:"";position:absolute;left:50%;right:50%;bottom:-6px;height:1.5px;
  border-radius:2px;background:var(--grad-brand);transition:left var(--dur-2) var(--swift),right var(--dur-2) var(--swift)}
.lnav .links a:not(.btn):hover::after{left:0;right:0}

.hero{padding:7.5rem 2rem 3rem;text-align:center;position:relative;z-index:1}
/* the eyebrow pill: glass + a live pulsing dot */
.hero .eyebrow{display:inline-flex;gap:.55rem;align-items:center;padding:.4rem 1rem;
  border:1px solid var(--glass-line);border-radius:var(--r-full);color:var(--brand2);font-weight:600;
  font-size:.8rem;background:var(--glass);backdrop-filter:var(--blur-lite);margin-bottom:1.8rem;
  box-shadow:var(--lift-1);animation:rise .7s var(--swift) both}
.hero .eyebrow .dot{width:6px;height:6px;border-radius:50%;background:var(--brand2);
  box-shadow:0 0 0 0 rgba(34,211,238,.7);animation:pulse 2.4s infinite}
@keyframes pulse{70%{box-shadow:0 0 0 8px rgba(34,211,238,0)}100%{box-shadow:0 0 0 0 rgba(34,211,238,0)}}

/* MASSIVE type. clamp keeps it sane on phones; the gradient makes it read as lit. */
.hero h1{font-size:clamp(2.6rem,7.4vw,5.4rem);line-height:.98;font-weight:700;max-width:16ch;
  margin:0 auto 1.4rem;letter-spacing:var(--tracking-tighter);
  background:linear-gradient(180deg,#fff 32%,#a9b6de 120%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:rise .8s .06s var(--swift) both}
.hero h1 .g{background:linear-gradient(115deg,var(--brand) 10%,var(--brand2) 55%,var(--purple) 95%);
  background-size:220% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;
  animation:shift 9s ease-in-out infinite}
@keyframes shift{50%{background-position:100% 0}}
.hero p{font-size:1.18rem;color:var(--mut);max-width:60ch;margin:0 auto 2.2rem;line-height:1.65;
  animation:rise .8s .12s var(--swift) both}
.hero .cta{display:flex;gap:.9rem;justify-content:center;flex-wrap:wrap;
  animation:rise .8s .18s var(--swift) both}
@keyframes rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}

/* THE FLOATING PRODUCT: a phone-shaped pane held above the page on real shadow, tilted in 3D */
.hero-stage{perspective:1600px;padding:3rem 2rem 5rem;position:relative;z-index:1;
  animation:rise 1s .26s var(--swift) both}
.device{width:min(300px,72vw);margin:0 auto;aspect-ratio:9/16;border-radius:26px;position:relative;
  border:1px solid var(--glass-line-hi);overflow:hidden;background:#05070f;
  box-shadow:var(--lift-4), 0 0 120px -20px rgba(124,92,255,.6);
  transform:rotateX(9deg) rotateY(-8deg);
  transition:transform .9s var(--swift)}
.hero-stage:hover .device{transform:rotateX(2deg) rotateY(0deg) translateY(-8px)}
.device video,.device img{width:100%;height:100%;object-fit:cover;display:block}
.device::after{content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:linear-gradient(160deg,rgba(255,255,255,.14),transparent 42%)}
/* the pane's reflection on the "floor" */
.device-reflection{width:min(300px,72vw);height:70px;margin:14px auto 0;border-radius:50%;
  background:radial-gradient(ellipse,rgba(124,92,255,.32),transparent 70%);filter:blur(18px)}

/* THE OUTPUT MOCK — a real demo of what ThreadVid makes, drawn in CSS so it can never 404.
   Scenes cross-fade on a Ken Burns drift while a caption pops word-by-word, which is precisely
   what the renderer produces. */
.mock{position:absolute;inset:0;display:grid;place-items:center;overflow:hidden}
.mock .scene{position:absolute;inset:0;opacity:0;transform:scale(1.06);
  animation:sceneCycle 12s infinite}
.mock .scene:nth-child(1){animation-delay:0s;
  background:linear-gradient(160deg,#2b1c5e,#0a1230 60%),radial-gradient(circle at 30% 30%,rgba(124,92,255,.5),transparent 60%)}
.mock .scene:nth-child(2){animation-delay:4s;
  background:linear-gradient(160deg,#0c3a4a,#08122c 60%),radial-gradient(circle at 70% 40%,rgba(34,211,238,.45),transparent 60%)}
.mock .scene:nth-child(3){animation-delay:8s;
  background:linear-gradient(160deg,#4a1436,#0d0a26 60%),radial-gradient(circle at 50% 70%,rgba(244,63,126,.4),transparent 60%)}
@keyframes sceneCycle{
  0%{opacity:0;transform:scale(1.12)}
  6%,30%{opacity:1}
  8%,30%{transform:scale(1.0)}
  36%,100%{opacity:0}
}
/* karaoke caption: each word pops in, exactly like the rendered output */
.mock .cap{position:absolute;bottom:16%;left:0;right:0;text-align:center;padding:0 12px;
  font-family:var(--font-head);font-weight:700;font-size:clamp(.9rem,3.4vw,1.15rem);
  line-height:1.25;letter-spacing:-.02em;text-shadow:0 2px 10px rgba(0,0,0,.85)}
.mock .cap span{display:inline-block;margin:0 .12em;opacity:.28;transform:translateY(2px);
  animation:word 12s infinite}
.mock .cap span:nth-child(1){animation-delay:.2s}  .mock .cap span:nth-child(2){animation-delay:.5s}
.mock .cap span:nth-child(3){animation-delay:.8s}  .mock .cap span:nth-child(4){animation-delay:1.1s}
.mock .cap span:nth-child(5){animation-delay:1.4s} .mock .cap span:nth-child(6){animation-delay:1.7s}
@keyframes word{
  0%,1%{opacity:.28;transform:translateY(2px) scale(1);color:#fff}
  3%,12%{opacity:1;transform:translateY(0) scale(1.06);color:#fff;text-shadow:0 0 18px rgba(124,92,255,.9)}
  16%,100%{opacity:.28;transform:translateY(0) scale(1);text-shadow:0 2px 10px rgba(0,0,0,.85)}
}
/* progress bar at the top of the "video" */
.mock .prog{position:absolute;top:0;left:0;height:2px;background:var(--grad-brand);
  box-shadow:0 0 10px rgba(124,92,255,.9);animation:prog 12s linear infinite}
@keyframes prog{from{width:0}to{width:100%}}

/* AI PIPELINE: the product's actual stages, lighting up in sequence */
.pipe{display:flex;align-items:center;justify-content:center;gap:.35rem;flex-wrap:wrap;
  margin-top:2.6rem;animation:rise .9s .34s var(--swift) both}
.pipe-step{display:inline-flex;align-items:center;gap:.45rem;padding:.42rem .85rem;border-radius:var(--r-full);
  border:1px solid var(--glass-line);background:var(--glass);font-size:.78rem;font-weight:600;
  color:var(--dim);backdrop-filter:var(--blur-lite);
  animation:light 7s infinite}
.pipe-step:nth-child(1){animation-delay:0s}   .pipe-step:nth-child(3){animation-delay:.6s}
.pipe-step:nth-child(5){animation-delay:1.2s} .pipe-step:nth-child(7){animation-delay:1.8s}
.pipe-step:nth-child(9){animation-delay:2.4s} .pipe-step:nth-child(11){animation-delay:3s}
@keyframes light{
  0%,72%,100%{color:var(--dim);border-color:var(--glass-line);box-shadow:none}
  8%,18%{color:#fff;border-color:rgba(124,92,255,.6);box-shadow:var(--glow-brand)}
}
.pipe-arrow{color:var(--dim);opacity:.4;font-size:.7rem}

.section{padding:5.5rem 2rem;max-width:1140px;margin:0 auto;position:relative;z-index:1}
.section h2{font-size:clamp(1.9rem,3.6vw,2.9rem);text-align:center;margin-bottom:.7rem;
  letter-spacing:var(--tracking-tighter);
  background:linear-gradient(180deg,#fff 30%,#aab6da 130%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.section .sub{text-align:center;color:var(--mut);max-width:58ch;margin:0 auto 3.2rem;font-size:1.05rem}
/* reveal-on-scroll (JS adds .in) */
.reveal{opacity:0;transform:translateY(26px);transition:opacity .7s var(--swift),transform .7s var(--swift)}
.reveal.in{opacity:1;transform:none}
.features{display:grid;grid-template-columns:repeat(3,1fr);gap:1.2rem}
/* feature = glass tile with a light that follows the pointer across it */
.feature{position:relative;background:var(--glass);border:1px solid var(--glass-line);
  border-radius:var(--r-lg);padding:1.7rem;overflow:hidden;box-shadow:var(--lift-2);
  transition:transform var(--dur-2) var(--swift),border-color var(--dur-2) var(--smooth),
             box-shadow var(--dur-2) var(--swift)}
.feature::before{content:"";position:absolute;inset:0;opacity:0;pointer-events:none;
  background:radial-gradient(320px circle at var(--fx,50%) var(--fy,50%),rgba(124,92,255,.16),transparent 70%);
  transition:opacity var(--dur-2) var(--smooth)}
.feature:hover{transform:translateY(-5px);border-color:rgba(124,92,255,.3);box-shadow:var(--lift-4)}
.feature:hover::before{opacity:1}
.feature .fi{width:48px;height:48px;border-radius:14px;display:grid;place-items:center;font-size:1.4rem;
  margin-bottom:1.1rem;background:linear-gradient(150deg,rgba(124,92,255,.3),rgba(34,211,238,.1));
  border:1px solid rgba(124,92,255,.34);box-shadow:var(--edge-top-hi),0 8px 22px -8px rgba(124,92,255,.6)}
.feature h3{font-size:1.15rem;margin-bottom:.4rem}
.feature p{color:var(--mut);font-size:.95rem}
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:1.2rem;counter-reset:s}
.step{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:1.4rem;position:relative}
.step::before{counter-increment:s;content:counter(s);position:absolute;top:-14px;left:1.2rem;width:30px;height:30px;
  border-radius:50%;background:linear-gradient(135deg,var(--brand),var(--brand2));display:grid;place-items:center;font-weight:800;color:#fff}
.pricing{display:grid;grid-template-columns:repeat(3,1fr);gap:1.4rem}
.price{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:2rem;position:relative}
.price.pop{border-color:var(--brand);box-shadow:0 0 0 1px var(--brand),0 20px 50px rgba(124,92,255,.18)}
.price .tag{position:absolute;top:-13px;left:50%;transform:translateX(-50%);background:linear-gradient(135deg,var(--brand),var(--brand2));
  color:#fff;font-size:.72rem;font-weight:800;padding:.25rem .8rem;border-radius:999px}
.price h3{font-size:1.2rem;color:var(--mut)}
.price .amt{font-size:2.6rem;font-weight:800;margin:.3rem 0}
.price .amt span{font-size:1rem;color:var(--mut);font-weight:600}
.price ul{list-style:none;margin:1.2rem 0;display:grid;gap:.6rem}
.price li{display:flex;gap:.6rem;color:var(--fg);font-size:.92rem}
.price li::before{content:"✓";color:var(--green);font-weight:800}
.lfoot{border-top:1px solid var(--line);padding:2.5rem;text-align:center;color:var(--dim)}

/* platform icon chips */
.chip.icon{padding:.28rem .42rem;background:var(--bg2)}
.chip.icon.on{background:rgba(34,197,94,.18);box-shadow:0 0 0 1.5px var(--green)}
.pi{width:18px;height:18px;display:block;border-radius:4px}

/* video modal */
.modal{position:fixed;inset:0;z-index:60;display:none;place-items:center;padding:2rem}
.modal-bg{position:absolute;inset:0;background:rgba(0,0,0,.72);backdrop-filter:blur(3px)}
.modal-card{position:relative;background:var(--panel);border:1px solid var(--line);border-radius:16px;
  padding:1.2rem;width:min(420px,92vw);max-height:90vh;overflow-y:auto;box-shadow:var(--shadow)}
/* mobile: shrink the modal gutter so a tall (9:16) video card stays centered, not clipped */
@media (max-width:600px){ .modal{padding:.75rem} .modal-card{width:96vw;max-height:94vh} }

/* Live render pipeline — stage chips light up as the worker moves through a render (render_tracker.js) */
.pipe-visual{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;margin:.2rem 0}
.pstep{display:flex;align-items:center;gap:.4rem;padding:.4rem .7rem;border:1px solid var(--line);
  border-radius:999px;font-size:.78rem;color:var(--mut);opacity:.5;transition:all .3s}
.pstep .pic{font-size:1rem;line-height:1}
.pstep.done{opacity:1;color:var(--fg);border-color:#2f7d4f}
.pstep.active{opacity:1;color:#fff;border-color:var(--brand);animation:ppulse 1.3s ease-in-out infinite}
.parrow{color:var(--mut);opacity:.4;font-size:.75rem}
@keyframes ppulse{0%,100%{box-shadow:0 0 0 2px rgba(124,92,255,.25)}50%{box-shadow:0 0 0 5px rgba(124,92,255,.45)}}
@media (prefers-reduced-motion:reduce){ .pstep.active{animation:none} }

/* pricing toggle */
/* LEGACY `.toggle` — aliased onto the .segmented primitive so the two either/or controls in the
   product look identical. New code uses .segmented (UI_INVENTORY §17). */
.toggle{display:inline-flex;background:var(--bg2);border:1px solid var(--line);
  border-radius:var(--r-md);padding:3px;gap:2px}
.toggle button{border:0;background:none;color:var(--mut);font:inherit;font-weight:600;
  padding:.4rem .9rem;border-radius:calc(var(--r-md) - 3px);cursor:pointer;
  transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease)}
.toggle button:hover:not(.active){color:var(--fg)}
.toggle button.active{background:var(--panel2);color:var(--fg);box-shadow:var(--e-1)}
.save-badge{color:var(--green);font-weight:700;font-size:.8rem}
.was{color:var(--dim);text-decoration:line-through;font-size:1.1rem;font-weight:600}
.promo-note{color:var(--brand2);font-size:.8rem;font-weight:700}

/* media */
.mlist{display:grid;gap:.6rem}
.mrow{display:flex;align-items:center;gap:.9rem;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:.7rem .9rem}
.mrow .mname{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;font-size:.92rem}
.mrow audio{height:34px}
.mrow video{width:80px;border-radius:8px;background:#000}
.uploadbox{border:2px dashed var(--line);border-radius:12px;padding:1.2rem;text-align:center;color:var(--mut)}

/* mobile app shell: the sidebar becomes a hamburger-triggered full-screen menu */
.mobtop,.side-close{display:none}
@media(max-width:900px){
  html,body{overflow-x:hidden}
  .shell{grid-template-columns:1fr}
  .mobtop{display:flex;align-items:center;justify-content:space-between;
    padding:.6rem 1rem;position:sticky;top:0;z-index:40;
    background:var(--bg2);border-bottom:1px solid var(--line)}
  .mobtop-btn{background:transparent;border:1px solid var(--line);color:var(--fg);
    font-size:1.25rem;line-height:1;padding:.25rem .6rem;border-radius:9px;cursor:pointer}
  .side{display:none}
  .side.open{display:flex;position:fixed;inset:0;z-index:50;height:100vh;
    flex-direction:column;overflow-y:auto;padding:1.2rem}
  .side-close{display:block;position:absolute;top:1rem;right:1rem;background:transparent;
    border:none;color:var(--fg);font-size:1.5rem;line-height:1;cursor:pointer}
  body.nav-open{overflow:hidden}
  .nav a{font-size:1.05rem;padding:.8rem .9rem}
  .main{padding:1.1rem .9rem;min-height:auto;min-width:0;max-width:100%;overflow-x:hidden}
  .shell{min-width:0}
  .main .grid{grid-template-columns:1fr!important}      /* collapse every page grid */
  .stats,.features,.steps,.pricing{grid-template-columns:1fr 1fr}
  .topbar{flex-wrap:wrap;gap:.6rem}
  input[type=file]{max-width:100%}
  /* wide admin users table -> one card per user (label : value rows) */
  table.admin-users thead{display:none}
  table.admin-users, table.admin-users tbody, table.admin-users tr, table.admin-users td{display:block;width:100%}
  table.admin-users tr{background:var(--panel);border:1px solid var(--line);border-radius:12px;
    margin-bottom:.8rem;padding:.3rem .2rem}
  table.admin-users td{border:none;display:flex;justify-content:space-between;align-items:center;
    gap:1rem;padding:.45rem .8rem;font-size:.9rem}
  table.admin-users td::before{content:attr(data-label);color:var(--mut);font-size:.74rem;
    font-weight:700;text-transform:uppercase;letter-spacing:.04em;flex:none}
}
@media(max-width:600px){.stats,.features,.steps,.pricing{grid-template-columns:1fr}}

/* --- register captcha / robot check --- */
.robotbox{border:1px solid var(--line);border-radius:12px;padding:.85rem 1rem;margin:.5rem 0 .2rem;
  background:var(--bg2);display:flex;flex-direction:column;gap:.7rem}
.robot-check{display:flex;align-items:center;gap:.6rem;cursor:pointer;font-weight:600}
.robot-check input{width:20px;height:20px;accent-color:var(--brand)}
.captcha-q{display:flex;align-items:center;gap:.7rem;color:var(--mut);font-weight:600}

/* --- legal pages --- */
.legal h3{margin:1.7rem 0 .4rem;font-size:1.12rem}
.legal p{margin-bottom:.5rem}
.legal a{text-decoration:underline}

/* --- futuristic polish --- */
.auth-card{box-shadow:var(--shadow),0 0 70px rgba(124,92,255,.14)}
.auth-card::before{content:"";position:absolute;inset:0;border-radius:18px;padding:1px;pointer-events:none;
  background:linear-gradient(135deg,rgba(124,92,255,.6),rgba(34,211,238,.35),transparent 60%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude}
.auth-card{position:relative}
.btn-brand{box-shadow:0 8px 26px rgba(124,92,255,.4)}
.price.pop{box-shadow:0 0 0 1px var(--brand),0 24px 60px rgba(124,92,255,.22)}
.hero .eyebrow{box-shadow:0 0 30px rgba(124,92,255,.2)}

/* --- form validation styling --- */
.input.bad{border-color:#ff5b6e;box-shadow:0 0 0 3px rgba(255,91,110,.18)}
.ferr{color:#ff8a92;font-size:.82rem;margin-top:.35rem;font-weight:600}
.req-x{color:#ff5b6e;font-weight:900;margin-left:.25rem}
.pwlist{list-style:none;padding:0;margin:.6rem 0 0;display:grid;gap:.25rem}
.pwlist li{font-size:.82rem;color:var(--mut);display:flex;align-items:center;gap:.5rem}
.pwlist li::before{content:"○";display:inline-block;color:var(--dim);font-weight:900;width:1em}
.pwlist li.ok{color:#86efac}
.pwlist li.ok::before{content:"✓";color:var(--green)}

/* --- ensure landing "Start free" button has white text everywhere --- */
.lnav .btn-brand,.lnav .btn-brand:visited{color:#fff !important}

/* --- media library: two equal-height columns, internal scrollbars --- */
.media-grid{grid-template-columns:1fr 1fr;align-items:stretch}
.media-card{display:flex;flex-direction:column;height:calc(100vh - 200px);min-height:480px}
.media-card .mlist{margin-top:.8rem}
.scroll-pane{flex:1;overflow-y:auto;padding-right:.4rem;display:grid;gap:.6rem;align-content:start}
.scroll-pane::-webkit-scrollbar{width:10px}
.scroll-pane::-webkit-scrollbar-track{background:transparent}
.scroll-pane::-webkit-scrollbar-thumb{background:var(--line);border-radius:8px}
.scroll-pane::-webkit-scrollbar-thumb:hover{background:var(--panel2)}
@media(max-width:900px){.media-grid{grid-template-columns:1fr}.media-card{height:auto;max-height:60vh}}

/* --- profile avatar + sidebar avatar image --- */
.userbox .avatar{overflow:hidden}
.userbox .avatar img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%}
.userlink:hover .avatar{filter:brightness(1.1)}
.avatar-big{width:140px;height:140px;border-radius:50%;display:grid;place-items:center;color:#fff;
  font-size:3rem;font-weight:800;margin:.2rem auto 0;overflow:hidden;box-shadow:0 0 30px rgba(124,92,255,.35)}
.avatar-big img{width:100%;height:100%;object-fit:cover}

/* --- app footer (logged-in shell) --- */
.appfoot{margin-top:3rem;padding:1.4rem 0 .5rem;border-top:1px solid var(--line);
  color:var(--mut);font-size:.85rem}
.appfoot a{color:var(--mut)} .appfoot a:hover{color:var(--fg)}

/* --- show/hide password eye --- */
.pw-wrap{position:relative}
.pw-wrap input{padding-right:52px}
.pw-eye{position:absolute;right:6px;top:50%;transform:translateY(-50%);
  background:rgba(124,92,255,.18);border:1px solid var(--line);border-radius:8px;
  cursor:pointer;font-size:1.15rem;opacity:1;line-height:1;width:36px;height:32px;
  display:flex;align-items:center;justify-content:center;padding:0}
.pw-eye:hover{background:rgba(124,92,255,.35);border-color:var(--brand2)}

/* --- library: left list + right detail panel --- */
.libsplit{display:grid;grid-template-columns:minmax(0,1fr) 600px;gap:1.2rem;align-items:start}
.liblist{display:grid;gap:.7rem}
.libcard{display:flex;gap:.9rem;background:var(--panel);border:1px solid var(--line);
  border-radius:12px;padding:.7rem;cursor:pointer;transition:.12s}
.libcard:hover{border-color:#34465a;transform:translateY(-1px)}
.libcard.sel{border-color:var(--brand);box-shadow:0 0 0 1px var(--brand)}
.libthumb{position:relative;width:74px;min-width:74px;height:120px;border-radius:8px;color:#fff}
.libthumb .dur{position:absolute;bottom:4px;right:4px;background:rgba(0,0,0,.6);
  padding:0 .35rem;border-radius:5px;font-size:.68rem}
.partspill{position:absolute;top:4px;left:4px;background:var(--brand);color:#fff;
  font-size:.62rem;font-weight:700;padding:.1rem .35rem;border-radius:5px}
.libmeta{min-width:0;display:flex;flex-direction:column;gap:.25rem;padding-top:.2rem}
.libmeta .t{font-weight:600;font-size:.92rem;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden}
.libdetail{position:sticky;top:1rem}
.pager{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:1rem;align-items:center}
@media(max-width:900px){.libsplit{grid-template-columns:1fr}.libdetail{position:static}}

/* --- sticky footer: sits at the bottom of the viewport when content is short,
       and after the content (scroll to see it) when long --- */
.main{display:flex;flex-direction:column;min-height:100vh}
.main > .appfoot{margin-top:auto}
.vsample{background:var(--panel2);border:1px solid var(--line);color:var(--fg);border-radius:8px;
  cursor:pointer;padding:.55rem .7rem;font-size:.9rem;line-height:1}
.vsample:hover{filter:brightness(1.15)}

/* --- compact spacing so Studio/Credentials/Billing fit without scrolling --- */
.main{padding:1.25rem 1.9rem}
.page-head{margin-bottom:.9rem}
.page-head h1{font-size:1.5rem}
.field{margin:.5rem 0}
.field label{margin-bottom:.22rem;font-size:.82rem}
.input,textarea,select{padding:.5rem .72rem}
.card{padding:1rem}
.grid{gap:.9rem}
/* billing plan cards a touch tighter */
.price{padding:1.3rem}
.price .amt{font-size:2rem}
.price ul{margin:.8rem 0;gap:.4rem}
.price li{font-size:.86rem}

/* clickable platform-logo icons that reveal a per-platform caption */
.capicon{width:26px;height:26px;cursor:pointer;border-radius:7px;padding:3px;
  background:#0f1530;border:1px solid var(--line);opacity:.55;
  transition:opacity .15s,box-shadow .15s,transform .1s}
.capicon:hover{opacity:1;transform:translateY(-1px)}
.capicon.on{opacity:1;border-color:var(--brand);box-shadow:0 0 0 2px rgba(124,92,255,.35)}

/* risky-content warning (Library) */
.badge.risky{background:#3a2410;color:#f0b86a;border:1px solid #6b4a1a}
.riskwarn{background:#3a2410;border:1px solid #6b4a1a;color:#f0b86a;border-radius:10px;
  padding:.7rem .85rem;font-size:.85rem;line-height:1.45;margin-bottom:.9rem}

/* register agreement checkboxes */
.agree{display:flex;align-items:flex-start;gap:.5rem;margin:.4rem 0;cursor:pointer}
.agree input{margin-top:.2rem}
.agree.bad-row span{color:#ff8585}

/* Library detail: two columns side by side so it fits without scrolling */
.libcols{display:grid;grid-template-columns:1fr 1fr;gap:1.1rem;align-items:start}
@media(max-width:1080px){.libcols{grid-template-columns:1fr}}

/* Studio: tighter so the whole form fits without scrolling */
#studiogrid .card{padding:1rem 1.1rem}
#studiogrid h3{margin-bottom:.5rem}
#studiogrid .field{margin:.45rem 0}
#studiogrid .grid{gap:.6rem}
#studiogrid label{margin-bottom:.1rem}

/* ================= responsive / mobile ================= */
/* Billing has 4 plan cards: 4 across on desktop, 2 on tablet, 1 on phone.
   (A dedicated class so it isn't overridden by an inline style.) */
.pricing-4{grid-template-columns:repeat(4,1fr)}
@media(max-width:1100px){.pricing-4{grid-template-columns:1fr 1fr}}
@media(max-width:600px){.pricing-4{grid-template-columns:1fr}}

@media(max-width:760px){
  .main{padding:1rem .9rem}
  .page-head h1{font-size:1.35rem}
  /* rows that pair text with buttons stack instead of overflowing */
  .between{flex-wrap:wrap}
  .card.between > .flex{width:100%}
  .card.between .btn{flex:1 1 auto;justify-content:center}
  .card.between form{width:100%}
  .card.between form .btn{width:100%}
  /* plan cards a touch tighter on phones */
  .price{padding:1.1rem}
  .price .amt{font-size:1.9rem}
  /* full-width primary actions are easier to tap */
  .btn-lg{width:100%;justify-content:center}
}

/* landing page on phones: nav fits, sections breathe, nothing scrolls sideways */
@media(max-width:760px){
  html,body{overflow-x:hidden}
  .lnav{padding:.7rem 1rem;gap:.5rem}
  .lnav .brand{font-size:1.05rem}
  .lnav .links{gap:.7rem}
  .lnav .links a[href^="#"]{display:none}   /* hide section anchors (Features/How it works/Pricing) */
  .hero{padding:3.4rem 1.1rem 2.4rem}
  .hero p{font-size:1.05rem}
  .hero .cta .btn-lg{width:100%}
  .section{padding:3rem 1.1rem}
  .section h2{font-size:1.7rem}
  .section .sub{margin-bottom:2rem}
  .lfoot{padding:2rem 1.1rem}
}

/* app + admin pages on phones: stack every 2-column layout, make wide tables scroll */
@media(max-width:820px){
  .grid, .grid2{grid-template-columns:1fr !important}
  .grid > *, .grid2 > *, .card{min-width:0}            /* let grid cards shrink so tables can scroll */
  .stats{grid-template-columns:1fr 1fr !important}
  /* wide tables (admin users/map/workers/debug) scroll sideways instead of breaking layout */
  .card table{display:block;overflow-x:auto;white-space:nowrap;-webkit-overflow-scrolling:touch;max-width:100%}
  .card{padding:1rem}
  .page-head{flex-wrap:wrap;gap:.4rem}
  /* admin sub-nav becomes a horizontal scroll strip so all tabs stay reachable */
  .flex.wrap{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:.3rem;
    max-width:100%;width:100%}
  .flex.wrap .btn{flex:0 0 auto}
  /* studio form fields stack */
  #studiogrid .grid{grid-template-columns:1fr !important}
}
@media(max-width:480px){
  .stats{grid-template-columns:1fr !important}
}

/* ================================================================================
   DESIGN SYSTEM v1 — reusable primitives (skeletons, toasts, empty/error states,
   modal, segmented control, tooltip, tags, tables). Class-based so any page opts in.
   ================================================================================ */

/* ---- section header used at the top of every workspace page ---- */
/* Page headers: oversized display type, generous air. The h1 is the loudest thing on screen. */
.ds-head{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--sp-4);
  margin-bottom:var(--sp-6);flex-wrap:wrap;padding-top:var(--sp-2)}
.ds-head h1{font-size:clamp(1.9rem, 3.4vw, 2.65rem);line-height:1.02;
  letter-spacing:var(--tracking-tighter);
  /* headline reads as lit, not painted: a soft vertical falloff */
  background:linear-gradient(180deg,#fff 20%,#b9c4e6 130%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.ds-head .sub{color:var(--mut);font-size:var(--fs-base);margin-top:var(--sp-2);max-width:62ch}
.ds-eyebrow{display:inline-flex;align-items:center;gap:.4rem;font-size:.68rem;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--brand2);margin-bottom:var(--sp-2)}
/* the small brand tick that precedes every eyebrow — a recognisable ThreadVid signature */
.ds-eyebrow::before{content:"";width:14px;height:2px;border-radius:2px;background:var(--grad-brand);
  box-shadow:0 0 10px rgba(124,92,255,.8)}

/* ---- tags (non-interactive labels, distinct from clickable .chip) ---- */
.tag{display:inline-flex;align-items:center;gap:.3rem;padding:.15rem .5rem;border-radius:var(--r-sm);
  font-size:var(--fs-xs);font-weight:600;border:1px solid var(--line);color:var(--mut);background:var(--bg2)}
.tag-ok{color:var(--ok-fg);border-color:var(--ok-line);background:var(--ok-bg)}
.tag-warn{color:var(--warn-fg);border-color:var(--warn-line);background:var(--warn-bg)}
.tag-bad{color:var(--bad-fg);border-color:var(--bad-line);background:var(--bad-bg)}
.tag-info{color:var(--info-fg);border-color:var(--info-line);background:var(--info-bg)}
.tag-brand{color:#cdbcff;border-color:rgba(124,92,255,.4);background:rgba(124,92,255,.14)}

/* ---- skeleton loaders: replace "Loading…" text with shape-of-content shimmer ---- */
.skl{position:relative;overflow:hidden;background:var(--panel2);border-radius:var(--r-sm)}
.skl::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.06),transparent);
  animation:skl 1.25s infinite}
.skl-line{height:.72rem;margin:.4rem 0} .skl-line.w-40{width:40%} .skl-line.w-60{width:60%}
.skl-line.w-80{width:80%} .skl-title{height:1.15rem;width:55%;margin-bottom:.7rem}
.skl-card{height:150px;border-radius:var(--r-md)} .skl-chip{height:1.5rem;width:5rem;border-radius:var(--r-full)}
@keyframes skl{100%{transform:translateX(100%)}}

/* ---- note / callout: an inline advisory banner ----
   Replaces an amber box that was hand-rolled with raw hex in 3 templates. Use .note + a
   semantic variant; never re-invent this with inline colours. */
.note{display:flex;gap:.6rem;align-items:flex-start;padding:.75rem .95rem;border-radius:var(--r-md);
  border:1px solid var(--line);background:var(--bg2);color:var(--mut);font-size:var(--fs-sm)}
.note .ni{flex:0 0 auto;line-height:1.4}
.note b{color:var(--fg)}
.note-warn{border-color:var(--warn-line);background:var(--warn-bg);color:var(--warn-fg)}
.note-warn b{color:var(--warn-fg)}
.note-info{border-color:var(--info-line);background:var(--info-bg);color:var(--info-fg)}
.note-ok{border-color:var(--ok-line);background:var(--ok-bg);color:var(--ok-fg)}
.note-bad{border-color:var(--bad-line);background:var(--bad-bg);color:var(--bad-fg)}

/* ---- empty state: a friendly, on-brand "nothing here yet" with a next action ---- */
.empty{text-align:center;padding:var(--sp-8) var(--sp-5);border:1px dashed var(--line-strong);
  border-radius:var(--r-lg);background:linear-gradient(180deg,rgba(124,92,255,.04),transparent)}
.empty .ic{font-size:2.4rem;line-height:1;margin-bottom:var(--sp-4);display:inline-block;
  filter:grayscale(.1) drop-shadow(0 6px 16px rgba(124,92,255,.35))}
.empty h3{font-size:var(--fs-lg);margin-bottom:var(--sp-2)}
.empty p{color:var(--mut);max-width:44ch;margin:0 auto var(--sp-5);font-size:var(--fs-sm)}

/* ---- toasts / notifications ---- */
#toasts{position:fixed;z-index:120;bottom:var(--sp-5);right:var(--sp-5);display:flex;
  flex-direction:column;gap:var(--sp-3);max-width:min(92vw,380px);pointer-events:none}
.toast{pointer-events:auto;display:flex;gap:var(--sp-3);align-items:flex-start;padding:var(--sp-4);
  border-radius:var(--r-md);background:var(--panel-hi);border:1px solid var(--line-strong);
  box-shadow:var(--e-3);animation:toast-in var(--dur-3) var(--ease-out)}
.toast.leaving{animation:toast-out var(--dur-2) var(--ease) forwards}
.toast .tc{flex:1;min-width:0} .toast .tt{font-weight:700;font-size:var(--fs-sm)}
.toast .tm{color:var(--mut);font-size:var(--fs-xs);margin-top:2px;overflow-wrap:anywhere}
.toast .tx{background:none;border:0;color:var(--dim);cursor:pointer;font-size:1rem;line-height:1;padding:2px}
.toast .tx:hover{color:var(--fg)}
.toast .ti{font-size:1.1rem;line-height:1.2}
.toast.ok{border-left:3px solid var(--ok)} .toast.ok .ti{color:var(--ok-fg)}
.toast.warn{border-left:3px solid var(--warn)} .toast.warn .ti{color:var(--warn-fg)}
.toast.bad{border-left:3px solid var(--bad)} .toast.bad .ti{color:var(--bad-fg)}
.toast.info{border-left:3px solid var(--info)} .toast.info .ti{color:var(--info-fg)}
@keyframes toast-in{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}
@keyframes toast-out{to{opacity:0;transform:translateX(16px)}}

/* ---- modal / dialog ---- */
.modal-scrim{position:fixed;inset:0;z-index:110;background:var(--overlay);backdrop-filter:blur(3px);
  display:grid;place-items:center;padding:var(--sp-4);animation:fade var(--dur-2) var(--ease)}
/* Scoped to `.modal-scrim>` so it beats the OLDER `.modal{display:none}` (used by library.html's
   toggle-modal). Without the scope + explicit display, the confirm dialog inherited display:none:
   the scrim/blur showed but the dialog box never rendered, so a Delete confirm looked like "screen
   went blurry and nothing popped up". */
.modal-scrim>.modal{display:block;position:relative;inset:auto;width:100%;max-width:520px;background:var(--panel);border:1px solid var(--line-strong);
  border-radius:var(--r-lg);box-shadow:var(--e-4);padding:var(--sp-6);
  animation:modal-in var(--dur-3) var(--ease-out)}
.modal h3{font-size:var(--fs-xl);margin-bottom:var(--sp-2)}
.modal .modal-foot{display:flex;justify-content:flex-end;gap:var(--sp-3);margin-top:var(--sp-6)}
@keyframes fade{from{opacity:0}to{opacity:1}}
@keyframes modal-in{from{opacity:0;transform:translateY(12px) scale(.97)}to{opacity:1;transform:none}}

/* ---- segmented control (a11y radio group look; upgrades the ad-hoc .toggle) ---- */
.segmented{display:inline-flex;background:var(--bg2);border:1px solid var(--line);border-radius:var(--r-md);
  padding:3px;gap:2px}
.segmented button,.segmented .seg{border:0;background:none;color:var(--mut);font:inherit;font-weight:600;
  padding:.4rem .9rem;border-radius:calc(var(--r-md) - 3px);cursor:pointer;display:inline-flex;
  align-items:center;gap:.35rem;
  transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease)}
.segmented button[aria-selected="true"],.segmented button.active,.segmented .seg.active{
  background:var(--panel2);color:var(--fg);box-shadow:var(--e-1)}
.segmented .seg:hover:not(.active){color:var(--fg)}
/* A tab that isn't built yet. Deliberately NOT the `disabled` attribute: browsers don't dispatch
   hover or focus to disabled controls, so the tooltip explaining WHY the tab is inert could never
   appear and it just sat there silent when clicked. aria-disabled keeps it hoverable, focusable
   and able to explain itself, while ui.js stops it actually activating. */
.segmented .seg[aria-disabled="true"]{color:var(--dim);cursor:not-allowed}
.segmented .seg[aria-disabled="true"]:hover{color:var(--mut)}
.seg .soon{font-size:.6rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  padding:.08rem .3rem;margin-left:.35rem;border-radius:999px;color:var(--brand);
  background:color-mix(in srgb,var(--brand) 16%,transparent);
  border:1px solid color-mix(in srgb,var(--brand) 30%,transparent);vertical-align:middle}

/* ---- tooltip (pure CSS, keyboard-focusable trigger) ---- */
.tip{position:relative;display:inline-flex;cursor:help}
.tip[data-tip]::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;
  transform:translateX(-50%) translateY(4px);background:var(--panel-hi);color:var(--fg);
  border:1px solid var(--line-strong);border-radius:var(--r-sm);padding:.4rem .6rem;font-size:var(--fs-xs);
  font-weight:500;white-space:nowrap;max-width:260px;box-shadow:var(--e-3);opacity:0;pointer-events:none;
  transition:opacity var(--dur-1) var(--ease),transform var(--dur-1) var(--ease);z-index:60}
.tip:hover::after,.tip:focus-visible::after{opacity:1;transform:translateX(-50%) translateY(0)}

/* ---- data table ----
   `.admin-users` is the legacy class; it only ever had mobile rules, so admin tables rendered
   with no base styling at all. It is aliased here onto .dtable so every table in the product
   reads the same. New code uses .dtable (UI_INVENTORY §17). */
.dtable,table.admin-users{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
.dtable th,table.admin-users th{text-align:left;font-size:var(--fs-xs);text-transform:uppercase;
  letter-spacing:.05em;color:var(--dim);font-weight:700;padding:.6rem .7rem;
  border-bottom:1px solid var(--line)}
.dtable td,table.admin-users td{padding:.7rem;border-bottom:1px solid var(--line-soft)}
.dtable tbody tr,table.admin-users tbody tr{transition:background var(--dur-1) var(--ease)}
.dtable tbody tr:hover,table.admin-users tbody tr:hover{background:var(--panel2)}
.dtable tbody tr:last-child td,table.admin-users tbody tr:last-child td{border-bottom:0}

/* ---- inline spinner ---- */
.spin{display:inline-block;width:1em;height:1em;border:2px solid currentColor;border-right-color:transparent;
  border-radius:50%;animation:spin .7s linear infinite;vertical-align:-.15em}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---- score ring: an animated 0-100 dial (quality / CTR). --deg is set inline or by JS ---- */
.ring{--deg:0deg;--ring-c:var(--brand);position:relative;width:74px;height:74px;flex:0 0 auto;
  border-radius:50%;display:grid;place-items:center;
  background:conic-gradient(var(--ring-c) var(--deg), var(--panel2) 0);
  transition:--deg var(--dur-3) var(--ease)}
.ring::before{content:"";position:absolute;inset:5px;border-radius:50%;background:var(--panel)}
.ring .rv{position:relative;font-weight:800;font-size:1.35rem;line-height:1;font-family:var(--font-head)}
.ring .rl{position:relative;font-size:.55rem;color:var(--dim);text-transform:uppercase;letter-spacing:.06em}
.ring.sm{width:52px;height:52px} .ring.sm .rv{font-size:1rem}
@property --deg{syntax:'<angle>';inherits:false;initial-value:0deg}

/* ---- dimension bar: one scored dimension (hook, pacing, emotion…) ---- */
.dim-row{display:flex;align-items:center;gap:.6rem;padding:.3rem 0}
.dim-row .dl{flex:0 0 8.5rem;font-size:var(--fs-xs);color:var(--mut)}
.dim-row .dt{flex:1;height:6px;border-radius:var(--r-full);background:var(--panel2);overflow:hidden}
.dim-row .df{height:100%;border-radius:var(--r-full);background:var(--grad-brand);
  transition:width var(--dur-3) var(--ease-out)}
.dim-row .df.ok{background:var(--ok)} .dim-row .df.warn{background:var(--warn)}
.dim-row .df.bad{background:var(--bad)}
.dim-row .dv{flex:0 0 2.2rem;text-align:right;font-size:var(--fs-xs);font-weight:700;color:var(--mut)}

/* ---- activity feed: a polished timeline, not a log file ---- */
.feed{position:relative;padding-left:1.35rem}
.feed::before{content:"";position:absolute;left:.42rem;top:.4rem;bottom:.4rem;width:1px;
  background:linear-gradient(var(--line-strong),transparent)}
.fitem{position:relative;padding:.5rem 0 .6rem}
.fitem .fdot{position:absolute;left:-1.18rem;top:.62rem;width:.85rem;height:.85rem;border-radius:50%;
  background:var(--panel2);border:1px solid var(--line-strong);display:grid;place-items:center;
  font-size:.5rem;line-height:1}
.fitem.ai .fdot{background:rgba(124,92,255,.25);border-color:rgba(124,92,255,.5)}
.fitem.render .fdot{background:var(--info-bg);border-color:var(--info-line)}
.fitem.version .fdot{background:var(--ok-bg);border-color:var(--ok-line)}
.fitem .fs{font-size:var(--fs-sm)}
.fitem .fm{font-size:var(--fs-xs);color:var(--dim);margin-top:.1rem}
.fdelta{display:inline-flex;align-items:center;gap:.3rem;font-size:var(--fs-xs);font-weight:700;
  padding:.1rem .45rem;border-radius:var(--r-sm);background:var(--bg2);border:1px solid var(--line);
  margin:.25rem .3rem 0 0}
.fdelta .up{color:var(--ok-fg)} .fdelta .down{color:var(--bad-fg)}

/* ---- scene card ---- */
.scard{display:grid;grid-template-columns:82px 1fr;gap:.9rem;padding:.85rem}
.scard .sthumb{aspect-ratio:9/16;border-radius:var(--r-sm);background:var(--panel2);
  display:grid;place-items:center;overflow:hidden;position:relative;font-size:1.1rem;color:var(--dim)}
.scard .sthumb img{width:100%;height:100%;object-fit:cover}
.scard .sno{position:absolute;top:.2rem;left:.2rem;background:rgba(0,0,0,.6);border-radius:var(--r-sm);
  font-size:.6rem;font-weight:700;padding:.05rem .3rem;color:#fff}
@media(max-width:560px){ .scard{grid-template-columns:56px 1fr} }

/* ═══════════ ART COMPONENTS v2 ═══════════ */

/* COVER ART — every project/opportunity gets a unique, recognisable image with ZERO assets.
   --h is a hue derived server-side from the title hash, so the same story always looks the
   same (like Linear's project colours / GitHub identicons). Two offset conic gradients + a
   grain give it depth rather than looking like a flat swatch. */
.cover{position:relative;overflow:hidden;border-radius:var(--r-md);
  background:
    radial-gradient(120% 100% at 15% 10%, hsl(var(--h,265) 85% 62% / .85), transparent 55%),
    radial-gradient(110% 90% at 85% 25%, hsl(calc(var(--h,265) + 55) 85% 58% / .7), transparent 55%),
    conic-gradient(from calc(var(--h,265) * 1deg) at 40% 70%,
      hsl(var(--h,265) 70% 22%), hsl(calc(var(--h,265) + 70) 70% 16%), hsl(var(--h,265) 70% 22%));
  box-shadow:var(--edge-top)}
.cover::after{content:"";position:absolute;inset:0;opacity:.5;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='c'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='90' height='90' filter='url(%23c)'/%3E%3C/svg%3E")}
.cover .cover-mark{position:absolute;inset:0;display:grid;place-items:center;
  font-family:var(--font-head);font-weight:700;font-size:1.9rem;color:rgba(255,255,255,.92);
  text-shadow:0 2px 18px rgba(0,0,0,.5);letter-spacing:-.04em}
.card-hover:hover .cover{transform:scale(1.03)}
.cover{transition:transform var(--dur-3) var(--swift)}

/* ANIMATED COUNTER — number rolls up on first paint. .counter[data-to] */
.counter{font-variant-numeric:tabular-nums}

/* AI THINKING SEQUENCE — the AI Producer's work, made visible.
   Each stage lights in turn; the active one glows and its dot spins. */
.think{display:grid;gap:.1rem}
.think-step{display:flex;align-items:center;gap:.7rem;padding:.5rem .2rem;opacity:.32;
  transition:opacity var(--dur-2) var(--smooth),transform var(--dur-2) var(--swift);
  transform:translateX(-4px)}
.think-step.on{opacity:1;transform:none}
.think-step.done{opacity:.58;transform:none}
.think-step .tdot{width:20px;height:20px;border-radius:50%;flex:0 0 auto;display:grid;
  place-items:center;font-size:.6rem;border:1px solid var(--line-strong);background:var(--panel2);
  transition:all var(--dur-2) var(--spring)}
.think-step.on .tdot{border-color:transparent;background:var(--grad-brand);color:#fff;
  box-shadow:var(--glow-brand);animation:tspin 1.1s linear infinite}
.think-step.done .tdot{background:var(--ok-bg);border-color:var(--ok-line);color:var(--ok-fg)}
@keyframes tspin{to{transform:rotate(360deg)}}
.think-step .tlabel{font-size:var(--fs-sm);font-weight:600}
.think-step.on .tlabel{color:#fff}
.think-step .tnote{font-size:var(--fs-xs);color:var(--dim);margin-left:auto}
/* the shimmer that says "working" */
.think-step.on .tlabel{background:linear-gradient(90deg,#fff,#9db4ff,#fff);background-size:200% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;animation:tshine 1.6s linear infinite}
@keyframes tshine{to{background-position:-200% 0}}

/* DISCOVERY FEED — opportunities as artwork, not table rows */
.feed-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:1.1rem}
.disc{position:relative;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--glass-line);
  background:var(--glass);box-shadow:var(--lift-2);display:flex;flex-direction:column;
  transition:transform var(--dur-2) var(--swift),box-shadow var(--dur-2) var(--swift),
             border-color var(--dur-2) var(--smooth)}
.disc:hover{transform:translateY(-6px);border-color:rgba(124,92,255,.36);
  box-shadow:var(--lift-4),0 0 50px -16px rgba(124,92,255,.55)}
.disc .art{aspect-ratio:16/10;position:relative;border-radius:0}
.disc .art .score{position:absolute;top:.55rem;right:.55rem;display:grid;place-items:center;
  width:38px;height:38px;border-radius:50%;font-weight:800;font-size:.82rem;
  font-family:var(--font-head);background:rgba(6,10,24,.72);color:#fff;
  border:1px solid var(--glass-line-hi);backdrop-filter:var(--blur-lite)}
.disc .art .cat{position:absolute;bottom:.55rem;left:.55rem}
.disc .body{padding:.85rem .9rem 1rem;display:flex;flex-direction:column;gap:.5rem;flex:1}
.disc .disc-cta{transform:translateY(4px);opacity:0;
  transition:opacity var(--dur-2) var(--smooth),transform var(--dur-2) var(--swift)}
.disc:hover .disc-cta{opacity:1;transform:none}
@media (hover:none){ .disc .disc-cta{opacity:1;transform:none} }

/* FLOATING TOOLBAR — hovers over content (storyboard) */
.floatbar{position:sticky;top:var(--sp-3);z-index:15;display:flex;align-items:center;gap:.5rem;
  padding:.5rem .6rem;border-radius:var(--r-full);border:1px solid var(--glass-line);
  background:rgba(12,18,38,.72);box-shadow:var(--lift-3);width:fit-content;margin:0 auto var(--sp-4);
  backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur)}

/* ---- workflow rail: the connected Opportunity → … → Library path ---- */
.wfrail{display:flex;align-items:center;gap:.15rem;overflow-x:auto;padding:var(--sp-2) 0 var(--sp-4);
  -webkit-overflow-scrolling:touch;scrollbar-width:none}
.wfrail::-webkit-scrollbar{display:none}
.wfstep{display:inline-flex;align-items:center;gap:.4rem;padding:.3rem .6rem;border-radius:var(--r-full);
  font-size:var(--fs-xs);font-weight:600;color:var(--dim);white-space:nowrap;flex:0 0 auto;
  transition:color var(--dur-1) var(--ease),background var(--dur-1) var(--ease)}
.wfstep .n{display:grid;place-items:center;width:1.25rem;height:1.25rem;border-radius:50%;
  background:var(--panel2);color:var(--mut);font-size:.7rem}
.wfstep.done{color:var(--ok-fg)} .wfstep.done .n{background:var(--ok-bg);color:var(--ok-fg)}
.wfstep.now{color:var(--fg);background:rgba(124,92,255,.12)} .wfstep.now .n{background:var(--grad-brand);color:#fff}
.wfsep{color:var(--dim);flex:0 0 auto;opacity:.5}

/* ── Image Review Studio ───────────────────────────────────────────────────────────────────
   Built for reviewing hundreds of images in one sitting: a dense contact-sheet grid, a full
   metadata panel, and keyboard-only operation (arrows to move, L/D to judge, Enter to save). */
.rgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:.9rem;
  margin-top:var(--sp-4)}
.rtile{margin:0;position:relative;border:2px solid var(--line);border-radius:12px;overflow:hidden;
  background:var(--panel);cursor:pointer;transition:transform .12s ease,border-color .12s ease}
.rtile:hover{transform:translateY(-2px);border-color:var(--brand)}
.rtile:focus{outline:none;border-color:var(--brand2)}
.rtile img{width:100%;aspect-ratio:9/16;object-fit:cover;display:block}
.rtile.like{border-color:#2f7d4f}
.rtile.dislike{border-color:#7d2f36}
.rtile figcaption{position:absolute;left:0;right:0;bottom:0;display:flex;flex-wrap:wrap;gap:.25rem;
  padding:.4rem;background:linear-gradient(transparent,rgba(0,0,0,.82))}
.rbadge{font-size:.68rem;font-weight:700;padding:.1rem .35rem;border-radius:5px;
  background:rgba(0,0,0,.6);color:#dbe4ff;border:1px solid rgba(255,255,255,.14)}
.rbadge.good{color:#86efac;border-color:#2f7d4f}
.rbadge.warn{color:#fde68a;border-color:#7a6320}
.rbadge.bad{color:#ff8a8a;border-color:#7d2f36}
.rtile.like .rverdict::after{content:"👍"}
.rtile.dislike .rverdict::after{content:"👎"}

.rpanel{position:fixed;inset:0;background:rgba(4,6,14,.86);backdrop-filter:blur(3px);z-index:80;
  display:none;padding:2rem 1rem}
.rpanel.open{display:block;animation:rfade .16s ease}
@keyframes rfade{from{opacity:0}to{opacity:1}}
.rpanel-in{max-width:1500px;margin:0 auto;height:100%;display:grid;
  grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:1.2rem;position:relative}
.rpanel-img{display:flex;flex-direction:column;gap:.7rem;min-height:0}
.rpanel-img img{flex:1;min-height:0;width:100%;object-fit:contain;border-radius:14px;
  border:1px solid var(--line);background:#05070f;cursor:zoom-in;transition:transform .18s ease}
.rpanel-img img.zoom{object-fit:cover;transform:scale(1.35);cursor:zoom-out}
.rstrip{display:flex;gap:.5rem;overflow-x:auto;padding-bottom:.2rem}
.rthumb{flex:0 0 auto;background:none;border:2px solid var(--line);border-radius:9px;padding:0;
  cursor:pointer;overflow:hidden;width:84px}
.rthumb.active{border-color:var(--brand)}
.rthumb img{width:100%;height:110px;object-fit:cover;display:block}
.rthumb span{display:block;font-size:.62rem;color:var(--mut);padding:.15rem}
.rpanel-meta{overflow-y:auto;padding-right:.4rem;background:var(--panel);border:1px solid var(--line);
  border-radius:14px;padding:1.1rem}
.rsec{margin-top:1rem}
.rsec>b{display:block;margin-bottom:.25rem;font-size:.82rem;letter-spacing:.02em;color:var(--fg)}
.rpre{white-space:pre-wrap;word-break:break-word;background:#0b1024;border:1px solid var(--line);
  border-radius:9px;padding:.6rem;font-size:.78rem;color:#c6d2f2;margin:0;max-height:11rem;overflow:auto}
.rtab{width:100%;font-size:.8rem;border-collapse:collapse}
.rtab td{padding:.22rem .3rem;border-bottom:1px solid var(--line);vertical-align:top}
.rtab td:first-child{width:44%}
.rgroup{margin:.5rem 0}
.rgtitle{display:block;font-size:.7rem;text-transform:uppercase;letter-spacing:.06em;color:var(--dim);
  margin-bottom:.25rem}
.rchip{display:inline-flex;align-items:center;gap:.3rem;font-size:.76rem;padding:.2rem .5rem;
  margin:.15rem .2rem .15rem 0;border:1px solid var(--line);border-radius:999px;cursor:pointer}
.rchip:has(input:checked){border-color:var(--brand);background:rgba(124,92,255,.16)}
.rclose{position:absolute;top:-1.4rem;right:0;background:none;border:none;color:var(--mut);
  font-size:1.3rem;cursor:pointer;z-index:2}
kbd{background:#0b1024;border:1px solid var(--line);border-bottom-width:2px;border-radius:5px;
  padding:0 .3rem;font-size:.74rem}
@media (max-width:980px){.rpanel-in{grid-template-columns:1fr;overflow-y:auto}
  .rpanel-img img{max-height:52vh}}

/* User image rating (storyboard) — feedback only, never alters the rendered video. */
.rategrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:.8rem;
  margin-top:var(--sp-3)}
.ratecard{margin:0;background:var(--panel);border:2px solid var(--line);border-radius:12px;
  overflow:hidden;transition:border-color .15s ease}
.ratecard img{width:100%;aspect-ratio:9/16;object-fit:cover;display:block}
.ratecard figcaption{padding:.55rem}
.ratecard.voted-up{border-color:#2f7d4f}
.ratecard.voted-down{border-color:#7d2f36}
.ratecard button:disabled{opacity:.45;cursor:default}
