
  /* ============================================================
     Reeli — "Blockbuster aisle" retro theme.
     Navy + marquee gold, warm VHS-sleeve cream in light mode, a lit-up
     store-at-night navy in dark mode. --accent is always the blue (it's
     the contrast-critical token paired with --on-accent text, and
     blue/cream clears WCAG comfortably where gold/anything reliably
     doesn't) — gold lives in --gold/--gold-ink for marquee accents that
     don't need to host body text.
     ============================================================ */
  :root{
    --bg:#F4ECD8; --frame:#E9DEBE; --surface:#FFFBF1; --surface2:#EFE4C8;
    --ink:#152452; --muted:#4E5478; --line:#D8C89E;
    --accent:#123C82; --accent-soft:#DCE6F5; --on-accent:#FFF7E0;
    --gold:#F2B705; --gold-ink:#3A2A00;
    --good:#1B6B3A; --good-soft:#DCEEDD;
    --mid:#8A5A12;  --mid-soft:#F5E7C7;
    --bad:#A32020;  --bad-soft:#F7DCDC;
    --shadow:0 10px 26px rgba(21,36,82,.16);
    --pop:3px 3px 0 rgba(21,36,82,.9);
    --nav-bg:#0F1E4A; --nav-ink:#C9D3EE; --nav-cur:#F2B705;
    --display:"Futura","Futura PT","Avenir Next","Century Gothic","Trebuchet MS",system-ui,sans-serif;
    --body:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
    /* the VCR-clock digit face — every numeric readout (scores, stats, the
       matchup counter) uses this instead of --display, for the cassette-deck
       LED feel. Phosphor amber in dark mode, ink-on-paper in light. */
    --mono:"SF Mono","JetBrains Mono","Roboto Mono","Courier New",monospace;
    --phosphor:#123C82;
  }
  @media (prefers-color-scheme: dark){
    :root{
      --bg:#0B1226; --frame:#070B18; --surface:#131C3B; --surface2:#1A254A;
      --ink:#F1E8CE; --muted:#9AA3CC; --line:#2B3766;
      --accent:#F2B705; --accent-soft:#3A2E0C; --on-accent:#141018;
      --gold:#F2B705; --gold-ink:#171000;
      --good:#3FCB77; --good-soft:#122A1C;
      --mid:#F0A93C;  --mid-soft:#332310;
      --bad:#E8635C;  --bad-soft:#331515;
      --shadow:0 10px 30px rgba(0,0,0,.55);
      --pop:3px 3px 0 rgba(0,0,0,.6);
      --nav-bg:#080E24; --nav-ink:#8E9BCB; --nav-cur:#F2B705;
      --phosphor:#3FCB77;
    }
  }
  :root[data-theme="light"]{
    --bg:#F4ECD8; --frame:#E9DEBE; --surface:#FFFBF1; --surface2:#EFE4C8;
    --ink:#152452; --muted:#4E5478; --line:#D8C89E;
    --accent:#123C82; --accent-soft:#DCE6F5; --on-accent:#FFF7E0;
    --gold:#F2B705; --gold-ink:#3A2A00;
    --good:#1B6B3A; --good-soft:#DCEEDD;
    --mid:#8A5A12;  --mid-soft:#F5E7C7;
    --bad:#A32020;  --bad-soft:#F7DCDC;
    --shadow:0 10px 26px rgba(21,36,82,.16);
    --pop:3px 3px 0 rgba(21,36,82,.9);
    --nav-bg:#0F1E4A; --nav-ink:#C9D3EE; --nav-cur:#F2B705;
    --phosphor:#123C82;
  }
  :root[data-theme="dark"]{
    --bg:#0B1226; --frame:#070B18; --surface:#131C3B; --surface2:#1A254A;
    --ink:#F1E8CE; --muted:#9AA3CC; --line:#2B3766;
    --accent:#F2B705; --accent-soft:#3A2E0C; --on-accent:#141018;
    --gold:#F2B705; --gold-ink:#171000;
    --good:#3FCB77; --good-soft:#122A1C;
    --mid:#F0A93C;  --mid-soft:#332310;
    --bad:#E8635C;  --bad-soft:#331515;
    --shadow:0 10px 30px rgba(0,0,0,.55);
    --pop:3px 3px 0 rgba(0,0,0,.6);
    --nav-bg:#080E24; --nav-ink:#8E9BCB; --nav-cur:#F2B705;
  }
  :root, :root[data-theme="light"]{--wallshade:rgba(244,236,216,.93)}
  @media (prefers-color-scheme: dark){ :root{--wallshade:rgba(11,18,38,.92)} }
  :root[data-theme="dark"]{--wallshade:rgba(11,18,38,.92)}
  *{box-sizing:border-box}
  html,body{margin:0;padding:0}
  body{background:var(--frame);color:var(--ink);font-family:var(--body);-webkit-font-smoothing:antialiased}
  /* every interactive control already has its own pressed/:active look —
     without this, Android Chrome and older iOS Safari flash a grey box over
     whatever was tapped, on top of that */
  button,a,[tabindex]{-webkit-tap-highlight-color:transparent}
  button{font-family:inherit;color:inherit;background:none;border:none;padding:0;cursor:pointer}
  button:focus-visible,input:focus-visible,a:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
  input{font-family:inherit}
  /* Also kill scroll-behavior:smooth and any transform-based motion, not just
     animation/transition — vestibular triggers live in all three. */
  @media (prefers-reduced-motion: reduce){
    *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
    html{scroll-behavior:auto}
  }

  /* visible only to assistive tech: live-region text with no on-screen home */
  .sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
    clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
  /* the first thing Tab reaches, so keyboard users can jump the 5-item nav */
  .skip{position:absolute;left:8px;top:-60px;z-index:100;background:var(--gold);color:var(--gold-ink);
    padding:10px 16px;border-radius:0 0 10px 10px;font-size:14px;font-weight:700;text-decoration:none;
    transition:top .12s ease}
  .skip:focus{top:0}
  /* assertive counterpart to .toast: failures the user has to act on, and which
     must not vanish on a timer before they have read them */
  .alertbar{position:fixed;left:50%;transform:translateX(-50%);bottom:104px;z-index:61;
    max-width:min(432px,calc(100vw - 24px));display:flex;align-items:flex-start;gap:10px;
    background:var(--bad-soft);color:var(--bad);border:1px solid var(--bad);
    padding:11px 13px;border-radius:12px;font-size:13px;line-height:1.35;box-shadow:var(--shadow)}
  .alertbar[hidden]{display:none}
  .alertbar button{color:inherit;font-size:16px;line-height:1;flex:none;padding:1px 3px;opacity:.75}
  .alertbar button:hover{opacity:1}

  /* the aisle floor: a faint diagonal ticket-stripe wash behind everything,
     the closest thing to a "carpet pattern" a flat UI can get away with
     without hurting legibility. Pure gradients, no images. */
  .app{max-width:432px;margin:0 auto;min-height:100dvh;background:var(--bg);
    background-image:
      linear-gradient(var(--wallshade),var(--wallshade)),var(--wall,none),
      repeating-linear-gradient(-45deg, color-mix(in srgb, var(--ink) 3%, transparent) 0 2px, transparent 2px 26px);
    background-size:cover,cover,auto;
    background-position:center,center,center;
    background-attachment:fixed,fixed,fixed;
    display:flex;flex-direction:column;position:relative;
    border-left:1px solid var(--line);border-right:1px solid var(--line)}
  .avatar img{width:100%;height:100%;object-fit:cover;border-radius:50%}

  /* header: the marquee — bold navy-on-gold wordmark like the sign over the
     store's front doors */
  /* apple-mobile-web-app-status-bar-style is black-translucent (index.html),
     so the status bar overlays web content instead of pushing it down —
     without this top inset the logo would sit under the notch/status bar
     on an installed iOS home-screen app */
  .top{position:sticky;top:0;z-index:20;background:var(--nav-bg);border-bottom:3px solid var(--gold);
    padding:calc(14px + env(safe-area-inset-top)) 18px 12px;display:flex;align-items:center;justify-content:space-between}
  .logo{display:flex;align-items:center;gap:9px}
  .logo svg{display:block}
  .logo svg circle[stroke]{stroke:var(--gold)!important}
  .logo svg circle[fill]{fill:var(--gold)!important}
  .wordmark{font-family:var(--display);font-weight:800;font-size:22px;letter-spacing:1px;color:var(--gold);
    text-transform:uppercase;text-shadow:1px 1px 0 rgba(0,0,0,.35)}
  .screen-tag{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--nav-ink);font-weight:700;
    display:inline-flex;align-items:center;gap:6px}
  /* a REC light for whatever screen is live right now, camcorder-style —
     prefers-reduced-motion already forces every animation off globally
     (see the @media rule near the top), so this degrades to a static dot */
  .screen-tag::before{content:"";width:7px;height:7px;border-radius:50%;background:#ff4444;
    box-shadow:0 0 5px #ff4444;animation:rec 1.8s ease-in-out infinite}
  @keyframes rec{0%,100%{opacity:1}50%{opacity:.35}}
  .top .iconbtn{border-color:transparent;background:rgba(255,255,255,.08);color:var(--nav-ink)}

  /* screens */
  .screens{flex:1;padding:0 0 92px;position:relative;overflow-x:clip}
  .screen{display:none}
  .screen.on{display:block;animation:fade .18s ease}
  @keyframes fade{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
  /* tab-switch slide: "walking down the aisle" — both the outgoing and
     incoming screen are briefly stacked and absolutely positioned so they can
     pass each other, direction set in JS from the two tabs' left-to-right
     order in the bottom nav. Kept fast (nav() runs this on every tap) and it
     is animation-driven so prefers-reduced-motion's global `animation:none`
     kill-switch (top of file) turns it off for free — nav() also checks the
     same media query in JS so it skips the whole absolute-position dance
     rather than leaving a screen invisibly stuck mid-flight. */
  .screen.slide-out-l,.screen.slide-out-r,.screen.slide-in-l,.screen.slide-in-r{
    display:block;position:absolute;top:0;left:0;width:100%}
  .screen.on.slide-out-l{animation:slideOutL .19s ease both}
  .screen.on.slide-out-r{animation:slideOutR .19s ease both}
  .screen.on.slide-in-l{animation:slideInL .19s ease both}
  .screen.on.slide-in-r{animation:slideInR .19s ease both}
  @keyframes slideOutL{to{transform:translateX(-100%)}}
  @keyframes slideOutR{to{transform:translateX(100%)}}
  @keyframes slideInL{from{transform:translateX(-100%)}to{transform:none}}
  @keyframes slideInR{from{transform:translateX(100%)}to{transform:none}}
  /* the general-purpose "just arrived" entrance — chips, feed cards, stat
     tiles all use this so a re-rendered screen feels like it's being placed
     down rather than just appearing */
  @keyframes riseIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
  /* "stocked onto the shelf" entrance — search results, ranks rows, profile
     podium/franchise rows: slides in from the side with a slight rotation and
     a tiny overshoot before settling flat, reading as a VHS box being placed
     down rather than just a fade. Each row carries its own --i (its index in
     the list) via inline style so rows stagger in one after another; min()
     caps the stagger at the 20th row so a long list doesn't crawl in for
     seconds — everything past #20 still animates, just all at the #20 delay. */
  @keyframes shelfIn{
    0%{opacity:0;transform:translateX(-22px) rotate(-4deg)}
    55%{opacity:1;transform:translateX(3px) rotate(1deg)}
    100%{opacity:1;transform:none}
  }
  .shelf{animation:shelfIn .4s cubic-bezier(.22,.9,.32,1) both;
    animation-delay:calc(min(var(--i,0),20) * 40ms)}
  .pad{padding:16px 18px}
  .h1{font-family:var(--display);font-weight:800;font-size:24px;margin:4px 0 2px;text-wrap:balance;
    letter-spacing:.2px}
  .sub{color:var(--muted);font-size:13.5px;margin:0 0 14px;line-height:1.45}

  /* bottom nav: the store counter — a fixed navy bar, gold picks out whatever
     aisle you're standing in */
  .nav{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:432px;z-index:30;
    background:var(--nav-bg);border-top:3px solid var(--gold);
    display:grid;grid-template-columns:repeat(5,1fr);align-items:end;padding:6px 6px calc(8px + env(safe-area-inset-bottom))}
  .nav button{position:relative;display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 0;color:var(--nav-ink);font-size:10.5px;font-weight:700;letter-spacing:.03em;border-radius:10px;text-transform:uppercase;
    transition:color .15s ease}
  .badge{position:absolute;top:2px;left:calc(50% + 4px);background:var(--gold);color:var(--gold-ink);
    font-size:9.5px;font-weight:800;border-radius:999px;min-width:16px;height:16px;
    display:flex;align-items:center;justify-content:center;padding:0 4px;animation:badgeIn .25s cubic-bezier(.3,1.8,.4,1) both}
  .badge:empty{display:none}
  @keyframes badgeIn{from{transform:scale(0)}to{transform:scale(1)}}
  .nav button.cur{color:var(--nav-cur)}
  /* the current tab's icon gets the same pop the score reveal uses, instead
     of the label color just snapping over — a subtler cousin of scoreIn, tab
     switches happen far more often than a match result so the motion is kept
     small and quick */
  .nav button.cur svg{animation:tabPop .22s cubic-bezier(.3,1.8,.4,1) both}
  @keyframes tabPop{from{transform:scale(.8)}to{transform:scale(1)}}
  .nav svg{width:22px;height:22px;transition:transform .15s ease}
  .nav .plus{margin:-26px auto 0;width:54px;height:54px;border-radius:50%;background:var(--gold);color:var(--gold-ink);
    display:flex;align-items:center;justify-content:center;box-shadow:0 4px 0 rgba(0,0,0,.3),var(--shadow);padding:0;
    border:3px solid var(--nav-bg)}
  .nav .plus svg{width:26px;height:26px}

  /* posters: the VHS box — a bold spine stripe down the left edge, squarer
     corners than a plain poster card, a hard flat "sticker" shadow instead
     of a soft blur */
  .poster{border-radius:6px;display:flex;flex-direction:column;align-items:center;justify-content:center;
    color:#fff;flex:none;position:relative;overflow:hidden;text-shadow:0 1px 4px rgba(0,0,0,.45);
    box-shadow:var(--pop);border:1px solid rgba(0,0,0,.25)}
  .poster::before{content:"";position:absolute;left:0;top:0;bottom:0;width:6px;background:var(--gold);z-index:2}
  .poster::after{content:"";position:absolute;inset:0;background:
    linear-gradient(160deg,rgba(255,255,255,.22),rgba(255,255,255,0) 45%),
    linear-gradient(0deg,rgba(0,0,0,.32),rgba(0,0,0,0) 55%)}
  .poster .init{font-family:var(--display);font-weight:800;position:relative;z-index:1}
  .poster .pimg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:3;opacity:0;transition:opacity .25s ease}
  .poster .pimg.ld{opacity:1}
  .poster .yr{position:relative;z-index:1;font-size:8px;opacity:.9;letter-spacing:.1em}
  .p-xs{width:30px;height:42px;border-radius:4px}.p-xs .init{font-size:11px}.p-xs .yr{display:none}
  .p-sm{width:44px;height:62px}.p-sm .init{font-size:17px}
  .p-md{width:58px;height:82px}.p-md .init{font-size:21px}
  .p-lg{width:96px;height:136px;border-radius:8px}.p-lg .init{font-size:34px}.p-lg .yr{font-size:10px}

  /* score badge: a VCR counter readout welded onto a rental price tag —
     monospace digits with a faint phosphor glow, tabular so they don't
     jitter the ring width between scores, a hard sticker shadow */
  .score{width:42px;height:42px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;
    font-family:var(--mono);font-weight:700;font-size:13.5px;font-variant-numeric:tabular-nums;border:2.5px solid transparent;
    box-shadow:2px 2px 0 rgba(0,0,0,.14);text-shadow:0 0 6px color-mix(in srgb, currentColor 55%, transparent)}
  .s-good{background:var(--good-soft);color:var(--good);border-color:var(--good)}
  .s-mid{background:var(--mid-soft);color:var(--mid);border-color:var(--mid)}
  .s-bad{background:var(--bad-soft);color:var(--bad);border-color:var(--bad)}

  /* skeleton rows: "tuning in" — while search/trending waits on the network,
     row-shaped placeholders (same poster/text geometry as .row/.p-sm, so
     nothing shifts once real rows land) sweep with a diagonal static-band
     like a paused tape waiting to spin up. Same weight/palette as the REC
     dot and the .app aisle-floor stripe — a moving gradient, no JS loop, and
     it's animation-driven so prefers-reduced-motion turns it into a plain
     static placeholder for free. */
  .skel-row{display:flex;align-items:center;gap:12px;padding:11px 14px;border-bottom:1px solid var(--line)}
  .skel-row:last-child{border-bottom:none}
  .skel-poster{width:44px;height:62px;border-radius:6px;flex:none}
  .skel-meta{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px}
  .skel-line{height:10px;border-radius:5px;width:78%}
  .skel-line.sm{height:8px;width:42%}
  .skel-poster,.skel-line{
    background-image:repeating-linear-gradient(-45deg,
        color-mix(in srgb, var(--ink) 5%, var(--surface2)) 0 6px,
        var(--surface2) 6px 14px),
      linear-gradient(100deg, transparent 35%, color-mix(in srgb, var(--ink) 10%, transparent) 50%, transparent 65%);
    background-size:auto, 220% 100%;
    background-position:0 0, 120% 0;
    animation:skelSweep 1.5s ease-in-out infinite}
  @keyframes skelSweep{to{background-position:0 0, -20% 0}}

  /* list rows */
  .card{background:var(--surface);border:1px solid var(--line);border-radius:12px;overflow:hidden}
  .row{display:flex;align-items:center;gap:12px;padding:11px 14px;width:100%;text-align:left;border-bottom:1px solid var(--line);
    transition:background-color .15s ease}
  .row:active{background:var(--surface2)}
  .row:last-child{border-bottom:none}
  .row .meta{flex:1;min-width:0}
  .row .t{font-weight:650;font-size:14.5px;line-height:1.25;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .row .d{color:var(--muted);font-size:12px;margin-top:2px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .rankno{font-family:var(--mono);font-weight:700;font-size:12.5px;color:var(--muted);width:26px;flex:none;text-align:center;font-variant-numeric:tabular-nums}

  /* buttons: chunky, bordered, a hard offset shadow like a physical kiosk
     button — pressed :active state pushes it flat against its shadow */
  .pillbtn{border:1.5px solid var(--line);background:var(--surface);border-radius:999px;padding:7px 13px;font-size:12.5px;font-weight:700;flex:none;
    box-shadow:2px 2px 0 rgba(0,0,0,.08);transition:transform .08s ease,box-shadow .08s ease}
  .pillbtn:active{transform:translate(2px,2px);box-shadow:none}
  .pillbtn.acc{background:var(--accent);border-color:var(--accent);color:var(--on-accent);box-shadow:var(--pop)}
  .pillbtn.soft{background:var(--accent-soft);border-color:transparent;color:var(--accent);box-shadow:none}
  .iconbtn{width:34px;height:34px;border-radius:50%;border:1.5px solid var(--line);display:flex;align-items:center;justify-content:center;flex:none;color:var(--muted);background:var(--surface);
    transition:transform .1s ease,color .15s ease,border-color .15s ease,background-color .15s ease}
  .iconbtn.on{color:var(--accent);border-color:var(--accent);background:var(--accent-soft)}
  .iconbtn:active{transform:scale(.88)}

  /* segmented filter */
  .segs{display:flex;gap:8px;margin:0 0 14px;flex-wrap:wrap}
  /* min-height, not just padding — the ~44px floor is the actual iOS/Android
     tap-target guideline, and padding alone drifts with font metrics.
     .seg.sm (the secondary genre-filter row) opts out: it's a dense,
     lower-stakes refinement row, not a primary control. */
  .seg{border:1.5px solid var(--line);background:var(--surface);border-radius:999px;padding:0 14px;min-height:44px;
    display:inline-flex;align-items:center;justify-content:center;font-size:12.5px;font-weight:700;color:var(--muted);
    text-transform:uppercase;letter-spacing:.02em;
    transition:transform .1s ease,background-color .15s ease,color .15s ease,border-color .15s ease}
  .seg.sm{min-height:0;padding:5px 11px;font-size:11.5px;text-transform:none;letter-spacing:normal}
  .seg.cur{background:var(--nav-bg);color:var(--gold);border-color:var(--nav-bg)}
  .seg:active{transform:scale(.96)}

  /* search */
  .searchbar{display:flex;align-items:center;gap:10px;background:var(--surface);border:1.5px solid var(--line);
    border-radius:12px;padding:11px 14px;margin-bottom:14px}
  .searchbar svg{color:var(--muted);flex:none}
  /* `outline:none` here used to remove the only focus indicator the two
     search fields had, so keyboard users lost the caret's position entirely. The ring
     moves to the wrapper instead, which is what the field visually is. */
  /* 16px, not 15 — iOS Safari zooms the whole page in on focus for any text
     input under 16px, and doesn't zoom back out on blur. Same reasoning on
     .field below and the three inline custom-add inputs in app.js. */
  .searchbar input{border:none;outline:none;background:transparent;color:var(--ink);font-size:16px;width:100%}
  .searchbar:focus-within{outline:2px solid var(--accent);outline-offset:2px}
  .searchbar input::placeholder{color:var(--muted)}

  /* feed */
  .fgrid{display:grid;grid-template-columns:1fr;gap:12px}
  .fitem{background:var(--surface);border:1.5px solid var(--line);border-radius:12px;padding:14px;animation:riseIn .32s ease both}
  .fhead{display:flex;align-items:center;gap:10px;margin-bottom:10px}
  .avatar{width:36px;height:36px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;
    color:#fff;font-weight:800;font-size:13px;font-family:var(--display)}
  .fwho{flex:1;min-width:0;font-size:13.5px;line-height:1.35}
  .fwho b{font-weight:700}
  .ftime{color:var(--muted);font-size:11.5px}
  .fbody{display:flex;gap:12px;align-items:center;background:var(--surface2);border-radius:10px;padding:10px 12px}
  .fbody .meta{flex:1;min-width:0}
  .fnote{color:var(--muted);font-size:12.5px;font-style:italic;margin-top:6px;line-height:1.4}
  .facts{display:flex;gap:14px;margin-top:10px}
  .facts button{display:flex;align-items:center;gap:5px;color:var(--muted);font-size:12px;font-weight:700}
  .facts button.liked{color:var(--bad)}
  .facts button.disliked{color:var(--ink)}
  /* the hot-take follow button reuses .iconbtn (same on/off treatment as the
     watchlist bookmark) but at 26px, not the standalone 34px — a hot-take
     row is already three controls deep (like, dislike, follow) so the full
     size would crowd it; 26px still gives it a real hit box of its own,
     unlike the borderless like/dislike icons beside it, since unlike those
     it's a state change with a network round trip, not just a local toggle */
  .facts .iconbtn{width:26px;height:26px;font-size:13px;font-weight:800;flex:none}

  /* debate threads: a hot take's replies, collapsed under it by default. The
     dashed rule (rather than another solid .card border) reads as "still part
     of this note", not a new section — the sechead treatment is reserved for
     real screen sections. Each reply is a shrunk-down echo of the take row
     it's nested under: small avatar, name, body, no facts row of its own —
     replies aren't themselves re-repliable. */
  .tkreplies{margin-top:8px;padding-top:8px;border-top:1.5px dashed var(--line);animation:riseIn .2s ease both}
  .tkreplies[hidden]{display:none}
  .tkreply{display:flex;gap:8px;align-items:flex-start;padding:5px 0}
  .tkreply .meta{flex:1;min-width:0}
  .tkreply .t{font-weight:700;display:block}
  .tkreply .d{margin-top:1px}
  .tkreply-form{display:flex;gap:8px;align-items:flex-end;margin-top:8px}
  /* 16px, not smaller — same iOS Safari zoom-on-focus reasoning as .field and
     .searchbar input above: anything under 16px zooms the page in on focus
     and never zooms back out */
  .tkreply-form textarea{resize:vertical;min-height:44px;max-height:120px;font-size:16px;padding:8px 10px;line-height:1.4}
  .tkreply-form .pillbtn{flex:none}

  /* profile */
  .phead{display:flex;align-items:center;gap:14px;margin-bottom:16px}
  .phead .avatar{width:58px;height:58px;font-size:20px}
  .pname{font-family:var(--display);font-weight:800;font-size:20px}
  .phandle{color:var(--muted);font-size:13px}

  /* profile header, laminated as a video-store membership card. Same
     navy-card/gold-label vocabulary as .wrapcard/.wraplabel below (this is
     the second "screenshot-shaped" surface in the profile, so it deliberately
     matches rather than differentiates) plus a cheap diagonal "laminate sheen"
     — one gradient layer, no extra markup — for the plastic-card read. */
  .memcard{position:relative;overflow:hidden;background:var(--nav-bg);border-radius:16px;padding:16px 18px 14px;
    box-shadow:var(--pop);border:1.5px solid var(--line);margin-bottom:16px;animation:riseIn .3s ease both}
  .memcard::before{content:"";position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(115deg,rgba(255,255,255,.14) 0%,rgba(255,255,255,0) 22%,rgba(255,255,255,0) 68%,rgba(255,255,255,.08) 100%)}
  .memcard-top{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:14px;position:relative}
  .memcard-top .iconbtn{border-color:transparent;background:rgba(255,255,255,.08);color:var(--nav-ink)}
  .memcard-top .pillbtn{background:transparent;border-color:var(--nav-ink);color:var(--nav-ink)}
  .memcard-body{display:flex;align-items:center;gap:14px;margin-bottom:14px;position:relative}
  .memcard-body .pname{color:var(--gold)}
  .memcard-body .phandle{color:var(--nav-ink)}
  .memcard-fields{display:flex;gap:22px;flex-wrap:wrap;padding-top:12px;border-top:1px dashed rgba(201,211,238,.3);position:relative}
  .memfield{display:flex;flex-direction:column;gap:3px}
  .memlbl{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--nav-ink);opacity:.75}
  .memval{font-family:var(--mono);font-weight:700;font-size:13px;letter-spacing:.03em;color:var(--gold);font-variant-numeric:tabular-nums}
  /* minmax(0,1fr), not bare 1fr — a bare 1fr track still has an implicit
     auto minimum, so a stat's content (the number + label) can force the
     grid wider than its container instead of the columns shrinking to fit,
     overflowing the screen horizontally on the narrowest phones */
  .stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-bottom:16px}
  .stat{background:var(--surface);border:1.5px solid var(--line);border-radius:12px;padding:12px 10px;text-align:center;box-shadow:2px 2px 0 rgba(0,0,0,.06);animation:riseIn .3s ease both}
  .stat .n{font-family:var(--mono);font-weight:700;font-size:20px;font-variant-numeric:tabular-nums;color:var(--phosphor);
    text-shadow:0 0 8px color-mix(in srgb, var(--phosphor) 45%, transparent)}
  .stat .l{color:var(--muted);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;font-weight:700;margin-top:3px}
  .distrow{display:flex;align-items:center;gap:10px;margin-bottom:8px;font-size:12.5px}
  .distrow .lbl{width:74px;color:var(--muted);font-weight:700;flex:none}
  .distrow .bar{flex:1;height:10px;border-radius:6px;background:var(--surface2);overflow:hidden}
  .distrow .fill{display:block;height:100%;border-radius:6px}
  .distrow .cnt{width:22px;text-align:right;font-variant-numeric:tabular-nums;color:var(--muted);flex:none}
  .chips{display:flex;gap:8px;flex-wrap:wrap}
  .chip{background:var(--surface);border:1.5px solid var(--line);border-radius:999px;padding:6px 12px;font-size:12px;font-weight:700;color:var(--muted);
    animation:riseIn .3s ease both}
  /* GitHub-style ranking activity calendar: 7 rows (Sun-Sat) laid out one week
     per column via grid-auto-flow, so it reads top-to-bottom/left-to-right the
     same way the real calendar does. A year's worth of days is wider than any
     phone, so the wrapper scrolls horizontally instead of squeezing cells down
     to unreadable slivers or shrinking the whole grid off its calendar grid. */
  .heatwrap{overflow-x:auto}
  .heatgrid{display:grid;grid-template-rows:repeat(7,9px);grid-auto-flow:column;grid-auto-columns:9px;gap:3px;width:max-content}
  .heatgrid > div{border-radius:2px}

  /* yearly wrap-up: a cassette-label "REWIND" framing — the one profile
     section explicitly meant to be screenshotted/shared, so it leans harder
     into the retro-VHS identity than the rest of the profile does. Every
     colour below is an existing token (--gold/--gold-ink/--nav-bg/--nav-ink/
     --pop/--line), nothing new. */
  .wraplabel{font-family:var(--mono);font-weight:700;font-size:10.5px;letter-spacing:.2em;color:var(--gold-ink);
    background:var(--gold);display:inline-block;padding:4px 10px;border-radius:4px;box-shadow:var(--pop)}
  .wrapcard{display:block;width:100%;text-align:left;background:var(--nav-bg);border-radius:14px;padding:16px 18px;
    box-shadow:var(--pop);border:1.5px solid var(--line);animation:riseIn .3s ease both;
    transition:transform .1s ease,box-shadow .1s ease}
  .wrapcard:active{transform:translate(2px,2px);box-shadow:none}
  .wrapcard .wraplabel{margin-bottom:9px}
  .wrapcard .wc-title{display:block;font-family:var(--display);font-weight:800;font-size:17px;color:var(--gold)}
  .wrapcard .wc-sub{display:block;color:var(--nav-ink);font-size:12px;margin-top:4px}
  @media (hover:hover){ .wrapcard:hover{border-color:var(--gold)} }
  .danger{color:var(--bad);font-weight:700;font-size:13px;margin-top:18px}
  /* Ranks screen: a close call worth a rematch, in the same amber "not sure
     yet" tone the fine-bucket dot already uses elsewhere */
  .tiebreak{display:flex;align-items:center;gap:12px;padding:12px 14px;margin-bottom:14px;
    border-radius:12px;border:1.5px solid var(--mid);background:var(--mid-soft)}
  .tiebreak p{flex:1;margin:0;font-size:13px;line-height:1.45;color:var(--ink)}
  .tiebreak b{color:var(--mid)}
  .tiebreak .tbbtns{display:flex;align-items:center;gap:6px;flex:none}

  .empty{text-align:center;padding:44px 24px;color:var(--muted)}
  .empty .big{font-size:34px;margin-bottom:10px}
  .empty p{font-size:13.5px;line-height:1.5;margin:0 0 16px}
  /* section headers read like a shelf-talker label: small, bold, uppercase,
     a short gold underline instead of plain text */
  .sechead{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);font-weight:800;
    margin:20px 2px 8px;position:relative;display:inline-block;padding-bottom:4px}
  .sechead::after{content:"";position:absolute;left:0;bottom:0;width:22px;height:3px;background:var(--gold);border-radius:2px}

  /* overlay / sheets */
  .overlay{position:fixed;inset:0;z-index:50;background:rgba(8,12,28,.6);display:none;align-items:flex-end;justify-content:center}
  .overlay.on{display:flex;animation:fade .15s ease}
  .sheet{width:100%;max-width:432px;background:var(--bg);border-radius:16px 16px 0 0;padding:20px 20px calc(22px + env(safe-area-inset-bottom));
    max-height:88dvh;overflow-y:auto;animation:up .22s ease;border-top:4px solid var(--gold)}
  @keyframes up{from{transform:translateY(28px);opacity:.6}to{transform:none;opacity:1}}
  /* exit mirrors the entrance (up/fade played backwards) — closeSheet() in
     app.js adds .closing and holds the DOM in place for this animation's
     duration before actually tearing the sheet down, so a dismiss reads as
     the box sliding back off the shelf instead of just vanishing */
  .overlay.closing{animation:fade .18s ease reverse both}
  .overlay.closing .sheet:not(.full){animation:up .18s ease reverse both}
  .grab{width:40px;height:4px;border-radius:2px;background:var(--line);margin:0 auto 16px}
  .sheet .h1{font-size:20px}

  /* full-screen profile view: same #sheet element, just filling the viewport
     instead of drawing a bottom drawer. .sheet.full has higher specificity
     than every plain .sheet rule above (and the desktop one below), so it
     always wins regardless of source order or viewport width. */
  .sheet.full{max-width:none;width:100%;height:100dvh;min-height:100dvh;max-height:100dvh;
    border-radius:0;padding:0;margin:0;animation:none;overflow-y:auto;border-top:none}
  .fullprofile{min-height:100dvh;padding:20px 20px calc(20px + env(safe-area-inset-bottom));
    background-color:var(--bg);background-size:cover;background-position:center top}
  .fullhead{display:flex;justify-content:flex-end;margin-bottom:12px}

  /* milestone celebrations: first ranking / 50th / one-year anniversary.
     Same .fullprofile shell as the full profile and yearly wrap-up, plus a
     confetti burst confined to the top of the screen and a scoreIn-style pop
     on the headline — the one place besides the result sheet that earns a
     bigger entrance than riseIn's quiet fade. */
  .milestone{position:relative;overflow:hidden}
  .milestone .h1{animation:scoreIn .4s cubic-bezier(.2,1.6,.4,1) both}
  .milestone .sub{color:var(--muted);font-size:13.5px;line-height:1.5;margin:8px 0 0}
  .milestone .stats{margin-top:18px}
  .confetti{position:absolute;left:0;right:0;top:0;height:200px;overflow:hidden;pointer-events:none}
  .confetti-piece{position:absolute;top:-16px;width:7px;height:13px;border-radius:2px;opacity:.9;
    animation-name:confettiFall;animation-timing-function:ease-in;animation-fill-mode:forwards}
  @keyframes confettiFall{from{transform:translateY(0) rotate(0deg);opacity:.95}to{transform:translateY(360px) rotate(300deg);opacity:0}}
  @media (prefers-reduced-motion:reduce){
    .confetti-piece{animation:none;opacity:0}
    .milestone .h1{animation:none}
  }

  /* rate flow */
  .buckets{display:grid;gap:10px;margin-top:14px}
  .bucket{display:flex;align-items:center;gap:12px;border-radius:12px;padding:14px;border:1.5px solid var(--line);background:var(--surface);text-align:left;
    transition:transform .1s ease,border-color .15s ease}
  .bucket:active{transform:scale(.98)}
  .bucket .dot{width:34px;height:34px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center}
  .bucket b{font-size:15px;display:block}
  .bucket span{color:var(--muted);font-size:12px}
  .faceoff{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:8px;margin:18px 0 14px}
  .contender{background:var(--surface);border:1.5px solid var(--line);border-radius:12px;padding:14px 10px;display:flex;flex-direction:column;align-items:center;gap:9px;text-align:center;transition:transform .1s ease}
  .contender:active{transform:scale(.97)}
  .contender .t{font-weight:650;font-size:13px;line-height:1.3}
  .contender .d{color:var(--muted);font-size:11px}
  /* a tape-reel hub instead of a plain badge — dashed ring reads as sprocket
     teeth at this size */
  .vs{font-family:var(--display);font-weight:800;color:var(--gold-ink);background:var(--gold);border-radius:50%;
    width:28px;height:28px;display:flex;align-items:center;justify-content:center;font-size:11px;
    border:2px dashed var(--gold-ink)}
  .tiebtn{display:block;margin:0 auto;color:var(--muted);font-size:13px;font-weight:600;text-decoration:underline;text-underline-offset:3px}
  .result{display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;padding:8px 0 4px}
  /* the payoff moment — every other reveal in the app is a quiet fade, this
     one gets to pop */
  .result .bigscore{width:84px;height:84px;font-size:28px;animation:scoreIn .38s cubic-bezier(.2,1.6,.4,1) both}
  @keyframes scoreIn{from{opacity:0;transform:scale(.4) rotate(-8deg)}to{opacity:1;transform:none}}
  .result h2{font-family:var(--display);font-size:22px;margin:0;text-wrap:balance}
  .result p{color:var(--muted);font-size:13.5px;margin:0;line-height:1.5}
  .step{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:700;text-align:center}

  /* detail sheet */
  .dhead{display:flex;gap:16px;align-items:flex-start;margin-bottom:16px}
  .dhead .meta{flex:1;min-width:0;padding-top:6px}
  .dhead h2{font-family:var(--display);font-size:21px;margin:0 0 4px;line-height:1.2;text-wrap:balance}
  .dhead .d{color:var(--muted);font-size:13px;line-height:1.5}
  .dactions{display:flex;gap:9px;flex-wrap:wrap;margin-top:6px}
  /* a changed number gets a brief gold flash-and-settle instead of just
     silently being different — the rewatch counter (logged another watch)
     wraps its digit in this on every re-render, and since the detail sheet
     is rebuilt via innerHTML each time, the freshly-inserted span replays it
     for free */
  .pulse{display:inline-block;animation:pulseHi .5s cubic-bezier(.2,1.6,.4,1) both}
  @keyframes pulseHi{0%{transform:scale(1.7);color:var(--gold)}100%{transform:scale(1);color:inherit}}

  .toast{position:fixed;left:50%;transform:translateX(-50%) translateY(8px);bottom:104px;z-index:60;background:var(--nav-bg);color:var(--gold);
    padding:10px 18px;border-radius:999px;font-size:13px;font-weight:700;box-shadow:var(--shadow);opacity:0;pointer-events:none;
    transition:opacity .2s ease,transform .2s ease}
  .toast.on{opacity:1;transform:translateX(-50%) translateY(0)}

  /* auth / onboarding */
  .auth{position:absolute;inset:0;z-index:40;background:var(--bg);overflow-y:auto;display:none;padding:38px 26px 40px}
  .auth.on{display:block;animation:fade .25s ease}
  .auth .hero{display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;margin-bottom:26px}
  .auth .hero .wordmark{font-size:34px;color:var(--accent);text-shadow:none}
  .auth .tagline{font-size:15px;color:var(--muted);line-height:1.5;max-width:30ch;text-wrap:balance;margin:0}
  .feat{display:flex;gap:10px;align-items:flex-start;font-size:13px;color:var(--muted);line-height:1.45}
  .feat b{color:var(--ink)}
  .feat .fdot{width:26px;height:26px;border-radius:8px;background:var(--accent-soft);color:var(--accent);
    display:flex;align-items:center;justify-content:center;flex:none;font-size:13px}
  .feats{display:grid;gap:12px;margin:0 auto 26px;max-width:320px}
  .field{width:100%;padding:12px 14px;border-radius:10px;border:1.5px solid var(--line);background:var(--surface);color:var(--ink);font-size:16px}
  .authcard{background:var(--surface);border:1.5px solid var(--line);border-radius:14px;padding:18px;display:grid;gap:10px;max-width:360px;margin:0 auto}
  .socialbtn{display:flex;align-items:center;justify-content:center;gap:9px;border:1.5px solid var(--line);background:var(--surface2);
    border-radius:10px;padding:11px;font-size:14px;font-weight:700}
  .socialbtn .mark{font-family:var(--display);font-weight:700;width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;color:#fff}
  .socialbtn.picked{border-color:var(--accent);background:var(--accent-soft)}
  .ordiv{display:flex;align-items:center;gap:12px;color:var(--muted);font-size:11px;letter-spacing:.12em;text-transform:uppercase;font-weight:700}
  .ordiv::before,.ordiv::after{content:"";flex:1;height:1px;background:var(--line)}
  .swatches{display:flex;gap:9px;justify-content:center;padding:2px 0}
  .swatch{width:30px;height:30px;border-radius:50%;border:2px solid transparent;transition:transform .12s ease,border-color .15s ease}
  .swatch:active{transform:scale(.85)}
  .swatch.cur{border-color:var(--ink)}
  .authnote{text-align:center;color:var(--muted);font-size:11.5px;line-height:1.5;max-width:340px;margin:14px auto 0}
  .ghostlink{display:block;margin:14px auto 0;color:var(--muted);font-size:13px;font-weight:600;text-decoration:underline;text-underline-offset:3px}

  /* onboarding taste picker */
  .chipgrid{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 4px}
  .chippick{border:1.5px solid var(--line);border-radius:999px;padding:8px 14px;font-size:13px;font-weight:700;background:var(--surface);color:var(--muted);
    transition:transform .1s ease,background-color .15s ease,border-color .15s ease,color .15s ease}
  .chippick:active{transform:scale(.95)}
  .chippick.sel{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
  .pickgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:14px 0 4px}
  .pcard{border:2px solid var(--line);border-radius:10px;padding:8px 6px;display:flex;flex-direction:column;align-items:center;gap:6px;background:var(--surface);position:relative;
    transition:transform .1s ease,border-color .15s ease,background-color .15s ease}
  .pcard:active{transform:scale(.96)}
  .pcard.sel{border-color:var(--accent);background:var(--accent-soft)}
  .pcard.sel::after{content:"✓";position:absolute;top:6px;right:8px;width:20px;height:20px;border-radius:50%;
    background:var(--gold);color:var(--gold-ink);font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center}
  .pcard .pt{font-size:11px;line-height:1.25;text-align:center;font-weight:600;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .obdots{display:flex;gap:6px;justify-content:center;margin-top:16px}
  .obdots span{width:6px;height:6px;border-radius:50%;background:var(--line)}
  .obdots .on{background:var(--gold)}
  .obfoot{display:flex;gap:9px;justify-content:center;margin-top:16px;flex-wrap:wrap}

  /* reelmates */
  .match{font-family:var(--display);font-weight:800;font-size:13px;color:var(--accent);background:var(--accent-soft);
    border-radius:999px;padding:5px 10px;flex:none;font-variant-numeric:tabular-nums}
  .matchring{width:74px;height:74px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex:none;
    font-family:var(--display);font-weight:800;font-size:17px;color:var(--accent);
    background:conic-gradient(var(--gold) calc(var(--pct)*1%), var(--line) 0);position:relative;
    animation:ringIn .5s cubic-bezier(.2,1.4,.4,1) both}
  @keyframes ringIn{from{opacity:0;transform:scale(.6) rotate(-90deg)}to{opacity:1;transform:none}}
  .matchring::before{content:"";position:absolute;inset:6px;border-radius:50%;background:var(--surface)}
  .matchring span{position:relative}
  .bothrow{display:grid;grid-template-columns:auto 1fr auto auto;gap:10px;align-items:center;padding:9px 0;border-bottom:1px solid var(--line);font-size:13.5px}
  .bothrow .t{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .bothrow:last-child{border-bottom:none}
  .bothrow .sc{width:34px;height:34px;font-size:12px}

  /* hover affordances for mouse users */
  @media (hover:hover){
    .row:hover{background:var(--surface2)}
    .fitem:hover,.bucket:hover{border-color:var(--accent)}
    .contender:hover{border-color:var(--accent);transform:translateY(-2px)}
    .pillbtn:hover{border-color:var(--accent)}
    .pillbtn.acc:hover{filter:brightness(1.08)}
    .iconbtn:hover{color:var(--accent);border-color:var(--accent)}
    .seg:hover{border-color:var(--accent)}
    .nav button:hover{color:var(--gold)}
  }
  .kbdhint{display:none;text-align:center;color:var(--muted);font-size:11.5px;margin-top:12px}
  .kbdhint b{font-weight:700;border:1px solid var(--line);border-radius:5px;padding:1px 5px;background:var(--surface)}

  /* ---------- desktop / landscape (PC & laptop): fill the browser ---------- */
  @keyframes pop{from{transform:scale(.97);opacity:0}to{transform:none;opacity:1}}
  @media (min-width: 900px){
    .app{max-width:none;padding-left:240px;border-left:none;border-right:none}
    /* bottom tab bar becomes a left sidebar */
    .nav{left:0;transform:none;top:0;bottom:0;width:240px;max-width:none;
      display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;gap:4px;
      padding:22px 14px;border-top:none;border-right:3px solid var(--gold)}
    .nav::before{content:"Reeli";font-family:var(--display);font-weight:800;font-size:26px;letter-spacing:1px;
      text-transform:uppercase;color:var(--gold);padding:4px 12px 24px;text-shadow:1px 1px 0 rgba(0,0,0,.35)}
    .nav button{flex-direction:row;justify-content:flex-start;gap:12px;padding:11px 12px;font-size:14px;border-radius:10px}
    .nav button:hover{color:var(--bg);background:rgba(255,255,255,.08)}
    .nav button.cur{background:rgba(242,183,5,.16);color:var(--nav-cur)}
    .nav .plus{margin:0;width:34px;height:34px;border-radius:8px;box-shadow:none;flex:none;border:none}
    .nav .plus svg{width:20px;height:20px}
    .nav button[data-nav="search"]::after{content:"Rank a movie";font-size:14px;font-weight:700;color:var(--nav-ink)}
    .nav button[data-nav="search"]{margin:8px 0}
    .badge{top:50%;transform:translateY(-50%);left:auto;right:10px}
    .top{padding:16px 36px 14px}
    .top .logo{visibility:hidden} /* the sidebar carries the wordmark on desktop */
    .screens{padding-bottom:56px}
    .pad{max-width:1360px;margin:0 auto;padding:28px 36px}
    #scr-profile .pad{max-width:940px}
    .h1{font-size:30px}
    .sub{font-size:14px;max-width:64ch}
    /* feed becomes a card grid */
    .fgrid{grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:14px;align-items:start}
    /* list screens go multi-column: each row becomes its own card */
    #scr-ranks .card,#scr-search .card,#scr-watch .card{background:transparent;border:none;border-radius:0;overflow:visible;
      display:grid;grid-template-columns:repeat(auto-fill,minmax(420px,1fr));gap:10px}
    #scr-ranks .card .row,#scr-search .card .row,#scr-watch .card .row{
      background:var(--surface);border:1.5px solid var(--line);border-radius:12px}
    #scr-ranks .card .empty,#scr-search .card .empty,#scr-watch .card .empty{grid-column:1/-1}
    .kbdhint{display:block}
    /* bottom sheets become centered dialogs */
    .overlay{align-items:center;padding:28px}
    .sheet{max-width:520px;border-radius:16px;animation:pop .18s ease;max-height:86dvh}
    .grab{display:none}
    .toast{bottom:44px}
    /* onboarding goes two-column */
    .auth{padding:48px 60px}
    .auth.on{display:grid;grid-template-columns:minmax(0,560px) 420px;justify-content:center;
      grid-template-areas:"hero card" "feats card" "feats ghost" ". note";
      column-gap:64px;row-gap:10px;align-content:center}
    .auth .hero{grid-area:hero;align-items:flex-start;text-align:left;margin-bottom:10px}
    .auth .hero .wordmark{font-size:42px}
    .auth .tagline{max-width:34ch;font-size:16.5px}
    .feats{grid-area:feats;margin:0;max-width:380px}
    .feat{font-size:13.5px}
    .authcard{grid-area:card;align-self:center;width:100%;max-width:none}
    .ghostlink{grid-area:ghost;margin:12px auto 0}
    .authnote{grid-area:note;margin:0 auto}
  }
