/* ==========================================================================
   glu studio design system: tokens + components. ONE source of truth.
   Source:  work/wan/public/studio/create/_shared/ds.css   (served as /studio/create/_shared/ds.css)
   Used by: /studio (body.theatre), /studio/create, /studio/explore, /studio/skills, /studio/account, the studio mock build
            (work/wan/review/build -> /studio/create/mock/), and manage.glu.tv
            (work/manage/public/ds.css is a GENERATED copy written by
            work/scripts/deploy-manage.py; never edit the copy).
   Design note: work/wan/review/build/DESIGN.md
   Layers (z-index): sticky bars 20 (.ex-bar, .q-strip) · account tabs 40 · studio dock, library panel 55 · sidebar scrim 58 ·
   sidebar 59 · top bar 60 · menus 70-71 · drawers 84-85 (style.css) · library sheet 89-90 · create sheets 94-95
   (create/studio.css) · skip link and mock flag 300 · toast 400.

   Two rooms, one system:
   - Workshop (default): graphite surfaces separated by TONE, not lines (see SURFACES below), dark wells behind
     media, magenta ONLY for actions, active states and focus.
   - Theatre (body.theatre): the marketing stage. Cinematic black page,
     full-bleed video; same components on top.
   Type: Anton for film titles and section titles only. Inter for all UI.

   LAYOUT RULES (one experience on every page; page CSS may not restyle these, only place them)
   1. Pill = ONE component. Options, filters and toggles are .chip, or .opt (radio) / .opt-b (toggle button) inside .opts.
      They are the same pill: --pill-h 44px (md, the default, also the touch target), 16px side padding, .875rem 600.
      .chip.sm / .opt.sm / .pill-sm = --pill-h-sm 36px, ONLY for dense toolbars on a fine pointer (becomes 44px on touch).
      .seg (segmented switch between views) is 44px outside, so it sits level with pills.
   2. Button = .btn (48 default), .btn-sm 44 (cards, rows, dialogs), .btn-lg / .big 52. Never under 44px.
      Primary action in a panel or form = .btn.big (full width, 52px), last in the stack, --grp-gap below its group.
      Primary in a row/card = .btn.btn-sm; secondary = .btn-ghost; destructive = .btn-danger.
   3. Link = .btn-link (and .lnk inline): brand pink (--signal-text), 600, .875rem, 44px tall, underline on hover.
      Back links, "see all", "build it in the studio" and "Reset" are all this one style.
   4. Labels: .lbl sits --lbl-gap (10px) above its control, for <label>, <legend> and .fs-h alike.
   5. Groups: --grp-gap (24px) between one labelled group and the next, in every form (.sform, .sset, .opstack, .form-a).
   6. Panel heading (Anton .t-title) to its first control: --head-gap (24px). Panel padding: --pad-panel. Nested rows: --pad-inset.
   7. Sections on a page: --sec-gap (48px) above a section heading, --sec-head-gap (16px) between heading and content.
   9. SURFACES (tone, not lines). Page --bg < --surface-1 (cards, panels, dialogs) < --surface-2 (raised controls, and anything nested
      in a card) < --surface-3 (hover). Cards and panels have NO outline; a nested panel has no outline and no box-in-box (a faint
      --surface-nest tint or just spacing). Wells (text areas, inputs, the preview, media backing) are DARKER than the surface they
      sit on, with no drop shadow or glow. --line-faint (6% white) is the only hairline: dividers and where two same-tone surfaces
      touch; drop a divider where spacing already separates. Secondary controls (ghost buttons, chips, pills) and fields keep an
      edge of at least 3:1 against their surfaces (WCAG 1.4.11; Sasha, 27 Oct): --line-ctl for controls, --line-field for inputs
      (hover --line-ctl-hi). Dashed "add" affordances use --line-dash. Shadows are for floating layers only (menus, dialogs,
      toasts, drawers), never for something sitting in the page.
   8. Current / selected state is ONE look: signal outline + --signal-dim fill, fully rounded (header section pill,
      account side nav, avatar menu, chips, notices). No left accent bars.
      The ONE exception (Sasha, 27 Oct): the left sidebar's current page is glu.tv's fill only, no outline (glu.tv parity).
   States: disabled = --op-disabled on every control (disabled and aria-disabled alike); a card's hover = --lift, its image --zoom.
   ========================================================================== */

:root{
  color-scheme:dark;
  /* colour: surfaces (lightest last) */
  --bg:#17191E;          /* page (surface 0) */
  --well:#101216;        /* recessed: darker than any surface; text areas, inputs, preview, behind media */
  --surface-1:#1F2329;   /* cards, panels, sheets, dialogs: a step lighter than the page, no outline */
  --surface-2:#272B32;   /* raised controls, and anything nested in a card */
  --surface-3:#30353D;   /* hover */
  --surface-nest:rgba(255,255,255,.03);  /* a nested panel: a tint over whatever it sits on (never an outline) */
  --line-faint:rgba(255,255,255,.06);    /* the only hairline: dividers, and where two same-tone surfaces touch */
  /* Edges that identify a control reach 3:1 (WCAG 1.4.11; Sasha, 27 Oct, reversing the 26 Oct halving):
     --line-field over the well is 3.57:1 on the well, 3.35 on --bg, 3.00 on --surface-1 (2.71 directly on --surface-2);
     --line-ctl over --surface-2 is 3.18:1 on its fill, 3.53 on --surface-1, 3.93 on --bg. Theatre values are within 0.2 of these. */
  --line-field:rgba(255,255,255,.38);    /* an input's edge */
  --line-ctl:rgba(255,255,255,.36);      /* a secondary control's edge (ghost button, chip, pill, switch track) */
  --line-ctl-hi:rgba(255,255,255,.56);   /* the same, on hover (raised with the rest edge so hover still reads) */
  --line-media:rgba(255,255,255,.3);     /* a control's edge over photos and video */
  --line-dash:rgba(255,255,255,.18);     /* dashed "add" affordances */
  --panel:var(--surface-1);--panel-2:var(--surface-2);--panel-3:var(--surface-3);   /* legacy names */
  --border:var(--line-faint);            /* legacy: card and divider lines are now the faint hairline */
  --border-strong:var(--line-ctl);       /* legacy: control outlines */
  /* colour: content (all AA on bg, panel and panel-2) */
  --ink:#F0EDE8;
  --ink-dim:#B4B8C2;
  --ink-faint:#9AA0AC;
  --on-light:#0D0F14;    /* text on magenta and on ink fills */
  --on-dark:#fff;        /* glyphs and initials on media and on colour swatches */
  /* colour: signal (actions, active, focus) and states */
  --signal:#FF2E88;
  --signal-hi:#FF4F9C;
  --signal-text:#FF6EA9;  /* magenta as small text: AA on every surface incl. panel-3 */
  --signal-dim:rgba(255,46,136,.14);
  --signal-glow:rgba(255,46,136,.35);
  --danger:#FFB4B4;--danger-line:#E07A86;--danger-dim:rgba(224,122,134,.12);
  --warn:#F2C66D;--warn-dim:rgba(242,198,109,.1);
  --scrim:rgba(8,9,12,.78);          /* behind dialogs and sheets */
  --glass:rgba(16,18,22,.72);        /* chips over media */
  --glass-strong:rgba(13,15,20,.9);  /* glass bars, and glass controls on hover */
  --media-fade:linear-gradient(180deg,rgba(16,18,22,0) 0%,rgba(16,18,22,.55) 55%,rgba(16,18,22,.92) 100%);

  /* type */
  --font-ui:"Inter",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-head:"Anton",Impact,"Arial Narrow",sans-serif;
  --font-mono:ui-monospace,SFMono-Regular,Menlo,monospace;
  --head:var(--font-head);
  --fs-xs:.75rem;  --fs-sm:.875rem; --fs-md:1rem; --fs-lg:1.125rem;
  --fs-title-sm:1.375rem;                         /* card / film title */
  --fs-title:clamp(1.5rem,2.6vw,1.875rem);        /* section title */
  --fs-page:clamp(2.25rem,5vw,3.25rem);           /* page title */
  --fs-display:clamp(3rem,9.2vw,7.2rem);          /* theatre hero */
  --lh-tight:1.02;--lh-ui:1.5;

  /* space: 4px grid */
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:24px;--sp-6:32px;--sp-7:48px;--sp-8:64px;
  --gutter:24px;
  /* layout rhythm (see LAYOUT RULES above) */
  --lbl-gap:10px;                     /* label -> control */
  --grp-gap:var(--sp-5);              /* group -> group (24) */
  --head-gap:var(--sp-5);             /* panel heading -> first control (24) */
  /* Page spacing (Sasha, 27 Oct): glu.tv's 24px sides and 24px under the header, inside the studio's 1240px desktop letterbox,
     48px between sections. --page-max is the letterbox width (header, footer and carousel maths use it too). */
  --page-max:1240px;--page-pad:24px;--page-top:24px;
  /* Inline inset that puts a FULL-WIDTH bar's content on the letterbox edge (used as padding-inline on the header, whose background stays full-bleed). Resolves against that element's own width. */
  --page-edge:calc(max(0px,(100% - var(--page-max))/2) + var(--page-pad));
  --sec-gap:48px;     /* section -> section heading */
  --sec-head-gap:var(--sp-4);         /* section heading -> its content (16) */
  --pad-panel:clamp(16px,2.4vw,24px); /* card / panel padding */
  --pad-inset:12px 16px;              /* a row or note nested in a panel */
  /* control sizes */
  --pill-h:44px;--pill-h-sm:36px;--pill-px:16px;
  --btn-h:48px;--btn-h-sm:44px;--btn-h-lg:52px;

  /* radii */
  --r-xs:6px;--r-sm:9px;--r-md:12px;--r-lg:16px;--r-pill:999px;

  /* elevation */
  --e-1:0 1px 2px rgba(0,0,0,.25);   /* floating layers only (see rule 9) */
  --e-2:0 8px 24px rgba(0,0,0,.28);
  --e-3:0 18px 48px rgba(0,0,0,.4);
  --e-signal:0 8px 28px var(--signal-glow);

  /* motion */
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --dur-1:140ms;--dur-2:220ms;--dur-3:340ms;
  --lift:translateY(-3px);           /* a card on hover */
  --zoom:scale(1.035);               /* the image inside a card on hover */

  /* states */
  --op-disabled:.45;                 /* every disabled control */

  /* layout */
  --top:67px;   /* = glu.tv header: 66px bar + 1px rule */--foot:60px;--tabbar:0px;--gap:14px;
}
/* Theatre: the marketing stage (/studio). Same system, darker room, with glu.tv's own surfaces (--surface, -2, -3). */
.theatre{--bg:#0D0F14;--well:#07080B;--surface-1:#14161F;--surface-2:#1A1D28;--surface-3:#21242F;
  --panel:var(--surface-1);--panel-2:var(--surface-2);--panel-3:var(--surface-3)}   /* the legacy aliases resolve where they are declared, so restate them here */

/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box}
html{color-scheme:dark;-webkit-text-size-adjust:100%;scroll-padding-top:calc(var(--top) + 16px);scroll-padding-bottom:calc(var(--foot) + 16px)}
body{margin:0;background:var(--bg);color:var(--ink);font:400 var(--fs-md)/var(--lh-ui) var(--font-ui);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;overflow-x:clip}
button,input,textarea,select{font:inherit;color:inherit}
/* no browser bevel on any button: components add their own border, fill and padding */
button{cursor:pointer;border:0;background:none;padding:0}
a{color:inherit;text-underline-offset:3px}
img,video{max-width:100%}
h1,h2,h3,h4,p,ul,ol,fieldset,figure{margin:0}
[hidden]{display:none!important}
::selection{background:var(--signal);color:var(--on-light)}
:focus-visible{outline:2px solid var(--signal);outline-offset:3px}
.sr-only{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:absolute;left:-999px;top:8px;background:var(--signal);color:var(--on-light);padding:10px 16px;border-radius:var(--r-sm);z-index:300;font-weight:700;text-decoration:none}
.skip:focus{left:8px}
.num,.tnum{font-variant-numeric:tabular-nums}

/* ---------- type ---------- */
.t-display,.t-page,.t-title,.t-film,.title-font{font-family:var(--font-head);font-weight:400;text-transform:uppercase;letter-spacing:.02em;line-height:var(--lh-tight);text-wrap:balance}
.t-display{font-size:var(--fs-display)}
.t-page{font-size:var(--fs-page)}
.t-title{font-size:var(--fs-title)}
.t-film{font-size:var(--fs-title-sm);line-height:1.08}
.lbl,.eyebrow{display:block;font:700 .6875rem/1.2 var(--font-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:var(--lbl-gap)}
/* a label that follows another control starts a new group: clear air above, tight below */
:is(.chips,.seg,.field,.opts,.stiles,.row,.ta,.inp,.sel,textarea,input,select,.switch)+.lbl{margin-top:var(--grp-gap)}
.lede{color:var(--ink-dim);font-size:1.0625rem;line-height:1.55;max-width:62ch}
.fine{font-size:.8125rem;color:var(--ink-faint);line-height:1.5}
.dim{color:var(--ink-dim)}
code,.mono{font-family:var(--font-mono);font-size:.9em}

/* ---------- buttons ----------
   .btn is the magenta action. .btn-ghost/.ghost is every secondary action.
   Sizes: default 48, .btn-sm/.sm 44, .btn-lg/.lg 52. .big = full-width. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:var(--btn-h);padding:0 24px;border-radius:var(--r-pill);border:1px solid transparent;background:var(--signal);color:var(--on-light);font-weight:700;font-size:.9375rem;line-height:1.1;text-decoration:none;white-space:nowrap;cursor:pointer;transition:transform var(--dur-1) var(--ease),background-color var(--dur-1),border-color var(--dur-1),box-shadow var(--dur-2) var(--ease),color var(--dur-1)}
.btn:hover{background:var(--signal-hi);box-shadow:var(--e-signal);transform:translateY(-1px)}
.btn:active{transform:translateY(0) scale(.98);box-shadow:none}
.btn svg{width:16px;height:16px;flex:none}
.btn-primary{background:var(--signal);color:var(--on-light)}
.btn-ghost,.btn.ghost{background:var(--panel-2);border-color:var(--border-strong);color:var(--ink)}
.btn-ghost:hover,.btn.ghost:hover{background:var(--surface-3);border-color:var(--line-ctl-hi);box-shadow:none}
.btn-danger{background:transparent;border-color:var(--danger-line);color:var(--danger)}
.btn-danger:hover{background:var(--danger-dim);box-shadow:none}
.btn-sm,.btn.sm{min-height:var(--btn-h-sm);padding:0 20px;font-size:.875rem;gap:8px}
.btn-lg,.btn.lg{min-height:var(--btn-h-lg);padding:0 30px;font-size:1rem}
.btn.big,.btn-block{display:flex;width:100%;min-height:var(--btn-h-lg);font-size:1rem}
.btn[disabled],.btn:disabled,.btn[aria-disabled=true]{opacity:var(--op-disabled);cursor:not-allowed;transform:none;box-shadow:none}
.btn-primary[aria-disabled=true],.btn:not(.btn-ghost):not(.ghost):not(.btn-danger)[aria-disabled=true]{background:var(--signal)}
.btn.busy{opacity:.65;cursor:progress}
.btn-link,.lnk{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 6px;background:none;border:0;color:var(--signal-text);font-weight:600;font-size:.875rem;text-decoration:none;cursor:pointer;transition:color var(--dur-1)}
.btn-link:hover,.btn-link:focus-visible,.lnk:hover,.lnk:focus-visible{color:var(--signal-hi);text-decoration:underline;text-underline-offset:3px}
.iconbtn{width:44px;height:44px;border-radius:50%;border:1px solid var(--border-strong);background:var(--panel-2);color:var(--ink);display:grid;place-items:center;flex:none;padding:0;cursor:pointer;transition:border-color var(--dur-1),background-color var(--dur-1)}
.iconbtn:hover{border-color:var(--line-ctl-hi);background:var(--panel-3)}
.iconbtn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.iconbtn.sm{width:36px;height:36px}
.iconbtn.sm svg{width:15px;height:15px}
.iconbtn[disabled]{opacity:var(--op-disabled);cursor:not-allowed}
/* share row (share.js): round 44px icon buttons in ink, pink on hover/focus. The label is the aria-label; data-tip draws it as a tooltip on pointer hover and keyboard focus (not on touch). */
.shr-l{font:700 .6875rem/1.2 var(--font-ui);text-transform:uppercase;letter-spacing:.1em;color:var(--ink-faint);margin:0 0 var(--sp-2)}
.shr-row{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.shr-b{position:relative;width:44px;height:44px;border-radius:50%;border:1px solid var(--border-strong);background:var(--panel-2);color:var(--ink);display:grid;place-items:center;flex:none;padding:0;cursor:pointer;transition:color var(--dur-1),border-color var(--dur-1),background-color var(--dur-1)}
.shr-b svg{width:20px;height:20px}
.shr-b:hover,.shr-b:focus-visible{color:var(--signal-hi);border-color:var(--signal);background:var(--signal-dim)}
.shr-b[aria-disabled=true]{opacity:var(--op-disabled);cursor:progress}
.shr-b::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);background:var(--ink);color:var(--on-light);font:600 .75rem/1 var(--font-ui);padding:6px 10px;border-radius:var(--r-pill);white-space:nowrap;pointer-events:none;opacity:0;z-index:5;transition:opacity var(--dur-1)}
.shr-b:hover::after,.shr-b:focus-visible::after{opacity:1}
@media (hover:none){.shr-b::after{display:none}}
/* tiles variant: logo over label, a grid (3 across on phones, 4 from 700px) */
.shr.tiles .shr-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-2)}
@media (min-width:700px){.shr.tiles .shr-row{grid-template-columns:repeat(4,minmax(0,1fr))}}
.shr.tiles .shr-b{width:auto;height:auto;min-height:64px;border-radius:var(--r-md);flex-direction:column;gap:6px;padding:10px 4px;display:flex;justify-content:center;align-items:center}
.shr.tiles .shr-b::after{display:none}
.shr-n{font:600 .75rem/1.1 var(--font-ui);text-align:center}
.shr.tiles .shr-st{margin-top:var(--sp-1)}
.shr-st{margin:var(--sp-2) 0 0;min-height:1.2em;font-size:.8125rem;line-height:1.2;color:var(--ink-faint)}

/* ---------- chips, options, segmented control ---------- */
.chips{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
/* the ONE pill: .chip, and .opt / .opt-b inside .opts (radio and toggle options) */
.chip,.opt span,.opt-b{display:inline-flex;align-items:center;gap:6px;min-height:var(--pill-h);padding:0 var(--pill-px);border-radius:var(--r-pill);background:var(--panel-2);border:1px solid var(--border-strong);color:var(--ink-dim);font-weight:600;font-size:.875rem;line-height:1.2;text-decoration:none;text-align:left;white-space:nowrap;cursor:pointer;transition:color var(--dur-1),border-color var(--dur-1),background-color var(--dur-1)}
.chip:hover,.opt-b:hover,.opt:hover span{color:var(--ink);border-color:var(--line-ctl-hi)}
.chip[aria-pressed=true],.chip[aria-checked=true],.chip[aria-expanded=true],.chip[aria-current],.opt input:checked+span,.opt-b[aria-pressed=true]{background:var(--signal-dim);border-color:var(--signal);color:var(--ink)}
.chip.sm,.pill-sm,.opts.sm .opt span,.opts.sm .opt-b{min-height:var(--pill-h-sm);padding:0 12px;font-size:.8125rem}
@media (pointer:coarse){.chip.sm,.pill-sm,.opts.sm .opt span,.opts.sm .opt-b{min-height:var(--pill-h);padding:0 var(--pill-px);font-size:.875rem}}
.opt{position:relative}
.opt input{position:absolute;opacity:0;inset:0;width:100%;height:100%;margin:0;cursor:pointer}
.opt input:focus-visible+span{outline:2px solid var(--signal);outline-offset:2px}
.opts{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.chip.add{border-style:dashed;border-color:var(--line-dash);background:transparent}
.chip.add:hover{border-color:var(--line-ctl-hi);background:var(--surface-2)}
.chip[aria-disabled=true]{opacity:var(--op-disabled);cursor:not-allowed}
.seg{display:inline-flex;gap:4px;padding:4px;background:var(--well);border:0;border-radius:var(--r-pill);max-width:100%;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;overscroll-behavior-x:contain}
.seg::-webkit-scrollbar{display:none}
.seg button{flex:none}
.seg button,.seg [role=tab]{border:0;background:none;padding:0 var(--pill-px);min-height:34px;border-radius:var(--r-pill);font-weight:600;font-size:.875rem;color:var(--ink-dim);white-space:nowrap;cursor:pointer;transition:color var(--dur-1),background-color var(--dur-2) var(--ease)}
.seg button small{font-weight:500;opacity:.75;margin-left:4px}
.seg button:hover:not([aria-pressed=true]):not([aria-selected=true]){color:var(--ink)}
.seg button[aria-pressed=true],.seg button[aria-selected=true]{background:var(--ink);color:var(--on-light)}
.seg button:focus-visible{outline-offset:1px}

/* ---------- form fields ---------- */
.field,.ta,.inp,.sel{width:100%;min-height:46px;background-color:var(--well);border:1px solid var(--line-field);border-radius:var(--r-md);padding:10px 14px;font-size:1rem;line-height:1.45;color:var(--ink);transition:border-color var(--dur-1)}
.field:hover,.ta:hover,.inp:hover,.sel:hover{border-color:var(--line-ctl-hi)}
.field:focus-visible,.ta:focus-visible,.inp:focus-visible,.sel:focus-visible,
.field:focus,.ta:focus,.inp:focus{outline:2px solid var(--signal);outline-offset:1px;border-color:transparent}
.field::placeholder,.ta::placeholder,.inp::placeholder{color:var(--ink-faint);opacity:1}
.field.lg{min-height:52px;padding:12px 16px;font-size:1.1rem}   /* the one large field (sign-in email) */
textarea.field,.ta{resize:vertical;min-height:96px;padding:12px 14px}
/* Touch resize grip (header.js adds .ta-grip on coarse-pointer devices only): drawn like the native grip, bottom padding keeps text clear of it */
@media (pointer:coarse){textarea.ta-grip{resize:none;padding-bottom:26px;background-repeat:no-repeat;background-position:right 4px bottom 4px;background-size:16px 16px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M14 5L5 14M14 9L9 14M14 13L13 14' stroke='%239AA0AC' stroke-width='1.5' stroke-linecap='round' fill='none'/%3E%3C/svg%3E")}}
.field[readonly]{color:var(--ink-dim)}
select.field,.sel{appearance:none;-webkit-appearance:none;padding-right:38px;cursor:pointer;background-image:linear-gradient(45deg,transparent 50%,var(--ink-dim) 50%),linear-gradient(135deg,var(--ink-dim) 50%,transparent 50%);background-position:calc(100% - 19px) 55%,calc(100% - 14px) 55%;background-size:5px 5px;background-repeat:no-repeat}
select.field option,.sel option{background:var(--panel-2);color:var(--ink)}
.form{display:grid;gap:var(--sp-4);max-width:520px}
.check{display:inline-flex;align-items:center;gap:10px;min-height:44px;color:var(--ink-dim);font-weight:600;font-size:.9rem;cursor:pointer}
.check input,input[type=checkbox],input[type=radio],input[type=range]{accent-color:var(--signal)}
.check input{width:18px;height:18px;margin:0}
/* switch */
.switch,.sw{position:relative;display:flex;align-items:center;gap:12px;min-height:48px;cursor:pointer;font-weight:600}
.switch input,.sw input{position:absolute;opacity:0;width:1px;height:1px}
.switch .tr,.sw .trk{flex:none;width:44px;height:26px;border-radius:var(--r-pill);background:var(--well);border:1px solid var(--border-strong);position:relative;transition:background-color var(--dur-1),border-color var(--dur-1)}
.switch .tr::after,.sw .trk::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:var(--ink-dim);transition:transform var(--dur-2) var(--ease-out),background-color var(--dur-1)}
.switch input:checked+.tr,.sw input:checked+.trk{background:var(--signal-dim);border-color:var(--signal)}
.switch input:checked+.tr::after,.sw input:checked+.trk::after{transform:translateX(18px);background:var(--signal)}
.switch input:focus-visible+.tr,.sw input:focus-visible+.trk{outline:2px solid var(--signal);outline-offset:3px}
.switch input:disabled+.tr{opacity:var(--op-disabled)}
.sw{width:fit-content}
.switch small{display:block;font-weight:400;color:var(--ink-faint);font-size:.8rem}

/* ---------- surfaces ---------- */
.card,.panel{background:var(--surface-1);border-radius:var(--r-lg);padding:var(--pad-panel)}
/* a panel inside a card: a tint, no outline, never box-in-box */
.card .card,.card .panel,.panel .card,.panel .panel,.nest{background:var(--surface-nest);border-radius:var(--r-md)}
.well{background:var(--well);border-radius:var(--r-md)}
.rows{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.rows>.row{display:flex;flex-wrap:wrap;gap:10px 16px;align-items:center;justify-content:space-between;background:var(--surface-1);border-radius:var(--r-md);padding:var(--pad-inset)}
.rows>.row .main{min-width:0;flex:1 1 260px}
.rows>.row b{display:block;overflow-wrap:anywhere}
.rows>.row small,.rows>.row .sub{color:var(--ink-dim);font-size:.86rem;overflow-wrap:anywhere}
.rows>.row .acts{display:flex;gap:8px;flex-wrap:wrap}
.notes{margin:0;padding-left:1.2em;color:var(--ink-dim);display:grid;gap:6px}
details.faq{background:var(--surface-1);border-radius:var(--r-md);padding:0 16px;transition:background-color var(--dur-1)}
details.faq+details.faq{margin-top:10px}
details.faq[open]{background:var(--surface-2)}
details.faq summary{min-height:52px;display:flex;align-items:center;gap:12px;cursor:pointer;font-weight:600;list-style:none}
details.faq summary::-webkit-details-marker{display:none}
details.faq summary::after{content:"";margin-left:auto;flex:none;width:8px;height:8px;border-right:2px solid var(--ink-dim);border-bottom:2px solid var(--ink-dim);transform:translateY(-2px) rotate(45deg);transition:transform var(--dur-2) var(--ease)}
details.faq[open] summary::after{transform:translateY(2px) rotate(-135deg)}
details.faq summary:focus-visible{outline-offset:-2px;border-radius:var(--r-sm)}
details.faq p{padding:0 0 16px;color:var(--ink-dim)}

/* ---------- tables ---------- */
.tbl-wrap{overflow-x:auto}
.tbl{width:100%;border-collapse:collapse;font-size:.92rem;font-variant-numeric:tabular-nums}
.tbl caption{text-align:left;font:700 .6875rem/1 var(--font-ui);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint);padding-bottom:10px}
.tbl th,.tbl td{text-align:left;padding:11px 8px;border-bottom:1px solid var(--border)}
.tbl thead th{color:var(--ink-faint);font-weight:600;font-size:.8rem}
.tbl tbody tr{transition:background-color var(--dur-1)}
.tbl tbody tr:hover{background:rgba(255,255,255,.025)}
.tbl tfoot th,.tbl tfoot td{font-weight:700;border-bottom:0}

/* ---------- status: pills, tags, badges, meters ---------- */
.stat{display:inline-flex;align-items:center;white-space:nowrap;font:700 .6875rem/1 var(--font-ui);letter-spacing:.08em;text-transform:uppercase;padding:5px 9px;border-radius:var(--r-pill);border:1px solid var(--border-strong);color:var(--ink-dim);background:var(--panel-2)}
.stat:empty{display:none}
.stat.prog{border-color:var(--signal);background:var(--signal-dim);color:var(--ink)}
.stat.fin{background:var(--ink);color:var(--on-light);border-color:var(--ink)}
.stat.bad{border-color:var(--danger-line);color:var(--danger);background:var(--danger-dim)}
.badge{display:inline-grid;place-items:center;min-width:22px;height:22px;padding:0 7px;border-radius:var(--r-pill);background:var(--panel-2);border:1px solid var(--border-strong);font:700 .72rem/1 var(--font-ui);color:var(--ink)}
.badge.hot,.bdg{background:var(--signal);border-color:var(--signal);color:var(--on-light)}
.bdg{display:inline-grid;place-items:center;min-width:20px;height:20px;padding:0 6px;border-radius:var(--r-pill);font-size:.75rem;font-weight:700}
.bar{height:8px;background:var(--panel-2);border-radius:var(--r-pill);overflow:hidden}
.bar>div,.bar>i{display:block;height:100%;width:0;background:var(--signal);border-radius:inherit;transition:width .4s var(--ease)}
.bar.ind>div,.bar.ind>i{width:35%!important;animation:ds-ind 1.3s var(--ease) infinite}
@keyframes ds-ind{from{transform:translateX(-100%)}to{transform:translateX(300%)}}
.spin{flex:none;width:24px;height:24px;border-radius:50%;border:3px solid var(--panel-3);border-top-color:var(--signal);animation:ds-spin .8s linear infinite}
@keyframes ds-spin{to{transform:rotate(360deg)}}
/* loading skeleton: a soft sweep, not a blink */
.sk,.gb-sk{position:relative;overflow:hidden;background:var(--panel);border-radius:var(--r-lg)}
.sk::after,.gb-sk::after{content:"";position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,rgba(255,255,255,.045),transparent);animation:ds-sweep 1.6s var(--ease) infinite}
@keyframes ds-sweep{to{transform:translateX(100%)}}
/* Result box (glu.box in glu.js): the exact space a creation takes, from the moment making starts until the media is in it.
   Size comes from the job's ratio (--ar 'W / H', --arn W/H) and --mbox-h (the tallest it may be); the media fills the same box
   (object-fit:contain), so making -> done never moves anything. .mbox-load (the X2 loader, NN% when known, status) is
   reusable on its own inside any positioned box of a fixed size (the /studio/create scene well, a card thumb). .in = the media loaded. */
.mbox{--mbox-h:min(64vh,620px);position:relative;display:block;width:100%;max-width:calc(var(--mbox-h) * var(--arn,1));aspect-ratio:var(--ar,1);margin-inline:auto;background:var(--well);border-radius:var(--r-md);overflow:hidden;isolation:isolate;container-type:inline-size}
.mbox-m{position:absolute;inset:0;display:block;width:100%;height:100%;max-width:none;max-height:none;object-fit:contain;background:var(--well);opacity:0;transition:opacity .45s var(--ease)}
.in>.mbox-m{opacity:1}
.mbox-load{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:16px 16px 22px;text-align:center;overflow:hidden;transition:opacity .3s var(--ease)}
.in>.mbox-load{opacity:0;visibility:hidden;transition:opacity .3s var(--ease),visibility 0s .3s}
.mbox-load::before{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(100deg,transparent 30%,rgba(255,255,255,.06) 50%,transparent 70%);background-size:220% 100%;animation:mbox-shine 1.8s linear infinite}
@keyframes mbox-shine{from{background-position:120% 0}to{background-position:-120% 0}}
.mbox-pct{font:400 clamp(2rem,16cqi,4.5rem)/1 var(--font-head);letter-spacing:.01em;font-variant-numeric:tabular-nums;color:var(--ink)}
.mbox-pct[hidden],.mbox-dot[hidden]{display:none}
.mbox-dot{display:block;width:12px;height:12px;margin-bottom:6px;border-radius:50%;background:var(--signal);animation:mbox-pulse 1.2s var(--ease) infinite}
@keyframes mbox-pulse{50%{transform:scale(1.7);opacity:.35}}
.mbox-st{margin:0;max-width:30ch;font-weight:600;font-size:.9rem;line-height:1.35;color:var(--ink-dim);overflow-wrap:anywhere}
.mbox-bar{display:none;position:absolute;left:0;right:0;bottom:0;height:4px;background:rgba(255,255,255,.06);overflow:hidden}
.mbox-bar>i{display:block;height:100%;width:0;background:var(--signal);transition:width .4s var(--ease)}
.mbox-bar.ind{display:none}   /* no progress bars at all, percent or not: the shimmer, the pulse and the status say it is working (Sasha, 28 Oct) */
/* The X2 loader (glu-loader.js adds .g1 and the canvas where canvas works; elsewhere the shimmer + pulse above stay): a glossy 3D magenta
   jelly seeded by the job id, over the H mesh drift (two soft colour fields drifting slowly). The canvas holds a square picture, kept
   centred and whole by object-fit; it sits above the status and gives way to the big NN% when the engine reports progress.
   .still = not animating (reduced motion, the slow-device fallback, or more loaders than may animate at once): one frame that breathes. */
.mbox-load.g1{background:radial-gradient(50% 40% at 70% 20%,rgba(255,79,156,.10),transparent 70%)}
.mbox-load.g1::before,.mbox-load.g1::after{content:"";position:absolute;inset:auto;z-index:-1;width:90%;aspect-ratio:1;border-radius:50%;background-size:auto;will-change:transform}
.mbox-load.g1::before{left:-25%;top:-15%;background:radial-gradient(closest-side,rgba(255,46,136,.30),transparent);animation:mbox-m1 11s ease-in-out infinite alternate}
.mbox-load.g1::after{right:-30%;bottom:-25%;background:radial-gradient(closest-side,rgba(122,60,255,.22),transparent);animation:mbox-m2 13s ease-in-out infinite alternate}
@keyframes mbox-m1{to{transform:translate(45%,55%) scale(1.15)}}
@keyframes mbox-m2{to{transform:translate(-50%,-40%) scale(.9)}}
.mbox-load.g1 .mbox-dot{display:none}
.mbox-gcv{display:block;flex:0 1 auto;width:min(88%,250px);height:min(62%,250px);min-height:0;object-fit:contain}
.mbox-gcv.still{animation:mbox-calm 3s ease-in-out infinite alternate}
.mbox-pct:not([hidden])+.mbox-gcv,.err>.mbox-load .mbox-gcv,.err>.mbox-load.g1::after{display:none}
@keyframes mbox-calm{to{opacity:.45}}
.err>.mbox-load::before,.err>.mbox-load .mbox-dot,.err>.mbox-load .mbox-bar{display:none}
@media(prefers-reduced-motion:reduce){
  .mbox-load::before{animation:none;background:none}
  .mbox-load.g1::before,.mbox-load.g1::after{animation:none}
  .mbox-dot{animation:none}
  .mbox-bar.ind>i{animation:none;width:100%;opacity:.35}
}

/* ---------- feedback: notices, empty and error states ---------- */
.notice{display:flex;gap:12px;align-items:flex-start;padding:var(--pad-inset);border-radius:var(--r-md);background:var(--surface-2);border:1px solid transparent;font-size:.9rem}
.notice.signal{border-color:var(--signal);background:var(--signal-dim)}
.notice.bad{border-color:var(--danger-line);background:var(--danger-dim)}
.notice.warn{border-color:var(--warn);background:var(--warn-dim)}
.empty-state{display:grid;justify-items:center;gap:12px;text-align:center;padding:clamp(24px,5vw,48px) clamp(16px,4vw,32px);border:1.5px dashed var(--line-dash);border-radius:var(--r-lg);color:var(--ink-dim)}
.empty-state h2,.empty-state .t-title{color:var(--ink)}
.empty-state p{max-width:52ch}
.err-text{color:var(--danger)}

/* ---------- media ---------- */
/* A well behind every image and video; a bottom scrim keeps text legible over media
   and also sits over the engine watermark (bottom-right). */
.media{position:relative;background:var(--well);overflow:hidden;isolation:isolate}
.media>img,.media>video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.media>.mbox-m{object-fit:contain}   /* a result box is a .media too: its picture is never cropped */
/* Click to play (play.js): a result video starts without native controls (Chrome's grey buffered bar reads as a stuck loader);
   the Play button fills its parent, the first click removes it and turns the native controls on. Hover = transform/opacity only. */
.cp-btn{position:absolute;inset:0;z-index:1;display:grid;place-items:center;padding:0;border:0;background:transparent;color:var(--signal);cursor:pointer;transition:opacity .3s var(--ease)}
.cp-disc{display:grid;place-items:center;width:64px;height:64px;border-radius:50%;background:var(--glass);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);transition:transform .2s var(--ease-out)}
.cp-disc svg{margin-left:3px}   /* the triangle's weight sits left of its box */
.cp-btn:focus-visible{outline:0}
.cp-btn:focus-visible .cp-disc{outline:3px solid #fff;outline-offset:3px}
:is(.mbox,.well):not(.in)>.cp-btn{opacity:0;pointer-events:none}   /* not until the first frame has faded in */
@media (hover:hover){.cp-btn:hover .cp-disc{transform:scale(1.1)}}
@media (prefers-reduced-motion:reduce){.cp-btn,.cp-disc{transition:none}.cp-btn:hover .cp-disc{transform:none}}
.scrim-b::after{content:"";position:absolute;inset:auto 0 0 0;height:42%;background:var(--media-fade);pointer-events:none;z-index:1}
/* Drop targets (GluUpload.dropZone): highlight while files hover; the "or drop it here" hint shows only where a mouse can drag a file in. */
.dz-hint{display:none}
@media (hover:hover) and (pointer:fine){.dz-hint{display:inline}}
/* One dashed line, never two: the outline sits exactly on the zone's own edge (over its border, which goes clear), so a zone with a dashed border and one without look the same */
.dz.over{border-color:transparent;background:color-mix(in srgb,var(--signal-text) 8%,var(--well));outline:1.5px dashed var(--signal-text);outline-offset:-1.5px;border-radius:var(--r-md)}
.dz.over .drop,.dz.over .ps-drop,.dz.over .gs-zone{border-color:transparent}
.glass{background:var(--glass);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}

/* ---------- dialogs and sheets ---------- */
dialog.dlg{margin:auto;width:min(500px,calc(100vw - 24px));max-height:calc(100dvh - 24px);overflow:auto;background:var(--panel);color:var(--ink);border:1px solid var(--line-faint);border-radius:var(--r-lg);padding:clamp(18px,3vw,28px);box-shadow:var(--e-3)}
dialog.dlg::backdrop{background:var(--scrim);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
dialog.dlg[open]{animation:ds-pop var(--dur-2) var(--ease-out)}
dialog.dlg h2{font-family:var(--font-head);font-weight:400;text-transform:uppercase;letter-spacing:.02em;line-height:1.05;font-size:1.75rem;margin:0 0 10px}
dialog.dlg .acts{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:18px}
@keyframes ds-pop{from{opacity:0;transform:translateY(8px) scale(.98)}}
@keyframes ds-rise{from{opacity:0;transform:translateY(16px)}}

/* ---------- toast ---------- */
.toast{position:fixed;left:50%;bottom:calc(var(--foot) + 16px + var(--tabbar));transform:translate(-50%,16px);opacity:0;pointer-events:none;z-index:400;width:max-content;max-width:calc(100vw - 32px);background:var(--ink);color:var(--on-light);padding:12px 20px;border-radius:var(--r-pill);font-weight:600;font-size:.9rem;line-height:1.35;text-align:center;box-shadow:var(--e-2);transition:opacity var(--dur-2) var(--ease-out),transform var(--dur-3) var(--ease-out)}
.toast.on,.toast.show{opacity:1;transform:translate(-50%,0)}
.toast.act{pointer-events:auto;display:flex;align-items:center;gap:14px;padding:6px 6px 6px 20px;text-align:left}
.toast button{background:var(--on-light);color:var(--ink);border:0;border-radius:var(--r-pill);min-height:36px;padding:0 16px;font-weight:700;flex:none}
.toast button:focus-visible{outline-color:var(--on-light)}
.toast a{display:inline-flex;align-items:center;background:var(--on-light);color:var(--ink);border-radius:var(--r-pill);min-height:36px;padding:0 16px;font-weight:700;text-decoration:none;flex:none}
.toast a:focus-visible{outline-color:var(--on-light)}

/* ==========================================================================
   App shell: one top bar for every surface.
   <header class="top"> brand · .grow (title or .top-nav) · .credits · .avatar
   .top is fixed (page pads by --top); .top.is-sticky stays in flow.
   .top-nav = section links; on phones they stay inline in the bar (scrolls under ~360px).
   ========================================================================== */
.top{position:fixed;top:0;left:0;right:0;z-index:60;height:var(--top);display:flex;align-items:center;gap:12px;padding:0 24px;background:var(--bg);border-bottom:1px solid var(--border)}   /* window edges, not the letterbox (Sasha, 26 Oct) */
/* 24px sides at every width = glu.tv's header (--container-pad) */
.top.is-sticky{position:sticky}
.theatre .top{background:var(--glass-strong);-webkit-backdrop-filter:blur(14px) saturate(1.2);backdrop-filter:blur(14px) saturate(1.2);border-bottom-color:var(--line-faint)}
.brand{display:flex;align-items:center;gap:10px;flex:none;text-decoration:none;font-weight:700;font-size:1rem;letter-spacing:-.005em;border-radius:var(--r-sm)}
.brand img{width:32px;height:32px;border-radius:8px;display:block}
.top .grow{flex:1;min-width:0;display:flex;justify-content:center;align-items:center}
.top .pg{font-weight:600;color:var(--ink-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.top-r{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex:none}
.top-l{display:flex;align-items:center;gap:12px;min-width:0}
/* with a section nav the bar is a true three-column grid, so the nav sits dead centre */
.top:has(.top-nav){display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr)}
.top:has(.top-nav)>:is(.brand,.top-l,.ph-l){justify-self:start}
.credits,.top-pill{flex:none;display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 14px;border-radius:var(--r-pill);background:var(--panel-2);border:1px solid var(--border-strong);font-weight:600;font-size:.86rem;white-space:nowrap;text-decoration:none;color:var(--ink);font-variant-numeric:tabular-nums;cursor:pointer;transition:border-color var(--dur-1),background-color var(--dur-1)}
.credits:hover,.top-pill:hover{border-color:var(--line-ctl-hi);background:var(--panel-3)}
.credits b{font-weight:700}
.credits.low{border-color:var(--signal);background:var(--signal-dim)}
.top-pill svg,.credits svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.top-pill[aria-expanded=true]{border-color:var(--signal)}
.dot{width:8px;height:8px;border-radius:50%;background:var(--signal);box-shadow:0 0 8px var(--signal-glow);flex:none}
.dot.warn{background:var(--ink-faint);box-shadow:none}
.avatar{flex:none;width:44px;height:44px;border-radius:50%;background:var(--panel-2);border:1px solid var(--border-strong);font-weight:700;display:grid;place-items:center;padding:0;transition:border-color var(--dur-1)}
.avatar:hover,.avatar[aria-expanded=true]{border-color:var(--signal)}
/* common header avatar (header.js): an initial on the profile colour once the account is known, else the person icon */
.top .avatar{color:var(--ink);cursor:pointer}
.top .avatar.has-i{color:var(--on-dark);border-color:transparent;font:400 1.1rem/1 var(--font-head);text-transform:uppercase;box-shadow:inset 0 0 0 1px rgba(255,255,255,.12)}
.top .avatar.has-i:hover,.top .avatar.has-i[aria-expanded=true]{box-shadow:0 0 0 2px var(--signal)}
/* section nav: centred pills on desktop */
.top-nav{display:flex;justify-content:center;gap:4px}
.top-nav a{display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:0 16px;border-radius:var(--r-pill);border:1px solid transparent;text-decoration:none;font-weight:600;font-size:.9375rem;color:var(--ink-dim);white-space:nowrap;transition:color var(--dur-1),background-color var(--dur-1),border-color var(--dur-1)}
.top-nav a:hover{color:var(--ink);background:var(--panel-2)}
.top-nav a[aria-current=page]{color:var(--ink);background:var(--signal-dim);border-color:var(--signal)}
/* current-state family: the same outline + fill wherever something is the current item (rule 8) */
.menu [role=menuitem][aria-current=page]{background:var(--signal-dim);box-shadow:inset 0 0 0 1px var(--signal)}
.top-nav svg{display:none;width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex:none}
/* [role=menuitem] twin: raises specificity above the later `.menu [role=menuitem]{display:flex}` so the phone-only and desktop-only items actually hide */
.menu .ph-only,.menu [role=menuitem].ph-only{display:none}
/* Header left = glu.tv's at every width: hamburger + wordmark (.ph-l), 16px apart (glu.tv .console-inner gap). The section name
   (.ph-title) is phone-only. On glu.tv at 1280: burger box x=24, "glu" x=80; at 390: burger box x=12.5 (icon on the 24px edge). */
.ph-l{display:flex;align-items:center;gap:var(--sp-4);min-width:0;flex:none}
.ph-title{display:none}
/* Hamburger and wordmark: copied from glu.tv (work/web/index.html .burger / .wm-*), on studio tokens. Outfit comes from the page's font link.
   The tv circle sits high so it centres on the "u", as on glu.tv (2px there, scaled to this 28px circle). */
.burger{width:40px;height:40px;border-radius:var(--r-pill);flex:none;display:flex;align-items:center;justify-content:center;background:none;border:0;padding:0;color:var(--ink);cursor:pointer;transition:background var(--dur-1) var(--ease)}
.burger:hover{background:var(--surface-2)}
.burger span{display:block;position:relative;width:17px;height:1.5px;background:var(--ink);border-radius:2px;transition:background var(--dur-1) var(--ease)}
.burger span::before,.burger span::after{content:'';position:absolute;left:0;width:17px;height:1.5px;background:var(--ink);border-radius:2px;transition:transform var(--nav-dur) var(--nav-ease),width var(--nav-dur) var(--nav-ease)}
.burger span::before{top:-5.5px}
.burger span::after{top:5.5px}
/* open: the burger morphs to an X (glu.tv body.nav-open .burger) */
body.nav-open .burger span{background:transparent}
body.nav-open .burger span::before{transform:translateY(5.5px) rotate(45deg)}
body.nav-open .burger span::after{transform:translateY(-5.5px) rotate(-45deg)}
/* phones: the 17px icon lines up with the 24px content edge, 19.5px from "glu" (glu.tv, max-width 767px); tap target stays 40px */
@media(max-width:767px){.burger{margin-left:-11.5px;margin-right:-8px}}
/* The studio wordmark (Sasha, 27 Oct): glu.tv's lockup ("glu" + the 32px magenta circle, circle 2px high) with a video camera
   outline in the circle instead of "tv". Header left at every width. */
.wm{display:inline-flex;align-items:center;flex:none;text-decoration:none;color:var(--ink);border-radius:var(--r-sm)}
.wm-glu{font-family:"Outfit","Inter",sans-serif;font-weight:800;font-size:1.5rem;letter-spacing:-.045em;color:var(--ink);line-height:1;position:relative;top:-2.63px;white-space:nowrap}   /* = glu.tv .wm-glu (24px, same optical offset) */
.wm-cam{width:32px;height:32px;border-radius:50%;background:var(--signal);display:inline-flex;align-items:center;justify-content:center;flex:none;position:relative;top:-2px;margin-left:4px;transition:box-shadow var(--dur-2) var(--ease-out)}
.wm-cam svg{width:21px;height:21px;fill:none;stroke:var(--on-light);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;display:block}
.wm:hover .wm-cam{box-shadow:0 0 24px 0 var(--signal-glow)}

@media(max-width:760px){
  /* Phones: no bottom tab bar. --tabbar stays 0px (set on :root above) so every page that offsets by it (footers, make bar, toasts,
     dock) needs no change. Top bar = hamburger + wordmark | section name | avatar. The section links live in the sidebar. */
  .top:has(.top-nav){grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:6px}
  .top>.grow{display:none}
  .ph-l{justify-self:start}
  .ph-title{display:block;max-width:100%;text-align:center;font-weight:600;font-size:.9375rem;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .top-r{margin-left:auto;gap:0;justify-self:end}
  .top-r #mine-pill{display:none}
  .top-r .credits{display:none}   /* phones: the balance is in the avatar menu (Sasha, 28 Oct: the text crowded the bar) */
  .avatar{width:44px;height:44px}
  .menu .ph-only,.menu [role=menuitem].ph-only{display:flex}
  .menu .dt-only,.menu [role=menuitem].dt-only{display:none}

}
/* below ~360px there is no room to centre the name: it takes the space between the wordmark and the avatar */
@media(max-width:359px){
  .top:has(.top-nav){grid-template-columns:auto minmax(0,1fr) auto}
}
/* ==========================================================================
   Left sidebar = glu.tv's #sidebar (work/web/index.html .sidebar / .chan / .side-label / .side-divider / .scrim), same
   geometry and behaviour; studio colour tokens. header.html markup, header.js setNav().
   > 960px: sits beside the content under the header and pushes it: body.nav-open animates --nav-w 0 -> 232px, the body pads by
     it and the full-width header pulls back over it. Anything fixed to the left edge offsets by var(--nav-w) (studio dock, bands).
   <= 960px: slides over the page from under the header, on a scrim; the page behind is inert (header.js). No scroll lock (glu.tv
     has none). Closed = width 0 (desktop) or off-canvas (phones), and inert either way.
   ========================================================================== */
@property --nav-w{syntax:'<length>';inherits:true;initial-value:0px}
:root{--sidebar-w:232px;--nav-w:0px;--nav-dur:260ms;--nav-ease:cubic-bezier(.65,0,.35,1)}   /* = glu.tv --sidebar-w, --dur-standard, --ease-in-out-apple */
.sidebar{position:fixed;top:var(--top);left:0;bottom:0;z-index:59;width:var(--sidebar-w);overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;padding:var(--sp-5) var(--sp-3) var(--sp-7);background:var(--bg);scrollbar-width:thin;scrollbar-color:var(--surface-3) transparent}
.sidebar::-webkit-scrollbar{width:5px}
.sidebar::-webkit-scrollbar-thumb{background:var(--surface-3);border-radius:99px}
.sidebar .chan{display:flex;align-items:center;gap:11px;width:100%;padding:9px 13px;border-radius:var(--r-pill);font-size:.9rem;line-height:1.55;color:var(--ink-dim);text-decoration:none;white-space:nowrap;transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease)}
.sidebar .chan:hover{background:var(--surface-2);color:var(--ink)}
.sidebar .chan:focus-visible{outline-offset:-2px}
/* current page: glu.tv's one magenta fill, no outline. The ONE documented exception to rule 8 (glu.tv parity, Sasha 27 Oct). */
.sidebar .chan[aria-current=page]{background:rgba(255,46,136,.22);color:var(--ink);font-weight:500}
.sidebar .chan svg{width:18px;height:18px;flex:none}
.sidebar .chan svg.sb-i{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.sidebar .chan svg.sb-b{fill:currentColor}
.sidebar .chan .ext{margin-left:auto;color:var(--ink-faint);font-size:.8rem}
.side-label{font-size:.733rem;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-dim);padding:0 var(--sp-3) 6px;white-space:nowrap;line-height:1.55}
.side-divider{border:0;border-top:1px solid var(--line-faint);margin:var(--sp-3) 10px}
.scrim{display:none;position:fixed;inset:0;z-index:58;background:var(--scrim);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);opacity:0;transition:opacity var(--nav-dur) var(--ease)}
@media(min-width:961px){
  body{transition:--nav-w var(--nav-dur) var(--nav-ease);padding-left:var(--nav-w)}
  body.nav-open{--nav-w:var(--sidebar-w)}
  body>.top{margin-left:calc(-1 * var(--nav-w))}   /* the header stays full width above the sidebar, as on glu.tv */
  .sidebar{transition:width var(--nav-dur) var(--nav-ease),opacity var(--dur-1) var(--ease),padding var(--nav-dur) var(--nav-ease)}
  body:not(.nav-open) .sidebar{width:0;padding-left:0;padding-right:0;opacity:0;overflow:hidden}
}
@media(max-width:960px){
  .sidebar{border-right:1px solid var(--line-faint);transform:translateX(-100%);transition:transform var(--nav-dur) var(--nav-ease)}
  body.nav-open .sidebar{transform:none}
  body.nav-open .scrim{display:block;opacity:1}
}
/* the remembered state is applied on load without animating (header.html boot script; header.js removes .nav-boot) */
body.nav-boot,body.nav-boot .sidebar,body.nav-boot .burger span,body.nav-boot .burger span::before,body.nav-boot .burger span::after{transition:none!important}
.menu .mcred b{font-weight:700;margin-right:.3em}
@media(max-width:600px){.credits,.top-pill{padding:0 11px}}
.top-pill .lab-sm{display:none}
@media(max-width:760px){.top-pill .lab{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}}

/* account menu: one compact popover anchored under the avatar, on desktop and phones alike (no sheet, no dimming) */
.menuback{position:fixed;inset:0;z-index:70;background:transparent}
.menu{position:fixed;z-index:71;top:calc(var(--top) + 2px);right:max(8px,env(safe-area-inset-right));width:min(272px,calc(100vw - 16px));max-height:calc(100dvh - var(--top) - 12px);overflow:auto;background:var(--surface-1);border:1px solid var(--line-faint);border-radius:var(--r-lg);padding:6px;box-shadow:var(--e-3);transform-origin:top right;animation:ds-menu var(--dur-2) var(--ease-out)}
@keyframes ds-menu{from{opacity:0;transform:scale(.96)}}
@media(prefers-reduced-motion:reduce){.menu{animation:none}}
.menu .mwho{display:flex;align-items:center;gap:12px;padding:10px 10px 12px;min-width:0}
.menu .mav{flex:none;width:36px;height:36px;border-radius:50%;display:grid;place-items:center;overflow:hidden;color:var(--on-dark);font:400 1.1rem/1 var(--font-head);text-transform:uppercase;background:var(--panel-2);box-shadow:inset 0 0 0 1px rgba(255,255,255,.12)}
.menu .mtxt{display:flex;flex-direction:column;gap:1px;min-width:0}
.menu .mwho b{color:var(--ink);font-weight:700;font-size:.9375rem;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.menu .mwho small{font-size:.75rem;color:var(--ink-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.menu .mprompt{margin:0;padding:10px 10px 8px;font-size:.8125rem;color:var(--ink-dim)}
.menu [role=menuitem]{display:flex;align-items:center;width:100%;min-height:44px;padding:0 12px;background:none;border:0;border-radius:var(--r-md);text-align:left;text-decoration:none;font:500 .9375rem/1.2 var(--font-ui);color:var(--ink);cursor:pointer}
.menu [role=menuitem]:hover,.menu [role=menuitem]:focus-visible{background:var(--surface-3)}
.menu [role=menuitem]:focus-visible{outline-offset:-2px}
.menu [role=menuitem][aria-current=page]{background:var(--signal-dim);box-shadow:inset 0 0 0 1px var(--signal);font-weight:700}
.menu .mcred{justify-content:space-between;margin-bottom:4px}
.menu .mpill{display:inline-flex;align-items:center;gap:8px;min-height:30px;padding:0 12px;border-radius:var(--r-pill);background:var(--panel-2);border:1px solid var(--line-faint);font-size:.8125rem;color:var(--ink-dim)}
.menu .mpill b{color:var(--ink);font-weight:700;margin:0 -.25em 0 0}
.menu .mpill .dot{width:8px;height:8px;border-radius:50%;background:var(--ink-faint);flex:none}
.menu .mpill.low{border-color:var(--signal);background:var(--signal-dim)}
.menu .mpill.low .dot,.menu .mpill.warn .dot{background:var(--signal)}
.menu .mgo{color:var(--ink-faint);font-size:1.25rem;line-height:1}
.menu .msign{color:var(--ink-dim)}
.menu hr{border:0;border-top:1px solid var(--line-faint);margin:4px 6px}
.menu .msign:hover,.menu .msign:focus-visible{color:var(--ink)}

/* ---------- page frame (account pages, manage) ---------- */
.page{max-width:960px;margin:0 auto;padding:calc(var(--top) + var(--page-top)) var(--gutter) 64px}
.page.wide{max-width:1240px}
.page>h1,.page .view>h1,.page .t-page{font-family:var(--font-head);font-weight:400;text-transform:uppercase;letter-spacing:.02em;line-height:var(--lh-tight);font-size:var(--fs-page);margin-bottom:10px;text-wrap:balance}
.page .lede{margin-bottom:24px}
.page>h2,.page .view>h2,.page .t-title{font-family:var(--font-head);font-weight:400;text-transform:uppercase;letter-spacing:.02em;line-height:1.05;font-size:var(--fs-title);margin:var(--sec-gap) 0 var(--sec-head-gap)}
.page a:not([class]){color:var(--ink);text-decoration-color:var(--border-strong)}
.page a:not([class]):hover{text-decoration-color:var(--signal)}

/* ---------- motion preference ---------- */
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto!important}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .btn:hover{transform:none}
}

/* Site footer (footer.html, synced by sync-header.py): same height, background and rule as the top bar, with its
   content held to the page's letterbox (the /studio .wrap width): glu links on the left, site links on the right.
   Class is .sitefoot, not .foot: .foot is /studio/create's fixed "Make my film" bar. */
.sitefoot{position:relative;z-index:1;background:var(--bg);border-top:1px solid var(--border);color:var(--ink-faint)}
.theatre .sitefoot{background:var(--bg);border-top-color:var(--line-faint)}
.sf-in{max-width:var(--page-max);min-height:var(--top);margin:0 auto;padding:0 var(--page-pad);display:flex;align-items:center;justify-content:space-between;gap:0 20px;flex-wrap:wrap}
.sf-nav{display:flex;align-items:center;flex-wrap:wrap;gap:0 4px}
.sf-l{margin-left:-12px}.sf-r{margin-inline:-12px}   /* text, not the link's hit area, lines up with the letterbox edge; .sf-r on both
   sides so that when it wraps under .sf-l its first link lines up with glu.tv above */
.sf-r{flex-wrap:nowrap}   /* About ... Privacy wraps as one unit, never link by link */
.sf-nav a{display:inline-flex;align-items:center;gap:.28em;min-height:44px;padding:0 12px;border-radius:var(--r-pill);text-decoration:none;font-weight:600;font-size:.875rem;color:var(--ink-dim);white-space:nowrap;transition:color var(--dur-1),background-color var(--dur-1)}
.sf-nav a:hover{color:var(--ink);background:var(--panel-2)}
@media(max-width:760px){
  .sf-in{padding-block:6px}
  .sf-nav a{padding:0 8px}
  .sf-l{margin-left:-8px}.sf-r{margin-inline:-8px}
}
/* /studio/create: the make bar is fixed only on phones (below 700px), where it would cover the footer, so lift the footer above it. From 700px up the
   Make my film control lives in the page's action row and there is nothing to clear. */
/* (the phone make bar is no longer fixed at the bottom: no space reserved for it) */
/* Footer at the bottom of a short page, straight after the content on a long one (not sticky, not fixed): the body becomes a
   min-height column and the footer's auto top margin takes up the slack. Block children keep their width (width:100% + their own
   max-width/auto margins), since auto side margins would otherwise shrink them inside a flex column. Sign-in (slim footer) is exempt. */
body:has(.sitefoot:not(.is-slim)){min-height:100vh;min-height:100dvh;display:flex;flex-direction:column}
body:has(.sitefoot:not(.is-slim))>*{min-width:0}
body:has(.sitefoot:not(.is-slim))>:is(main,.acct-wrap,.page){width:100%}
body:has(.sitefoot:not(.is-slim))>.sitefoot{margin-top:auto;flex:none}
/* sign-in: slim variant at the foot of the left column */
.sitefoot.is-slim{margin-top:auto;padding:12px 0 0;background:none}
.sitefoot.is-slim .sf-in{max-width:none;min-height:0;padding:0}
/* the mock-API badge (mock.js, local and preview only): one definition for every page */
.mockflag{position:fixed;left:10px;bottom:calc(var(--tabbar) + 10px);z-index:300;background:var(--warn);color:var(--on-light);font:700 .68rem/1 var(--font-ui);letter-spacing:.06em;text-transform:uppercase;padding:5px 9px;border-radius:var(--r-pill);opacity:.85;pointer-events:none}
b.glu{font:inherit!important;font-weight:600!important;text-transform:inherit;letter-spacing:inherit}   /* the word glu in running text (glu-word.js): same face and size as its sentence, semi-bold */

/* Link-style disclosures ("See the full prompt", "Smooth motion", "More options", Show the record…): a chevron after the label,
   down when closed and up when open (26 Oct). Covers every <details> summary and any link-styled button with aria-expanded,
   except the FAQ rows and controls that draw their own chevron (an <svg> inside). */
details:not(.faq)>summary{list-style:none}
details:not(.faq)>summary::-webkit-details-marker{display:none}
details:not(.faq)>summary:not(:has(svg))::after,
:is(.btn-link,.lnk,.link)[aria-expanded]:not(:has(svg))::after{content:"";display:inline-block;flex:none;width:7px;height:7px;margin-left:10px;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:translateY(-2px) rotate(45deg);transition:transform var(--dur-1,.15s) ease}
details:not(.faq)[open]>summary:not(:has(svg))::after,
:is(.btn-link,.lnk,.link)[aria-expanded=true]:not(:has(svg))::after{transform:translateY(2px) rotate(-135deg)}
@media (prefers-reduced-motion:reduce){details>summary::after,:is(.btn-link,.lnk,.link)[aria-expanded]::after{transition:none}}
/* The "this photo is mine" rights switch: same size and weight as the "Want more control?" line (not a bold label). */
.sw:has(input[data-consent]){font-weight:400;font-size:.9rem;color:var(--ink-dim)}
