/* glu.tv shared stylesheet: tokens, base type, content components, header, drawer, footer.

   ONE stylesheet for every page except the home family (home, tag pages, /all/, /shorts/),
   which keeps the same rules inline in index.html's <style> so its first screen paints
   without a render-blocking request (LCP). The two copies cannot drift silently:
   verify-seo.py check_mobile_css() fails the build when a token value here differs from
   index.html's :root, and on any ungated :hover, raw 100vh, input under 16px or text
   under 12px in either (work/scripts/css_guard.py).

   Generated pages get it from genpages.head() (no inline base copy any more); the
   hand-written pages get the <link> from sync-chrome.py. Page-specific rules stay inline
   on each page and load after this file, so they override it.

   Mobile-first, two breakpoints: base = phones, @media (min-width:640px) = tablets,
   @media (min-width:961px) = desktop (961, not 960: chrome.js and index.html switch the
   header at max-width:960px). Hover styles only ever inside @media (hover:hover).
   FUNC-SPEC.md "Shared stylesheet and mobile CSS guards" is the contract. */

/* ── 1. Tokens (values identical to index.html :root; the build checks) ────── */
:root{
  --bg:#0D0F14; --surface:#14161F; --surface-2:#1A1D28; --surface-3:#21242F; --line:#22252F;
  --line-soft:rgba(255,255,255,.055); --line-faint:rgba(255,255,255,.03);
  /* --ink-faint: 5.2:1 on --bg, 4.6:1 on --surface-2 (WCAG AA for text). Was #6B7080 (3.9:1). */
  --ink:#F0EDE8; --ink-dim:#9B9EA8; --ink-faint:#808596;
  --signal:#FF2E88; --signal-dim:rgba(255,46,136,.12); --signal-glow:rgba(255,46,136,.35);
  --warn:#E8B430; --danger:#FF6B6B;
  --c-films:#E06BB8; --c-worlds:#6B8AFF; --c-viral:#F0C245; --c-music:#9B7AFF;
  --c-ambient:#D69A63; --c-docs:#4DBA88; --c-space:#5AA8F0;
  --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; --sp-10:128px;
  --container-pad:var(--sp-5); --header-h:66px; --sidebar-w:232px;
  --r-pill:999px; --r-xl:22px; --r-lg:16px; --r-md:12px; --r-sm:9px;
  /* 12px floor for functional text (mobile audit C5/U13); body text is 16px everywhere. */
  --fs-2xs:.75rem; --fs-sm:.9rem; --fs-base:1rem;
  --dur-micro:140ms; --dur-standard:260ms;
  --ease:cubic-bezier(.22,.61,.36,1); --ease-out-apple:cubic-bezier(.16,1,.3,1);
  --ease-in-out-apple:cubic-bezier(.65,0,.35,1);
  color-scheme:dark;
}

/* ── 2. Base ─────────────────────────────────────────────────────────────── */
*{box-sizing:border-box}
html{background:var(--bg);-webkit-tap-highlight-color:transparent}
/* Belt and braces, AFTER the root fixes above (min-width:0, overflow-wrap): nothing may scroll the page sideways.
   clip, not hidden: hidden would make html/body a scroll container and break the sticky header. */
html,body{overflow-x:clip}
body{margin:0;background:var(--bg);color:var(--ink);font-family:Inter,system-ui,sans-serif;
  font-size:var(--fs-base);line-height:1.65;-webkit-font-smoothing:antialiased}
body::before{content:'';position:fixed;inset:0;z-index:0;pointer-events:none;
  background-image:repeating-linear-gradient(rgba(255,255,255,.014) 0 1px,transparent 1px 3px)}
a{color:inherit}
a,button,summary,label,input,select,textarea{touch-action:manipulation}
/* In-page anchors and focus targets land below the sticky header, not under it. */
[id]{scroll-margin-top:calc(var(--header-h) + var(--sp-3))}
/* Content pages sit left, on the header's edge: --container-pad, the same gutter as .console-inner (Sasha, 29 Oct).
   ONE container: main and .footer-inner are the same 1080px frame (same max-width, same left edge, so the same
   right edge), and the desktop header search ends on that frame's content edge. Everything inside spans it:
   paragraphs, lists, boxes (.method, .note), the ranked list, FAQ, rules, link rows, tables. There is no 720px
   prose cap any more (Sasha, 29 Oct: "inconsistent content containers"). Forms and inputs may be narrower inside.
   The frame shrinks with the window: main is a block, so below 1080px (+ the drawer's 232px push) it simply
   fills what is left; min-width:0 keeps a long unbroken word from ever widening it. */
main{position:relative;z-index:1;max-width:1080px;min-width:0;margin:0;padding:var(--sp-7) var(--container-pad) var(--sp-9)}
/* Long film titles (hashtag strings, URLs, CJK runs) wrap instead of widening the page. Zero specificity,
   so a page rule still wins. Flex/grid children default to min-width:auto, which is what let one long word
   push a rank row (and with it the page) wider than the window: let the text column shrink. */
main :where(h1,h2,h3,.ft,.fm,.why,.fw){overflow-wrap:anywhere}
main :where(.best,.ranked,.films,.flist){grid-template-columns:minmax(0,1fr)}
main :where(li > :not(img,svg,video)){min-width:0}
h1{font-family:Anton,sans-serif;text-transform:uppercase;font-size:clamp(1.8rem,4.6vw,2.9rem);
  line-height:1.02;letter-spacing:.01em;margin:0 0 var(--sp-4)}
.lede{font-size:1.15rem;color:var(--ink);margin:0 0 var(--sp-6);line-height:1.55}
h2{font-family:Outfit;font-weight:700;font-size:1.25rem;letter-spacing:-.01em;
  margin:var(--sp-7) 0 var(--sp-3)}
p{color:var(--ink-dim);margin:0 0 var(--sp-4)}
strong{color:var(--ink);font-weight:600}
.rule{border:0;border-top:1px solid var(--line-faint);margin:var(--sp-7) 0}
.gt{font-weight:600;letter-spacing:-.005em}
.semi{font-weight:600}

/* ── 3. Content components ───────────────────────────────────────────────── */
.note{font-size:.85rem;color:var(--ink-faint);border-left:2px solid var(--line-soft);
  padding-left:var(--sp-4);margin:var(--sp-5) 0}
.crumb{font-family:Outfit;font-weight:600;font-size:.78rem;letter-spacing:.04em;
  text-transform:uppercase;color:var(--ink-faint);margin:0 0 var(--sp-4)}
.crumb a{color:var(--ink-faint);text-decoration:none}
/* Page-body links that were 15-24px tall (breadcrumbs, "More from ..."): grow the
   hit area with padding and cancel it with margin, so the layout does not move. */
.crumb a,.onward a{display:inline-block;padding:10px 6px;margin:-10px -6px}
.pills{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 var(--sp-5);padding:0;list-style:none}
.pill{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:var(--r-pill);
  background:var(--surface-2);border:1px solid var(--line-soft);color:var(--ink-dim);
  font-family:Outfit;font-weight:600;font-size:.78rem;text-decoration:none}
.pill.hot{background:var(--signal);border-color:var(--signal);color:#0D0F14}
.credit-link{color:var(--ink);text-decoration:underline;text-decoration-color:var(--ink-faint);
  text-underline-offset:3px;font-weight:600}
.credit-link:focus-visible{color:var(--signal);text-decoration-color:var(--signal)}
/* A link inside running text is underlined, never told apart by colour alone
   (WCAG 1.4.1, review m1). Page CSS such as the creator hub's `.faq p a` sets
   text-decoration:none; this selector is more specific, so it wins. Classed links
   (pills, buttons, .credit-link) and the link rows (.onward, .crumb) keep their own look. */
main p:not(.onward):not(.crumb) a:not([class]){text-decoration-line:underline;text-underline-offset:3px}
@media (hover:hover){
  .crumb a:hover{color:var(--signal)}
  a.pill:hover{color:var(--signal);border-color:var(--signal)}
  .credit-link:hover{color:var(--signal);text-decoration-color:var(--signal)}
}

/* ── 4. Utilities ────────────────────────────────────────────────────────── */
html.glu-lock{overflow:hidden;scrollbar-gutter:stable}
.skip-link{position:absolute;left:10px;top:-60px;z-index:200;background:var(--signal);color:#0D0F14;
  font-weight:600;padding:10px 18px;border-radius:var(--r-pill);transition:top .18s var(--ease)}
.skip-link:focus{top:10px}
.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}
:focus-visible{outline:2px solid var(--signal);outline-offset:3px;border-radius:var(--r-sm)}

/* ── 5. Header bar. Same geometry as the home page: full width, --container-pad gutters. */
/* Phones and tablets get a solid bar: a backdrop-filter on a sticky header repaints
   on every scroll frame, which low-end Android pays for (mobile audit C17). */
.console{position:sticky;top:0;z-index:50;background:var(--bg);border-bottom:1px solid var(--line-faint)}
@media (min-width:961px){
  .console{background:rgba(13,15,20,.84);
    -webkit-backdrop-filter:blur(18px) saturate(1.35);backdrop-filter:blur(18px) saturate(1.35)}
}
.console-inner{display:flex;align-items:center;gap:var(--sp-4);height:var(--header-h);padding:0 var(--container-pad)}
/* Phones: the 17px icon sits centred in a 44px target; pull it out so the icon lines
   up with the content edge. */
.burger{width:44px;height:44px;border-radius:var(--r-pill);flex:none;display:flex;align-items:center;
  justify-content:center;padding:0;border:0;background:none;color:inherit;cursor:pointer;
  margin-left:-13.5px;margin-right:-10px;
  transition:background var(--dur-micro) var(--ease)}
@media (min-width:640px){.burger{margin-left:0;margin-right:0}}
.burger span{display:block;position:relative;width:17px;height:1.5px;background:var(--ink);border-radius:2px;
  transition:background var(--dur-micro) 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(--dur-standard) var(--ease-in-out-apple),width var(--dur-standard) var(--ease-in-out-apple)}
.burger span::before{top:-5.5px}
.burger span::after{top:5.5px}
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)}

.brand{display:inline-flex;align-items:center;flex:none;text-decoration:none;color:var(--ink);position:relative}
/* 44px-tall touch target for the 32px wordmark, nothing moves (final gate) */
.brand::after{content:"";position:absolute;left:0;right:0;top:-6px;bottom:-6px}
.wm-glu{font-family:Outfit,sans-serif;font-weight:800;font-size:1.5rem;letter-spacing:-.045em;color:var(--ink);
  line-height:1;position:relative;top:-2.63px}
.wm-tv{font-family:Outfit,sans-serif;font-weight:700;font-size:18px;line-height:1;letter-spacing:-.02em;
  background:var(--signal);color:#0D0F14;display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;border-radius:50%;flex:none;position:relative;top:-2px;
  padding:2.39px .92px 4.39px 2px;margin-left:4px;
  transition:box-shadow var(--dur-standard) var(--ease-out-apple),transform var(--dur-standard) var(--ease-out-apple)}
.wm-letters{display:block;transition:transform var(--dur-standard) var(--ease-out-apple),opacity var(--dur-standard) var(--ease-out-apple)}
.wm-play{position:absolute;inset:0;width:100%;height:100%;fill:#0D0F14;opacity:0;transform:rotate(90deg) scale(.55);
  transform-origin:50% 50%;pointer-events:none;
  transition:transform var(--dur-standard) var(--ease-out-apple),opacity var(--dur-standard) var(--ease-out-apple)}
.brand:focus-visible .wm-letters{opacity:0;transform:rotate(-90deg) scale(.55)}
.brand:focus-visible .wm-play{opacity:1;transform:rotate(0deg) scale(1)}
@media (prefers-reduced-motion:reduce){
  .wm-letters,.wm-play{transition-duration:1ms}
  .burger span,.burger span::before,.burger span::after,.searchbox,.skip-link{transition-duration:0s}
  .wm-play{transform:none}
}
.brand-sub{display:none;font-size:var(--fs-2xs);letter-spacing:.2em;text-transform:uppercase;color:var(--ink-dim);
  margin-left:var(--sp-3);padding-left:var(--sp-3);border-left:1px solid var(--line-faint);white-space:nowrap}
@media (min-width:961px){.brand-sub{display:inline}}

/* Search: 16px by default (below 16px iOS Safari zooms the page on focus and stays
   zoomed); the denser size only on a wide screen with a mouse, never on an iPad. */
.searchbox{flex:1 1 auto;min-width:0;max-width:460px;position:relative;display:flex;align-items:center;margin:0;
  transition:max-width var(--dur-standard) var(--ease-out-apple)}
.searchbox svg{position:absolute;left:15px;color:var(--ink-faint);pointer-events:none}
.searchbox input{width:100%;min-width:0;background:var(--surface);border:1px solid var(--ink-faint);color:var(--ink);
  border-radius:var(--r-pill);padding:11px 18px 11px 40px;font:inherit;font-size:16px;
  -webkit-appearance:none;appearance:none;
  transition:border-color var(--dur-standard) var(--ease),background var(--dur-standard) var(--ease),box-shadow var(--dur-standard) var(--ease)}
@media (min-width:961px) and (hover:hover) and (pointer:fine){.searchbox input{font-size:var(--fs-sm)}}
/* Desktop: the search fills the header, from the brand and tagline to the right gutter (--container-pad,
   from .console-inner). Nothing else sits on the right; the 460px cap stays on phones and tablets (Sasha, 29 Oct). */
@media (min-width:961px){.searchbox{max-width:none}}
/* Letterbox: the search ends where the content frame ends (main's content edge), never at the window edge.
   Frame right = push + min(1080px, 100% - push), minus the gutter; so the right padding is the gutter plus
   whatever the window has beyond push + 1080px. --nav-push is the drawer's push while it is open. */
@media (min-width:961px){
  .console-inner{padding-right:calc(var(--container-pad) + max(0px, 100% - var(--nav-push,0px) - 1080px));
    transition:padding-right var(--dur-standard) var(--ease-in-out-apple)}
  body.nav-open .console-inner{--nav-push:var(--sidebar-w)}
}
@media (prefers-reduced-motion:reduce){.console-inner{transition-duration:0s !important}}
.searchbox input::placeholder{color:var(--ink-faint)}
.searchbox input:focus{outline:none;background:var(--surface-2);border-color:rgba(255,46,136,.5);box-shadow:0 0 0 4px var(--signal-dim)}
.searchbox input::-webkit-search-cancel-button{-webkit-appearance:none}
.search-cancel{display:none}
/* The same 960px switch as chrome.js's matchMedia: focusing search collapses the bar. */
@media (max-width:960px){
  body.searching .console-inner > .burger,
  body.searching .console-inner > .brand,
  body.searching .console-inner > .brand-sub{display:none}
  body.searching .searchbox{max-width:none}
  body.searching .search-cancel{display:inline-flex;align-items:center;flex:none;background:none;border:0;
    min-height:44px;font-family:Outfit,sans-serif;font-size:var(--fs-sm);color:var(--ink-dim);
    padding:8px 2px 8px 14px;white-space:nowrap;cursor:pointer}
}

/* ── 6. Drawer: a flyout under the header on every width (the docked desktop sidebar
   belongs to the home/tag browse layout only). */
.scrim{display:none;position:fixed;inset:0;background:rgba(5,6,9,.6);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
  z-index:44;opacity:0;touch-action:none;transition:opacity var(--dur-standard) var(--ease)}
body.nav-open .scrim{display:block;opacity:1}
.chrome-drawer{position:fixed;top:var(--header-h);left:0;z-index:45;width:var(--sidebar-w);max-width:86vw;
  height:calc(100vh - var(--header-h));overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  padding:var(--sp-5) var(--sp-3) var(--sp-7);background:var(--bg);border-right:1px solid var(--line);
  transform:translateX(-100%);visibility:hidden;
  transition:transform var(--dur-standard) var(--ease-in-out-apple),visibility 0s linear var(--dur-standard)}
@supports (height:100dvh){.chrome-drawer{height:calc(100dvh - var(--header-h))}}
body.nav-open .chrome-drawer{transform:translateX(0);visibility:visible;transition-delay:0s}
/* Desktop (961px up, the same switch as index.html's docked sidebar): the open menu is docked,
   not a flyout. It pushes the page across by exactly the home sidebar's width (--sidebar-w) with
   the home sidebar's transition, and there is no scrim. Phones keep the overlay above. chrome.js
   remembers the state in localStorage 'glu-nav', the key index.html uses (open unless closed). */
@media (min-width:961px){
  body.nav-open .scrim{display:none}
  .chrome-drawer{border-right:0}
  /* Closed = nothing on screen, even mid-slide. The slide alone left a ghost strip of the drawer (its
     dividers and the 5px scrollbar thumb on its right edge) for most of the 260ms, so a screenshot or
     a slow frame showed a ~55px sliver. The home sidebar fades in 140ms (opacity) and clips its
     overflow when closed; the drawer does the same: it fades out first, and the scrollbar goes with
     the overflow. Open it is the home sidebar again: opaque, scrolling, same thumb. */
  .chrome-drawer{opacity:0;overflow-y:hidden;
    transition:transform var(--dur-standard) var(--ease-in-out-apple),opacity var(--dur-micro) var(--ease),visibility 0s linear var(--dur-standard)}
  body.nav-open .chrome-drawer{opacity:1;overflow-y:auto;transition-delay:0s}
  body > main,body > .site-footer{transition:margin-left var(--dur-standard) var(--ease-in-out-apple)}
  body.nav-open > main,body.nav-open > .site-footer{margin-left:var(--sidebar-w)}
}
@media (prefers-reduced-motion:reduce){
  .chrome-drawer,.scrim,body > main,body > .site-footer{transition-duration:0s !important;transition-delay:0s !important}
}
.chrome-drawer::-webkit-scrollbar{width:5px}
.chrome-drawer::-webkit-scrollbar-thumb{background:var(--surface-3);border-radius:99px}
.side-label{font-size:var(--fs-2xs);letter-spacing:.2em;text-transform:uppercase;color:#E6E7EA;
  padding:0 var(--sp-3) 6px;white-space:nowrap}
.side-divider{border:0;border-top:1px solid var(--line-faint);margin:var(--sp-3) 10px}
.chrome-drawer .chan{display:flex;align-items:center;gap:11px;padding:9px 13px;border-radius:var(--r-pill);
  font-size:var(--fs-sm);line-height:1.4;color:var(--ink-dim);width:100%;text-align:left;text-decoration:none;
  transition:background var(--dur-micro) var(--ease),color var(--dur-micro) var(--ease)}
/* 44px rows only where the drawer is an overlay for touch (same switch as the home sidebar, index.html: min-height at max-width:960px).
   The docked desktop menu keeps the home sidebar's natural 9px-padded rows, so open it reads row for row like home. */
@media (max-width:960px){.chrome-drawer .chan{min-height:44px}}
.chrome-drawer .chan .cdot{width:7px;height:7px;border-radius:50%;background:var(--dot,var(--ink-faint));flex:none}
.chrome-drawer .chan[aria-current="true"] .cdot{box-shadow:0 0 10px 1px var(--dot,transparent)}
.chrome-drawer .home-link span,.chrome-drawer .chan[data-chan="all"] span{text-transform:uppercase;letter-spacing:.04em}
.chrome-drawer .home-link{color:#E6E7EA}   /* menu headers (Home and the group labels): three quarters of the way from --ink-dim to white, so they read as headings (Sasha, 28 Oct) */

/* ── 7. Footer: four labelled groups (Explore, Creators, Studio, glu.tv), two by two on a phone. Links are 44px tall,
   32px only on a wide screen with a mouse (an iPad keeps 44px targets). */
.site-footer{border-top:1px solid var(--line-faint);margin-top:var(--sp-7)}
.footer-inner{max-width:1080px;margin:0;padding:var(--sp-5) var(--container-pad)}   /* fixed: 150% of the 720px reading column (Sasha, 28 Oct); left on the header's edge, like main (29 Oct) */
.footer-groups{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-5)}
@media (min-width:640px){.footer-groups{grid-template-columns:repeat(4,minmax(0,1fr))}}
.footer-group{display:flex;flex-direction:column;gap:0}
.footer-group-label{font-family:Outfit;font-weight:600;font-size:.78rem;letter-spacing:.04em;
  text-transform:uppercase;color:#CDCFD4;margin:0 0 var(--sp-2)}   /* same as the menu headers (Sasha, 28 Oct) */
.footer-group a{color:var(--ink-dim);font-size:.875rem;display:flex;align-items:center;min-height:44px;padding:0;text-decoration:none}
.footer-bottom{border-top:1px solid var(--line-faint);margin-top:var(--sp-6);
  padding-top:var(--sp-5);color:var(--ink-faint);font-size:.8rem}
@media (min-width:640px){.footer-inner{padding:var(--sp-6) var(--container-pad) var(--sp-5)}}
@media (min-width:961px) and (hover:hover) and (pointer:fine){.footer-group a{min-height:32px}}

/* ── 8. Hover: pointer devices only. A phone applies :hover on tap and keeps it. */
@media (hover:hover){
  .burger:hover{background:var(--surface-2)}
  .brand:hover .wm-tv{box-shadow:0 0 24px 0 var(--signal-glow)}
  .brand:hover .wm-letters{opacity:0;transform:rotate(-90deg) scale(.55)}
  .brand:hover .wm-play{opacity:1;transform:rotate(0deg) scale(1)}
  .searchbox input:hover{background:var(--surface-2)}
  .chrome-drawer .chan:hover{background:var(--surface-2);color:var(--ink)}
  .footer-group a:hover{color:var(--signal)}
}
@media (hover:hover) and (prefers-reduced-motion:reduce){
  .brand:hover .wm-letters,.brand:hover .wm-play{transform:none}
}
/* After the hover block on purpose: the current page keeps its magenta fill under the pointer. */
.chrome-drawer .chan[aria-current="true"]{background:rgba(255,46,136,.22);color:var(--ink);font-weight:500}
/* glu studio: the one drawer group in a softly tinted card with a 1px magenta edge (treatment C, Sasha, 28 Oct) */
.side-studio{margin:2px 0;padding:12px 6px 6px;border-radius:var(--r-lg);border:1px solid rgba(255,46,136,.34);
  background:linear-gradient(180deg,rgba(255,46,136,.085),rgba(255,46,136,.03) 70%)}
.side-studio .side-label{color:#FF8FBD}
.chrome-drawer .side-studio .studio-create{color:var(--ink)}
@media (hover:hover){.side-studio .chan:hover{background:rgba(255,255,255,.06)}}
