/* ============================================================================
   play.css — Predict the Weekend
   ----------------------------------------------------------------------------
   Loaded AFTER /account/account.css, which already carries the v2 token block,
   the base reset, .optb-nav and .site-footer. Nothing in here re-declares any
   of that; this file is only the game.

   THEME. The game is dark-only, like the profile hero and unlike the auth
   cards. Every screen in the design is a cinematic backdrop with panels on
   #0a0a0a, and the handoff gives no light values for any of it — a light
   variant would be invention, not implementation. Each page pins dark before
   paint with the same inline script the profile pages use.

   NAMING. Everything is pw-* (Predict the Weekend). The game's display name
   lives in ONE place, PW.NAME in play.js, because the handoff says the name is
   still moving. Nothing in this file spells it out.
============================================================================ */

/* ── Shell ────────────────────────────────────────────────────────────────── */
body.pw-body{background:var(--acc-ground)}

/* ── Heroes ───────────────────────────────────────────────────────────────────
   Four heights across the five screens: 400 landing, 180 board, 200 scored,
   220 all-time. The weekly leaderboard has no fixed height — its content sets
   it — so it gets .pw-hero--auto. */
/* HEIGHTS ARE MINIMUMS, NOT FIXED. This block used to say `height`, and the
   hero is `overflow:hidden` (it has to be — the backdrop is an absolutely
   positioned <img>) with `align-items:flex-end`. Put one word too many in the
   headline or a CTA label and the content outgrows the box, overflows UPWARD,
   and is clipped behind the nav — which is exactly what "See Week 33 results"
   did at 390px: it wrapped the CTA row onto two lines and the eyebrow went
   under the logo. min-height keeps the designed proportions and lets the rare
   tall case push the hero taller instead of eating its own top.

   padding-top clears the nav (54px desktop / 48px phone, position:absolute) for
   the same case. It costs nothing when the content is shorter than the box,
   because the content is bottom-aligned. */
.pw-hero{position:relative;display:flex;align-items:flex-end;overflow:hidden;padding-top:74px}
.pw-hero--tall{min-height:400px}
.pw-hero--compact{min-height:180px}
.pw-hero--mid{min-height:200px}
.pw-hero--board{min-height:220px}
.pw-hero--auto{display:block;height:auto;padding-top:0}   /* clears the nav itself, via .pw-lbtop */
.pw-hero-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 25%;filter:brightness(.35)}
.pw-hero--auto .pw-hero-img{object-position:center 30%;filter:brightness(.3)}
.pw-hero-glow{position:absolute;inset:0;background:radial-gradient(ellipse 70% 60% at 50% 20%,rgba(34,197,94,.12),transparent)}
.pw-hero-fade{position:absolute;inset:0;background:linear-gradient(to top,#0a0a0a 0%,rgba(10,10,10,.8) 20%,rgba(10,10,10,.25) 65%)}
.pw-hero--compact .pw-hero-fade,
.pw-hero--mid .pw-hero-fade{background:linear-gradient(to top,#0a0a0a 0%,rgba(10,10,10,.7) 30%,rgba(10,10,10,.3) 100%)}
.pw-hero--board .pw-hero-fade{background:linear-gradient(to top,#0a0a0a 0%,rgba(10,10,10,.75) 30%,rgba(10,10,10,.3) 100%)}
.pw-hero--auto .pw-hero-fade{background:linear-gradient(to top,#0a0a0a 0%,rgba(10,10,10,.85) 25%,rgba(10,10,10,.4) 70%)}
.pw-hero-body{position:relative;z-index:5;width:100%}
.pw-hero-centre{text-align:center;padding:0 64px 40px}
.pw-hero-row{padding:0 64px 20px;width:100%;display:flex;align-items:flex-end;gap:14px}
.pw-hero--board .pw-hero-row{padding-bottom:22px}

.pw-eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:11px;font-weight:800;letter-spacing:.2em;text-transform:uppercase;color:var(--accent-green-text);margin-bottom:14px}
.pw-eyebrow svg{width:12px;height:12px}
.pw-headline{font-size:50px;font-weight:800;letter-spacing:-.03em;line-height:1.05;color:#fff;text-shadow:0 2px 30px rgba(0,0,0,.6)}
.pw-headline--md{font-size:38px;letter-spacing:-.02em;line-height:1.1}
.pw-headline--sm{font-size:34px;letter-spacing:-.02em;text-shadow:none}
.pw-headline--xs{font-size:32px;letter-spacing:-.02em;text-shadow:none}
.pw-subhead{font-size:15px;color:var(--text-secondary);margin-top:12px}
.pw-crumb{font-size:11px;color:rgba(255,255,255,.5);margin-bottom:6px}
.pw-title{font-size:28px;font-weight:800;letter-spacing:-.02em;color:#fff}
.pw-hero-note{font-size:12.5px;color:rgba(255,255,255,.55);white-space:nowrap;padding-bottom:4px;margin-left:auto}

/* ── Pills ────────────────────────────────────────────────────────────────── */
.pw-ctas{display:flex;justify-content:center;gap:12px;margin-top:22px}
.pw-pill{display:inline-flex;align-items:center;justify-content:center;border-radius:100px;padding:12px 30px;font-size:13px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;cursor:pointer;font-family:inherit;text-decoration:none;border:none;transition:opacity .2s,background .2s,border-color .2s,color .2s}
.pw-pill--solid{background:var(--accent-green);color:#fff}
.pw-pill--solid:hover{opacity:.9}
.pw-pill--ghost{background:rgba(255,255,255,.03);color:rgba(255,255,255,.75);border:1px solid rgba(255,255,255,.16)}
.pw-pill--ghost:hover{color:#fff;border-color:rgba(255,255,255,.3)}
.pw-pill--sm{padding:12px 30px;font-size:12.5px;letter-spacing:.05em}
.pw-pill--outline{background:none;border:1px solid var(--accent-green-border);color:var(--accent-green-text);padding:9px 22px;font-size:11.5px}
.pw-pill--outline:hover{background:var(--accent-green-bg)}
.pw-pill:disabled{opacity:.45;cursor:default}

/* ── Hero CTAs: both unfilled ─────────────────────────────────────────────
   The hero used to pair a green-filled pill with a ghost pill. Green fill is
   also what .pw-toggle a.is-on uses to mean "you are here", and that toggle
   sits ~18px below in the same hero — so a solid/ghost pair read as a
   segmented control with the left half already selected, not as two things
   you can press. Both pills are outlined here so they read as actions.
   Scoped to .pw-hero: --solid is still the primary fill everywhere else
   (the gate, the results band, the leaderboard empty state), and the JS
   still finds this button via '.pw-ctas .pw-pill--solid'. */
.pw-hero .pw-ctas .pw-pill--solid{background:rgba(255,255,255,.03);color:rgba(255,255,255,.75);border:1px solid rgba(255,255,255,.16)}
.pw-hero .pw-ctas .pw-pill--solid:hover{opacity:1;color:#fff;border-color:rgba(255,255,255,.3)}
.pw-locked-pill{display:inline-flex;align-items:center;gap:8px;background:rgba(34,197,94,.12);border:1px solid rgba(34,197,94,.4);border-radius:100px;padding:11px 26px;font-size:12.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--accent-green-text)}
.pw-locked-pill svg{width:13px;height:13px}

/* ── Segmented toggle ─────────────────────────────────────────────────────── */
/* The two views used to be switched from a pill pair in the hero's right-hand
   slot, which meant the control moved horizontally every time you used it: the
   headline either side of it changes width ("Your five are in." vs "Week 34 —
   the field"), and a status chip appeared on one tab and not the other. A
   control that jumps out from under the thumb that just pressed it is the one
   thing a two-tab page must not do. It gets its own row, hard left, and nothing
   that changes width is allowed in the hero beside it. */
.pw-tabrow{display:flex;justify-content:flex-start;align-items:center;width:100%}
/* The leaderboard's hero is centred, so the same control centres there rather
   than sitting hard left against a centred headline. Centring is also what
   keeps it still when the view switches: "The week belonged to @x." and
   "All-time, it belongs to @x." are different widths, and a centred control
   does not care. */
.pw-tabrow--centre{justify-content:center}
/* One level down: which leaderboard, not which screen. Same pills, tucked
   under the game control rather than beside it, so the hierarchy is legible
   without a second visual language. */
.pw-tabrow--sub{margin-top:10px}
.pw-tabrow--sub .pw-toggle{margin-top:0;transform:scale(.92);transform-origin:center top}
/* The segment you are already on is not a link and must not offer to be one. */
.pw-toggle a:not([href]){cursor:default}
/* Three segments now: two that swap the body and one that navigates to the
   leaderboard. The third gets no .is-on state, because you can never be on it
   while you are reading this page — it is the way out, drawn in the same
   control because it is the same week of the same game. */
.pw-tabrow .pw-toggle a{white-space:nowrap}
@media(max-width:700px){
  .pw-tabrow .pw-toggle{margin-top:14px}
  /* Three labels across a 390px screen: the control keeps its shape and takes
     the extra room out of the padding rather than wrapping into two rows. */
  .pw-tabrow .pw-toggle a{padding:6px 12px}
}

.pw-toggle{display:inline-flex;border-radius:100px;padding:3px}
.pw-toggle--glass{background:rgba(10,10,10,.5);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.12);margin-top:18px}
.pw-toggle--solid{background:var(--bg-card);border:1px solid var(--border-medium);margin-bottom:4px}
.pw-toggle a{font-size:11px;font-weight:700;border-radius:100px;padding:6px 16px;cursor:pointer;text-decoration:none;color:rgba(255,255,255,.6);transition:color .2s,background .2s}
.pw-toggle--solid a{padding:5px 14px;color:rgba(255,255,255,.55)}
.pw-toggle a:hover{color:#fff}
.pw-toggle a.is-on{color:var(--accent-green-on);background:var(--accent-green)}

/* ── Rules band ───────────────────────────────────────────────────────────── */
.pw-banner{text-align:center;margin:30px auto 0;max-width:1100px;padding:14px 0;border-top:1px solid var(--border-light)}
.pw-banner b{font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-body)}
.pw-banner b i{font-style:normal;color:var(--accent-green-text)}
.pw-banner span{font-size:12.5px;color:var(--text-muted);margin-left:10px}

.pw-rules{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--border-light)}
.pw-rules--boxed{max-width:1100px;margin:0 auto;border-bottom:1px solid var(--border-light)}
.pw-rules > div{padding:24px 26px}
.pw-rules--boxed > div{padding:26px}
.pw-rules > div:not(:last-child){border-right:1px solid var(--border-light)}
.pw-rules .n{font-size:20px;font-weight:800;color:var(--accent-green-text);margin-bottom:8px}
.pw-rules--boxed .n{font-size:24px}
.pw-rules h3{font-size:13.5px;font-weight:700;color:#fff;margin-bottom:5px}
.pw-rules--boxed h3{font-size:14px}
.pw-rules h3 span{color:var(--text-muted);font-weight:600}
.pw-rules p{font-size:12.5px;color:var(--text-tertiary);line-height:1.6}
.pw-rules--boxed p{color:var(--text-muted)}
.pw-rules p b{color:#fff;font-weight:600}
.pw-rules p i{font-style:normal;color:var(--accent-green-text);font-weight:700}
/* Three open columns here, a tap-to-expand list on a phone, from one markup.
   <details> is the entire mechanism because it opens and closes with no
   JavaScript at all — so the phone behaviour cannot be broken by a script
   error. Each one ships with `open` and the inline script under the block
   closes them below 700px, which means a no-JS visitor gets today's fully
   expanded band rather than three headings they have no way to open.
   On desktop the summary is inert: no marker, no caret, no pointer. */
.pw-rules summary{list-style:none;display:block;cursor:default}
.pw-rules summary::-webkit-details-marker{display:none}
.pw-rules-caret{display:none}

/* ── Divider ──────────────────────────────────────────────────────────────── */
.pw-div{display:flex;align-items:center;gap:16px;max-width:1100px;margin:0 auto;padding:36px 64px 0}
.pw-div--narrow{max-width:860px;padding:34px 0 0}
.pw-div--tight{padding-top:22px}
.pw-div::before,.pw-div::after{content:'';flex:1;height:1px;background:var(--border-light)}
.pw-div span{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-faint);white-space:nowrap}
.pw-div span i{font-style:normal;color:var(--accent-yellow-text)}

/* ── Poster cards ─────────────────────────────────────────────────────────── */
.pw-row{display:flex;justify-content:center;align-items:flex-start;flex-wrap:wrap;gap:14px;padding:24px 64px 8px}
.pw-slate{width:132px;text-align:center}
.pw-art{border-radius:10px;overflow:hidden;box-shadow:0 8px 24px rgba(0,0,0,.4)}
.pw-art img{width:100%;display:block;aspect-ratio:2/3;object-fit:cover}
.pw-ph{aspect-ratio:2/3;background:linear-gradient(160deg,#232326,#141416);display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:800;color:rgba(255,255,255,.25)}
.pw-slate .t{font-size:12px;font-weight:600;color:#fff;margin-top:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pw-slate .m{font-size:10.5px;color:var(--text-faint);margin-top:2px}

/* ── The board ────────────────────────────────────────────────────────────── */
.pw-board{display:flex;justify-content:center;align-items:stretch;flex-wrap:wrap;gap:16px;padding:32px 64px 0}
.pw-card{width:190px;position:relative;border-radius:12px;overflow:hidden;box-shadow:0 16px 48px rgba(0,0,0,.5);cursor:grab;background:var(--bg-card)}
.pw-card.is-dragging{opacity:.45;cursor:grabbing}
.pw-card.is-over{outline:2px solid var(--accent-green);outline-offset:2px}
/* Every poster is forced to 2:3 and cropped to fill. TMDB is *usually*
   consistent, but one film served at a different ratio leaves a black gap
   under a short card while its neighbour stretches — and in a flex row with
   align-items:stretch that gap is very visible. Pinning the ratio makes the
   row uniform whatever the CDN returns. */
.pw-card > img{width:100%;display:block;aspect-ratio:2/3;object-fit:cover}
.pw-card .pw-ph{flex-direction:column;gap:8px;font-size:30px;color:rgba(255,255,255,.3);background:linear-gradient(160deg,#26262a,#121214)}
.pw-card .pw-ph em{font-style:normal;font-size:9px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.35)}
.pw-chip{position:absolute;top:10px;left:10px;width:28px;height:28px;border-radius:8px;background:var(--accent-green);color:var(--accent-green-on);display:inline-flex;align-items:center;justify-content:center;font-size:14px;font-weight:800}
/* The corner tool cluster: drag handle + remove. .pw-grab keeps its own
   absolute positioning for any markup that still places it alone. */
.pw-grab{position:absolute;top:10px;right:10px;background:rgba(0,0,0,.6);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:6px;padding:4px 7px;font-size:11px;letter-spacing:2px;color:rgba(255,255,255,.5)}
.pw-tools{position:absolute;top:10px;right:10px;display:flex;align-items:center;gap:5px;z-index:3}
.pw-tools .pw-grab{position:static}
/* Deliberately quiet until the card is touched. A red × sitting on every
   poster makes a board look like a list of mistakes; a player who wants one
   gone will hover or tap the card first. On touch there is no hover, so the
   media query below keeps it permanently visible there. */
.pw-remove{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;border-radius:6px;background:rgba(0,0,0,.6);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:rgba(255,255,255,.55);font-family:inherit;font-size:16px;line-height:1;cursor:pointer;opacity:0;transition:opacity .15s,background .15s,color .15s}
.pw-card:hover .pw-remove,.pw-remove:focus-visible{opacity:1}
.pw-remove:hover{background:var(--accent-red-bg);color:var(--accent-red-text)}
.pw-remove:focus-visible{outline:2px solid var(--accent-green);outline-offset:2px}
.pw-scrim{position:absolute;left:0;right:0;bottom:0;padding:50px 12px 14px;background:linear-gradient(transparent,rgba(0,0,0,.94));text-align:center}
.pw-scrim .n{font-size:13px;font-weight:700;color:#fff;margin-bottom:6px}
.pw-gross{width:110px;background:none;border:none;border-bottom:1px dashed rgba(255,255,255,.4);font-size:21px;font-weight:800;color:#fff;text-align:center;font-family:inherit;padding:0 0 3px;transition:border-color .2s}
.pw-gross:focus{outline:none;border-bottom-color:var(--accent-green)}
.pw-gross:disabled{opacity:1;border-bottom-color:transparent}
.pw-micro{font-size:9px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.45);margin-top:5px}
.pw-empty{width:190px;aspect-ratio:2/3;position:relative;border-radius:12px;border:1px dashed rgba(34,197,94,.4);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;cursor:pointer;background:none;font-family:inherit;transition:border-color .2s,background .2s}
.pw-empty:hover{border-color:rgba(34,197,94,.8);background:rgba(34,197,94,.04)}
.pw-empty .pw-chip{position:static;background:rgba(34,197,94,.15);color:var(--accent-green-text)}
.pw-empty .l{font-size:12.5px;font-weight:600;color:var(--text-tertiary);text-align:center;line-height:1.6;padding:0 20px}
.pw-empty .l span{color:var(--text-faint);font-weight:400}

/* ── The shelf ────────────────────────────────────────────────────────────── */
.pw-shelf{display:flex;justify-content:center;align-items:flex-start;flex-wrap:wrap;gap:14px;padding:22px 64px 0}
.pw-tile{width:98px;text-align:center;cursor:pointer;background:none;border:none;padding:0;font-family:inherit}
.pw-tile:disabled{opacity:.35;cursor:default}
.pw-tile .pw-art{border-radius:8px}
.pw-tile .pw-art img{opacity:.9}
.pw-tile .pw-ph{border-radius:8px;font-size:16px;color:rgba(255,255,255,.3)}
.pw-tile .t{font-size:11px;font-weight:600;color:#fff;margin-top:7px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pw-tile .a{font-size:10.5px;font-weight:700;color:var(--accent-green-text);margin-top:2px}

/* ── Lock bar ─────────────────────────────────────────────────────────────── */
/* The lock bar renders between the board and the shelf, so it no longer
   closes the page — the shelf does. Bottom spacing moved with it. */
.pw-lockwrap{max-width:1100px;margin:34px auto 0;padding:0 64px}
#pw-shelfwrap{padding-bottom:44px}
/* Once the week closes the shelf comes off — it is a picker with nothing left
   to pick — and that leaves the lock bar as the last thing in the stage,
   sitting flush against the rules grid's border-top with no gap at all. The
   shelf's own bottom padding is what held that line off the card, so match it
   here rather than putting a margin on .pw-lockwrap, which would also open a
   gap between the bar and the shelf on a board that is still open. */
#pw-stage > .pw-lockwrap:last-child{padding-bottom:44px}
.pw-lockbar{display:flex;align-items:center;gap:20px;flex-wrap:wrap;background:var(--bg-card);border:1px solid var(--border-medium);border-radius:14px;padding:18px 26px}
.pw-lockbar .s{font-size:13.5px;font-weight:700;color:#fff}
.pw-lockbar .s span{font-weight:400;color:var(--text-muted)}
.pw-count{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:700;color:var(--accent-yellow-text);margin-left:auto}
.pw-count svg{width:13px;height:13px}
.pw-count.is-past{color:var(--accent-red-text)}

/* ── The board's standing note (ruling 6) ───────────────────────────────────
   Sits under the lock bar on /play/board/: amber when the board would score
   nothing as it stands, green when it is complete and therefore safe. Same
   visual language as .pw-oop further down — an explanation, not an error.

   EVERY selector here is scoped under .pw-lockwrap on purpose. play.css is
   shared with Predict the Final, and .pw-lockwrap is rendered by /play/board/
   and by nothing else, so scoping is what keeps this out of the other game. */
.pw-lockwrap .pw-lockmsg{display:flex;gap:10px;align-items:flex-start;margin-top:10px;
  padding:11px 15px;border-radius:11px;font-size:12.5px;line-height:1.6;color:#d8d8dd}
.pw-lockwrap .pw-lockmsg .i{flex:none;width:18px;height:18px;border-radius:50%;
  display:grid;place-items:center;font-weight:800;font-size:11px;line-height:1;margin-top:1px}
.pw-lockwrap .pw-lockmsg--warn{background:rgba(234,179,8,.07);border:1px solid rgba(234,179,8,.28)}
.pw-lockwrap .pw-lockmsg--warn .i{background:rgba(234,179,8,.22);color:#fde047}
.pw-lockwrap .pw-lockmsg--warn b{color:#fde047;font-weight:700}
.pw-lockwrap .pw-lockmsg--ok{background:rgba(34,197,94,.06);border:1px solid rgba(34,197,94,.26)}
.pw-lockwrap .pw-lockmsg--ok .i{background:rgba(34,197,94,.2);color:#4ade80}
.pw-lockwrap .pw-lockmsg--ok b{color:#4ade80;font-weight:700}
@media(max-width:700px){.pw-lockwrap .pw-lockmsg{font-size:12px;padding:10px 13px}}

/* ── Panels, tables, marquees ─────────────────────────────────────────────── */
.pw-col{max-width:860px;margin:0 auto;padding:26px 20px 48px}
.pw-strip{display:flex;align-items:center;gap:16px;flex-wrap:wrap;background:var(--bg-card);border:1px solid var(--border-medium);border-radius:12px;padding:13px 18px;margin-top:18px}
.pw-strip .l{font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--text-muted);flex-shrink:0}
.pw-strip .list{flex:1;display:flex;gap:20px;flex-wrap:wrap;font-size:12.5px;color:var(--text-secondary)}
.pw-strip .list b{font-weight:700;color:#fff}
.pw-strip .list i{font-style:normal;color:var(--text-faint);font-weight:700}
.pw-strip .stamp{font-size:11px;color:var(--text-faint);flex-shrink:0}

/* ← older · latest · newer → under the weekly board */
/* Three slots, explicitly placed. It was flex + space-between, which put the
   middle item hard against the right edge whenever there was no "next" week,
   and on a phone squeezed all three into one line of two-word wraps. Explicit
   grid columns mean an absent slot leaves a gap where it was rather than
   dragging its neighbours across; below 700px the row becomes one centred
   column, because three links across 390px is not a row. */
.pw-weeknav{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:12px 20px;margin-top:24px;padding-top:18px;
  border-top:1px solid var(--border-light);font-size:12.5px}
.pw-weeknav-prev{grid-column:1;justify-self:start;text-align:left}
.pw-weeknav-mid{grid-column:2;justify-self:center;text-align:center}
.pw-weeknav-next{grid-column:3;justify-self:end;text-align:right}
@media(max-width:700px){
  .pw-weeknav{grid-template-columns:1fr;gap:16px;justify-items:center;
    margin-top:20px;padding-top:20px}
  .pw-weeknav-prev,.pw-weeknav-mid,.pw-weeknav-next{
    grid-column:1;justify-self:center;text-align:center}
}
.pw-weeknav .pw-navmid{color:var(--text-faint);font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.pw-weeknav .pw-navspacer{flex:0 0 auto;min-width:1px}

.pw-noresult{padding:14px 4px;font-size:13px;color:var(--text-faint);text-align:center}

/* "Other…" overflow tile on the shelf */
.pw-tile--other .pw-art--dashed{display:flex;align-items:center;justify-content:center;border:1px dashed var(--border-strong);background:transparent}
.pw-tile--other:not(:disabled):hover .pw-art--dashed{border-color:var(--accent-green-border)}
.pw-tile--other .pw-ph{font-size:22px;color:var(--text-faint);background:none}

.pw-thead,.pw-tr{display:flex;align-items:center;gap:14px}
.pw-thead{padding:0 10px 9px;border-bottom:1px solid var(--border-medium)}
.pw-thead div{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint)}
/* Sortable column headers (all-time board). They have to read exactly like
   the weekly board's static ones — same size, weight, tracking, colour —
   because the two theads sit behind one toggle and any difference in the
   type reads as a different table. The caret is the only tell. */
.pw-thead .pw-sortbtn{appearance:none;-webkit-appearance:none;background:none;border:0;padding:0;margin:0;font-family:inherit;font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);cursor:pointer;display:inline-flex;align-items:center;justify-content:flex-end;gap:4px;white-space:nowrap;flex:0 0 auto;transition:color .12s}
.pw-thead .pw-sortbtn:hover{color:var(--text-secondary)}
.pw-thead .pw-sortbtn.is-on{color:var(--accent-green-text)}
.pw-thead .pw-sortbtn .pw-caret{font-size:7px;line-height:1}
.pw-thead .pw-sortbtn:focus-visible{outline:2px solid var(--accent-green-text);outline-offset:3px;border-radius:3px}
/* Phones drop the Bullseyes and Wks columns (handles need the width), which
   would otherwise make two of the sorts unreachable on the device most of
   the game is played on. Same buttons, same data-sort hooks, shown as pills
   in the .pw-toggle's visual language instead of as column headers. */
.pw-sortbar{display:none}
.pw-tr{padding:11px 10px;border-bottom:1px solid var(--border-subtle);transition:background .2s}
.pw-tr:hover{background:var(--hover-bg)}
.pw-tr.is-you{background:rgba(34,197,94,.07);border-radius:10px;border-bottom:none;margin-top:2px}
.pw-tr.is-you:hover{background:rgba(34,197,94,.07)}
.pw-rank{width:26px;font-size:12px;font-weight:700;color:var(--text-tertiary);text-align:right;border-left:3px solid rgba(255,255,255,.15);padding-left:6px}
.pw-tr.is-you .pw-rank{color:var(--accent-green-text);border-left-color:var(--accent-green)}
.pw-av{width:30px;height:30px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:800;flex-shrink:0;overflow:hidden}
.pw-who{flex:1;display:flex;align-items:center;gap:8px;min-width:0;overflow:hidden}
.pw-who a,.pw-who span.h{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pw-flair{flex-shrink:0}
.pw-who a,.pw-who span.h{font-size:13.5px;font-weight:600;color:#fff;text-decoration:none}
.pw-tr.is-you .pw-who a{font-weight:700}
.pw-you{font-weight:600;color:var(--text-muted)}
.pw-num{text-align:right;font-size:13.5px;font-weight:700;color:var(--text-body)}
.pw-num2{text-align:right;font-size:12.5px;color:var(--text-muted)}
.pw-tr.is-you .pw-pts{font-weight:800;color:var(--accent-green-text)}
.pw-move{width:44px;text-align:right;font-size:11px;font-weight:700}
.pw-move.up{color:var(--accent-green-text)}
.pw-move.down{color:var(--accent-red-text)}
.pw-move.flat{color:var(--text-faint)}
.pw-ellipsis{text-align:center;padding:10px 0;font-size:12px;color:var(--text-xfaint)}
.pw-scale{font-size:12px;color:var(--text-faint)}
.pw-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:18px;padding:0 10px}
.pw-link{font-size:12.5px;font-weight:600;color:var(--accent-green-text);text-decoration:none;cursor:pointer}
.pw-link:hover{color:#4ade80}

/* Flair chips */
.pw-flair{border-radius:4px;padding:1px 6px;font-size:9px;font-weight:800;letter-spacing:.08em}
.pw-flair--green{background:rgba(34,197,94,.12);border:1px solid rgba(34,197,94,.35);color:var(--accent-green-text)}
.pw-flair--gold{background:rgba(234,179,8,.12);border:1px solid rgba(234,179,8,.35);color:var(--accent-yellow-text)}

/* Podium */
/* The scored-leaderboard headline block. .optb-nav is position:absolute and
   54px tall (48px on a phone), so anything less than that here is drawn UNDER
   the nav — which is exactly what a 34px inline padding was doing. Clear the
   nav, then leave it room to breathe. */
.pw-lbtop{text-align:center;padding:82px 20px 0}
@media(max-width:700px){.pw-lbtop{padding:68px 16px 0}}

.pw-podium{display:flex;justify-content:center;align-items:flex-end;flex-wrap:wrap;gap:18px;padding:34px 64px 40px}
.pw-pod{width:230px;background:rgba(24,24,27,.85);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.12);border-radius:14px;padding:22px;text-align:center}
.pw-pod--champ{width:270px;background:rgba(24,24,27,.9);border-color:rgba(234,179,8,.55);border-radius:16px;padding:28px 22px;box-shadow:0 24px 80px rgba(234,179,8,.12)}
.pw-pod .l{font-size:10px;font-weight:800;letter-spacing:.16em;color:var(--text-muted);margin-bottom:12px}
.pw-pod--champ .l{color:var(--accent-yellow-text)}
.pw-pod .pw-av{width:52px;height:52px;font-size:15px}
.pw-pod--champ .pw-av{width:66px;height:66px;font-size:19px;border:2px solid rgba(234,179,8,.6)}
.pw-pod .h{font-size:14px;font-weight:700;color:#fff;margin-top:10px;text-decoration:none;display:block}
.pw-pod--champ .h{font-size:16px}
.pw-pod .m{font-size:10.5px;color:var(--text-muted);margin-top:3px}
.pw-pod--champ .m{font-size:11px}
.pw-pod .p{font-size:30px;font-weight:800;color:#fff;letter-spacing:-.02em;margin-top:10px}
.pw-pod--champ .p{font-size:42px;color:var(--accent-yellow-text);line-height:1}
.pw-unlocked{display:inline-flex;align-items:center;gap:7px;background:rgba(34,197,94,.12);border:1px solid rgba(34,197,94,.35);border-radius:100px;padding:6px 14px;font-size:10.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--accent-green-text);margin-top:14px}

/* Ruled stat grids — totals band, top-3 marquee, record book, week strip */
.pw-grid{display:grid;border-top:1px solid var(--border-light);border-bottom:1px solid var(--border-light)}
.pw-grid--3{grid-template-columns:repeat(3,1fr)}
.pw-grid--4{grid-template-columns:repeat(4,1fr)}
.pw-grid > div{padding:26px 18px;text-align:center}
.pw-grid > div:not(:last-child){border-right:1px solid var(--border-light)}
.pw-grid .v{font-size:44px;font-weight:800;letter-spacing:-.02em;line-height:1;color:#fff}
.pw-grid .v.g{color:var(--accent-green-text)}
.pw-grid .v.a{color:var(--accent-yellow-text)}
/* The unit that stops a big bare number in the all-time podium reading as a
   score. It ranks on the average now, and "64.3" without a label is the one
   thing that would send someone looking for the missing points. */
.pw-grid .v .pw-unit,.pw-pod .p .pw-unit{font-size:.32em;font-weight:700;letter-spacing:.14em;margin-left:.4em;vertical-align:.42em;color:var(--text-muted)}
.pw-grid .l{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-faint);margin-top:8px}
.pw-grid--record > div{padding:22px 26px}
.pw-grid--record .v{font-size:22px}
.pw-grid--record .l{font-size:10px;letter-spacing:.14em;margin-bottom:8px;margin-top:0}
.pw-grid--record .m{font-size:11.5px;color:var(--text-muted);margin-top:6px}
/* The record book sits in the slot the weekend strip occupies on the weekly
   board, so it wears the same card. Without this it is .pw-grid's bare
   full-bleed band, which is the one thing that still made the two boards
   look like different pages. */
.pw-grid--card{background:var(--bg-card);border:1px solid var(--border-medium);border-radius:12px;overflow:hidden}

/* Four-week strip */
.pw-weeks{display:grid;grid-template-columns:repeat(4,1fr);max-width:860px;margin:20px auto 0;border:1px solid var(--border-light);border-radius:14px;overflow:hidden}
.pw-weeks > div{padding:18px;text-align:center;background:var(--bg-card)}
.pw-weeks > div:not(:last-child){border-right:1px solid var(--border-light)}
.pw-weeks .v{font-size:20px;font-weight:800;line-height:1;color:#fff}
.pw-weeks .l{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);margin-top:7px}
.pw-weeks .none .v{color:var(--text-xfaint)}
.pw-weeks .now{background:rgba(34,197,94,.08)}
.pw-weeks .now .v{color:var(--accent-green-text)}
.pw-weeks .now .l{color:var(--accent-green-text)}

/* ── Scored cards ─────────────────────────────────────────────────────────── */
.pw-scored{display:flex;justify-content:center;align-items:stretch;flex-wrap:wrap;gap:16px;padding:26px 64px 20px}
.pw-scard{width:186px;position:relative;border-radius:12px;overflow:hidden;box-shadow:0 16px 48px rgba(0,0,0,.5);background:var(--bg-card)}
.pw-scard > img{width:100%;display:block;aspect-ratio:2/3;object-fit:cover}
.pw-scard .pw-scrim{padding:52px 12px 13px;background:linear-gradient(transparent,rgba(0,0,0,.95))}
.pw-scard .p{font-size:24px;font-weight:800;letter-spacing:-.01em;line-height:1;color:#fff}
.pw-scard .p.g{color:var(--accent-green-text)}
.pw-scard .f{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-tertiary);margin-top:5px}
.pw-scard .c{font-size:10px;color:var(--text-muted);margin-top:3px}
.pw-stamp{position:absolute;top:10px;right:10px;background:rgba(234,179,8,.9);color:#1c1400;border-radius:6px;padding:4px 9px;font-size:9px;font-weight:800;letter-spacing:.1em;text-transform:uppercase}
.pw-chip--shift{display:inline-flex;align-items:center;gap:4px;width:auto;height:28px;padding:0 9px;background:rgba(234,179,8,.9);color:#1c1400;font-size:13px}

/* ── Notes and empty states ───────────────────────────────────────────────── */
.pw-note{text-align:center;padding:26px 64px 44px;font-size:12.5px;color:var(--text-tertiary);line-height:1.7;max-width:640px;margin:0 auto}
.pw-legal{text-align:center;padding:16px 64px 44px;font-size:12px;color:var(--text-faint)}
.pw-legal span{color:var(--text-tertiary)}
.pw-blank{max-width:640px;margin:0 auto;padding:56px 20px;text-align:center}
.pw-blank h2{font-size:20px;font-weight:800;color:#fff;margin-bottom:8px}
.pw-blank p{font-size:13.5px;color:var(--text-tertiary);line-height:1.7}
.pw-blank .pw-pill{margin-top:20px}
.pw-err{background:var(--accent-red-bg);border:1px solid var(--accent-red-border);border-radius:10px;padding:12px 14px;font-size:13px;color:var(--accent-red-text);max-width:860px;margin:16px auto 0}

/* ── Prose, for the rules page ────────────────────────────────────────────── */
.pw-prose{max-width:720px;margin:0 auto;padding:36px 20px 64px;font-size:14.5px;line-height:1.75;color:var(--text-secondary)}
.pw-prose h2{font-size:17px;font-weight:800;color:#fff;margin:32px 0 10px}
.pw-prose h2:first-child{margin-top:0}
.pw-prose p,.pw-prose li{margin-bottom:12px}
.pw-prose ul,.pw-prose ol{padding-left:22px}
.pw-prose strong{color:#fff;font-weight:700}
.pw-prose table{width:100%;border-collapse:collapse;margin:14px 0 20px;font-size:13.5px}
.pw-prose th,.pw-prose td{text-align:left;padding:8px 10px;border-bottom:1px solid var(--border-light)}
.pw-prose th{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint)}

/* ── Responsive ───────────────────────────────────────────────────────────────
   The handoff has no responsive rules at all — five fixed 1280px frames — and
   says to inherit the site's conventions, so this is the site's 700px
   breakpoint applied to each component. The poster rows already wrap rather
   than scroll horizontally, which on a phone beats a 5-wide row of 190px cards
   in a carousel nobody discovers. */
@media(max-width:700px){
  .pw-hero{padding-top:64px}
  .pw-hero--tall{min-height:340px}
  .pw-hero--compact,.pw-hero--mid,.pw-hero--board{min-height:150px}
  .pw-hero-centre{padding:0 16px 28px}
  .pw-hero-row{padding:0 16px 18px;flex-wrap:wrap;gap:10px}
  .pw-hero-note{margin-left:0;white-space:normal}
  .pw-headline{font-size:29px}
  .pw-headline--md{font-size:25px}
  .pw-headline--sm,.pw-headline--xs{font-size:23px}
  .pw-subhead{font-size:13.5px}
  .pw-title{font-size:21px}
  .pw-ctas{flex-direction:column;align-items:stretch;gap:10px}
  .pw-ctas .pw-pill{width:100%}
  /* The rules band goes to ONE column, not two. Two columns of 12.5px prose in
     a 390px viewport gives each cell about 170px of measure, which breaks
     "Guess the gross" into a ladder of two-word lines — and the third cell
     orphans onto its own row anyway. The stat grids keep two columns because
     they hold numbers, not sentences. */
  .pw-rules{grid-template-columns:1fr}
  .pw-grid--3,.pw-grid--4,.pw-weeks{grid-template-columns:repeat(2,1fr)}
  .pw-rules > div,.pw-grid > div,.pw-weeks > div{border-right:none!important;border-bottom:1px solid var(--border-light)}
  .pw-rules > div:last-child{border-bottom:none}

  /* Collapsed by default on a phone. Three stacked cells of prose ran 477px —
     most of a viewport spent on rules a returning player has read every week
     since they signed up — so the resting state is three tappable headings at
     ~150px, and the detail is one tap away for whoever actually wants it.
     The number stops being a display element on its own line and becomes a
     badge in the left gutter, which is what buys the row its single line.
     Padding moves from the cell to the summary and the paragraph so the whole
     row is the tap target, indented under the badge when open. */
  .pw-rules > div,.pw-rules--boxed > div{padding:0}
  .pw-rules summary{display:grid;grid-template-columns:26px 1fr 14px;column-gap:12px;
    align-items:center;padding:14px 20px;cursor:pointer;
    -webkit-tap-highlight-color:transparent}
  .pw-rules summary .n,.pw-rules--boxed summary .n{font-size:12px;font-weight:800;
    line-height:26px;height:26px;text-align:center;border-radius:8px;
    background:rgba(34,197,94,.14);margin-bottom:0}
  .pw-rules summary h3,.pw-rules--boxed summary h3{font-size:13px;margin:0}
  .pw-rules-caret{display:block;width:14px;height:14px;color:var(--text-faint);
    transition:transform .18s}
  .pw-rules details[open] .pw-rules-caret{transform:rotate(180deg)}
  .pw-rules details > p{padding:0 20px 15px 58px;font-size:12px;line-height:1.5}
  /* The line break in rule 1 exists to split two sentences across a wide
     column; in a 58px-indented phone column it just strands "5 points". */
  .pw-rules details > p br{display:none}
  .pw-rules details > p br + b::before{content:" \00b7  "}

  /* The divider label carries the live countdown, and nowrap sent
     "This weekend's board — Aug 14–16 · locks in 2d 3h" 14px past the right
     edge of a phone. Let it wrap and centre instead. */
  .pw-div{flex-wrap:wrap}
  .pw-div span{white-space:normal;text-align:center;flex:1 1 100%;order:-1}
  .pw-div::before,.pw-div::after{display:none}

  /* "50 for the order · 50 for the grosses" comes off the phone entirely: the
     collapsed rules below it already carry "— 50 points" on rules 1 and 2, so
     the split is stated twice within a screen height of itself. The headline
     stays. On desktop the clause still sits inline and costs nothing, so it
     stays there. */
  .pw-banner b{display:block}
  .pw-banner span{display:none}
  .pw-grid .v{font-size:30px}
  .pw-row,.pw-board,.pw-shelf,.pw-scored{padding-left:16px;padding-right:16px;gap:10px}
  /* Scored view stays two-up-and-wrap: it is a result, not a ranking task, and
     you want all five scores on screen together. Left-aligned rather than
     centred so the fifth card lands under the first instead of being stranded
     in the middle of row three, where it reads as a mistake rather than slot 5. */
  .pw-scored{justify-content:flex-start}

  /* Poster rows marked .pw-cardrow become one horizontal strip on a phone. A
     wrapping grid turns five cards into two rows of two and an orphan, which
     reads as three separate things rather than one board — and buries the fifth
     pick below the fold. The negative margin lets the strip bleed to both edges
     so the last card is visibly cut off, which is what tells a thumb to swipe.
     The strip is exactly as wide as the viewport and scrolls inside itself — no
     negative margin, which would have made the element wider than the document
     and given the whole page a horizontal scrollbar to go with the strip's. The
     last card is cut off by the viewport edge either way, which is the part that
     tells a thumb to swipe. .pw-board is excluded: the editor has its own. */
  .pw-cardrow{flex-wrap:nowrap;overflow-x:auto;justify-content:flex-start;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;
    scroll-padding-left:16px}
  .pw-cardrow::-webkit-scrollbar{display:none}
  .pw-cardrow > *{flex:0 0 auto}
  .pw-cardrow .pw-scard{width:clamp(134px,42vw,158px)}
  .pw-cardrow .pw-scard .p{font-size:20px}
  /* THE BOARD IS ONE HORIZONTAL STRIP ON A PHONE.
     Two-up-and-wrap made every poster ~174px, so slot 1 filled the screen and
     slots 3-5 sat below the fold: the one thing this page asks you to do is
     read your five in rank order, and you could not see them as an order.
     A single strip puts the ranks along the axis they already run on, and the
     third card peeking is what says "there is more" without a caption.
     The negative margin is deliberate — cards must reach the screen edge or
     the strip reads as a clipped grid rather than a scroller. Matches the
     homepage's .yl-grid / .upc-strip treatment.

     No scroll-snap. The snapport starts at the padding edge, so snapping the
     first card to `start` pulls it 16px left and eats the gutter on load —
     the strip opens with slot 1 already clipped. The homepage strips
     (.yl-grid, .upc-strip, .pstrip-scroll) are all free-scrolling for the
     same reason; this matches them. */
  .pw-board{flex-wrap:nowrap;justify-content:flex-start;overflow-x:auto;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;
    margin:0 -16px;padding-bottom:6px}
  .pw-board::-webkit-scrollbar{display:none}
  .pw-card,.pw-empty{flex:0 0 auto;width:clamp(132px,38vw,150px)}
  .pw-scard{width:calc(50% - 5px)}
  .pw-slate{width:calc(33.333% - 7px)}
  /* Three across, not four. At four the tiles are 85px wide and every title
     truncates to "The End of …", which tells a player nothing about what they
     are adding to their board. */
  .pw-tile{width:calc(33.333% - 7px)}

  /* The scrim stops floating over the poster and sits under it.
     At 170px wide a two-line film title plus a gross plus a caption is taller
     than the space the gradient covers, so the overlay version pushes text up
     over the middle of the image where it is unreadable. Below the poster it
     always fits, and the rank chip and bullseye stamp still sit on the art
     where the design wants them.

     THE GREY BAR. Cards in a row stretch to the tallest (align-items:stretch),
     the poster is a fixed 2:3, and the scrim was sized to its own content — so
     a card sitting next to a two-line title got its extra height as bare
     .pw-card background below the caption. A 20px grey band under exactly one
     poster in the row, which reads as a rendering fault rather than a layout.
     Two rules fix it, and both are needed:
       · the scrim grows into the leftover space, so any remainder is scrim
         rather than card background;
       · the title reserves two lines whatever it holds, so a row of mixed
         one- and two-line titles keeps its grosses on the same baseline
         instead of stepping down mid-row. */
  /* No hover on a phone, so the remove button never appears — it has to be
     visible by default here or the dead end this exists to fix comes straight
     back on the half of the traffic that is a phone. Bigger, too: 24px is
     under the 44px touch target and it sits next to the drag handle. */
  .pw-remove{opacity:1;width:30px;height:30px;font-size:19px}
  .pw-tools{gap:6px}

  .pw-card .pw-scrim,.pw-scard .pw-scrim{position:static;padding:12px 10px 14px;background:rgba(0,0,0,.55);
    flex:1;display:flex;flex-direction:column;justify-content:flex-start}
  .pw-card,.pw-scard{display:flex;flex-direction:column}
  .pw-card .pw-scrim .n,.pw-scard .pw-scrim .f{line-height:1.25;min-height:2.5em;
    display:flex;align-items:center;justify-content:center}
  .pw-gross{width:100%;font-size:19px}

  /* Champion first. Stacked vertically, "2nd, champ, 3rd" buries the winner in
     the middle of the column.

     And the card turns on its side. As three portrait cards the podium ran to
     roughly 1,000px on a 390px screen — the winner, the runner-up and nothing
     else, for three full swipes — which is not what a podium is for. The same
     pieces laid out as a row are about 70px each: medal, avatar, placing and
     handle, score. Nothing is dropped, it just stops being a poster. */
  .pw-podium{flex-direction:column;align-items:stretch;gap:9px}
  .pw-pod--champ{order:-1}
  .pw-pod{width:auto;max-width:none;text-align:left;padding:12px 14px;
    display:grid;grid-template-columns:auto auto minmax(0,1fr) auto;
    grid-template-rows:auto auto auto;align-items:center;column-gap:13px;row-gap:1px}
  .pw-pod .pw-champ{grid-column:1;grid-row:1/4;flex-direction:row;gap:0}
  .pw-pod .pw-champ-t{display:none}
  .pw-pod .pw-champ--lg .pw-champ-medal{width:34px;height:34px}
  .pw-pod .pw-av{grid-column:2;grid-row:1/4;width:38px;height:38px;font-size:13px;margin:0}
  .pw-pod .l{grid-column:3;grid-row:1;margin:0;font-size:9px;letter-spacing:.13em}
  .pw-pod .h{grid-column:3;grid-row:2;margin:0;font-size:13.5px;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pw-pod .m{grid-column:3;grid-row:3;margin:0;font-size:10.5px}
  .pw-pod .p{grid-column:4;grid-row:1/4;margin:0;font-size:23px}
  .pw-div{padding-left:16px;padding-right:16px}
  .pw-lockwrap{padding:0 16px}
  #pw-shelfwrap{padding-bottom:32px}
  #pw-stage > .pw-lockwrap:last-child{padding-bottom:32px}
  .pw-lockbar{gap:12px}
  .pw-count{margin-left:0}
  .pw-lockbar .pw-pill,.pw-lockbar .pw-locked-pill{width:100%;justify-content:center}
  .pw-podium{padding:24px 16px 30px}
  /* Full width, not 320. The cap dated from the portrait podium card, where
     320px of poster on a 390px screen was the right proportion. The card is a
     row now, and a row that stops 38px short of the right edge while every
     other block on the page runs to the margin just looks broken. */
  .pw-pod,.pw-pod--champ{width:100%;max-width:none}
  .pw-col{padding:20px 16px 36px}
  /* Drop the bullseye column and the flair chips from table rows. The chips
     were winning the fight for horizontal space and squeezing handles down to
     "@track…", which is the one thing in the row nobody can do without. The
     champion still wears their badge on the podium directly above. */
  .pw-thead .h-bull,.pw-tr .b-bull,.pw-thead .h-wks,.pw-tr .b-wks{display:none}
  .pw-sortbar{display:flex;gap:6px;overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 0 14px;padding-bottom:2px;scrollbar-width:none}
  .pw-sortbar::-webkit-scrollbar{display:none}
  .pw-sortbar .pw-sortlbl{flex:0 0 auto;align-self:center;font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--text-xfaint);margin-right:2px}
  .pw-sortbar .pw-sortpill{flex:0 0 auto;appearance:none;-webkit-appearance:none;background:var(--bg-card);border:1px solid var(--border-medium);border-radius:100px;padding:6px 13px;font-family:inherit;font-size:11px;font-weight:700;color:rgba(255,255,255,.6);cursor:pointer;display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
  .pw-sortbar .pw-sortpill.is-on{background:var(--accent-green);border-color:transparent;color:var(--accent-green-on)}
  .pw-sortbar .pw-sortpill .pw-caret{font-size:7px;line-height:1}
  /* Sorting by a column the phone hides reorders the table for no visible
     reason — the rows shuffle and the number they shuffled on is not on
     screen. So the active sort's column comes back, for as long as it is
     the active sort. Handles get tighter; that is the trade the reader
     just asked for by tapping it. */
  /* The phone shows FOUR columns, always: rank, player, average, and one
     context column. Move by default; whatever you sorted by if you sorted
     by something the phone hides. Revealing a fifth instead collapsed the
     handles to "@\2026", and the handle is the one thing in the row nobody
     can do without. The widths are narrowed off their inline desktop values,
     which is what the !important is for. */
  .pw-col.pw-show-bull .pw-thead .h-bull{display:inline-flex;width:52px!important}
  .pw-col.pw-show-bull .pw-tr .b-bull{display:block;width:52px!important}
  .pw-col.pw-show-wks .pw-thead .h-wks{display:inline-flex}
  .pw-col.pw-show-wks .pw-tr .b-wks{display:block}
  .pw-col.pw-show-bull .pw-thead .h-move,.pw-col.pw-show-bull .pw-tr .pw-move,
  .pw-col.pw-show-wks .pw-thead .h-move,.pw-col.pw-show-wks .pw-tr .pw-move{display:none}

  /* The weekend strip. On desktop this is one line: label, five films, stamp.
     On a phone the label and the stamp were eating two thirds of the width and
     the five films were being squeezed into what was left, which is what made
     every title wrap mid-word. Label on its own line, one film per row, gross
     pushed to the right edge where the eye already goes for a number. */
  .pw-strip{flex-direction:column;align-items:stretch;gap:11px;padding:15px 16px}
  .pw-strip .list{flex-direction:column;gap:10px;font-size:13.5px}
  .pw-strip .list span{display:flex;align-items:baseline;gap:8px}
  .pw-strip .list i{flex:none;width:13px}
  .pw-strip .list b{flex:1;min-width:0}
  .pw-strip .stamp{align-self:flex-end}
  .pw-tr .pw-flair{display:none}
  .pw-who a,.pw-who span.h{min-width:0}
  .pw-note,.pw-legal{padding-left:16px;padding-right:16px}
}

/* ── Predict the Final ──────────────────────────────────────────────────────
   The second game. Shares this stylesheet because it shares the shell — hero,
   pills, dividers and the .pw-toggle are all reused as-is. Only the call card
   is new, and it is prefixed .pwf- so nothing here can collide with the .pw-
   weekend classes or the .pf- profile classes in account.css.

   The field visualisation USED to reuse the movie pages' pred-bar language.
   Design handoff rev 4 (frame 10a) replaced it with a track whose marks each
   mean one thing — running gross, your call, the model, the field, the median —
   because the borrowed bar could not say where the film actually was. The
   .pred-bar-* copy that lived here has gone with it. */

.pwf-intro{max-width:1100px;margin:0 auto;padding:22px 64px 0;font-size:14.5px;line-height:1.75;color:var(--text-body)}
.pwf-intro b{color:#fff;font-weight:600}
.pwf-intro .lock{color:var(--accent-green-text);font-weight:600}

.pwf-list{max-width:1100px;margin:0 auto;padding:0 64px}

/* ── A call card ───────────────────────────────────────────────────────────
   The card element itself is now just a positioning shell. All the chrome
   lives on .pfd (desktop, frame 10a) or on .pwf-card itself at ≤640px, where
   the mobile subtree takes over — exactly one of the two is ever displayed. */
.pwf-card{margin-top:18px}

/* ═══════════════════════════════════════════════════════════════════════════
   PREDICT THE FINAL — DESKTOP CARD (design handoff rev 4, frame 10a)
   ---------------------------------------------------------------------------
   Replaces the old poster / model-bar / right-rail grid. The bar it used to
   draw was a verbatim copy of the movie page's .pred-bar-* — that copy is gone
   with it, so there is no longer a second place to keep in step when the movie
   page is restyled.

   What the marks mean, because the redesign changed them:
     .pfd-dot    green glowing dot   the RUNNING GROSS
     .pfd-call   dashed green line   YOUR CALL
     .pfd-band   bright green band   the MODEL's range
     .pfd-run    dim green run       the spread of every call the field made
     .pfd-tick   2px white tick      the FIELD MEDIAN
   ═══════════════════════════════════════════════════════════════════════════ */
.pfd{display:grid;grid-template-columns:150px 1fr;background:#111;
  border:1px solid rgba(255,255,255,.09);border-radius:18px;overflow:hidden}
.pwf-card.pwfm-card--settled .pfd{border-color:rgba(34,197,94,.35)}

.pfd-poster{position:relative;border-right:1px solid rgba(255,255,255,.08);min-height:100%}
.pfd-poster .pw-art{position:absolute;inset:0;width:100%;height:100%;border-radius:0;box-shadow:none}
.pfd-poster .pw-art img{width:100%;height:100%;object-fit:cover;display:block}
/* Locked films desaturate rather than grey out — the film is still in theaters,
   it is only your call that is fixed. */
.pfd-poster.is-off .pw-art img{filter:brightness(.75) saturate(.8)}

.pfd-main{display:flex;flex-direction:column;min-width:0}

.pfd-head{position:relative;height:80px;flex-shrink:0}
.pfd-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:center 25%;filter:brightness(.4)}
.pfd-head--off .pfd-bg{filter:brightness(.3) saturate(.7)}
.pfd-scrim{position:absolute;inset:0;background:linear-gradient(to top,#111 5%,rgba(17,17,17,.2) 100%)}
.pfd-headtext{position:absolute;left:20px;bottom:10px;right:20px;display:flex;
  flex-direction:column;gap:3px;min-width:0}
.pfd-title{font-size:18px;font-weight:800;color:#fff;letter-spacing:-.01em;line-height:1.1;
  text-shadow:0 2px 12px rgba(0,0,0,.6);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pfd-hmeta{font-size:11.5px;color:rgba(255,255,255,.6);text-shadow:0 2px 8px rgba(0,0,0,.6);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Lock chip. Carries both class families so initMobile()'s 60s re-render, which
   swaps the whole element's className, cannot strip the desktop styling. */
.pfd-chip{position:absolute;top:12px;right:12px;display:inline-flex;align-items:center;gap:5px;
  font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#eab308;
  background:rgba(10,10,10,.65);backdrop-filter:blur(8px);border:1px solid rgba(234,179,8,.3);
  border-radius:100px;padding:4px 10px;white-space:nowrap}
.pfd-chip--urgent{color:#f87171;border-color:rgba(248,113,113,.35)}
.pfd-chip--locked{color:rgba(255,255,255,.6);border-color:rgba(255,255,255,.15)}
.pfd-chip--settled{color:#052e16;background:#22c55e;border-color:transparent}

.pfd-body{padding:22px 24px 20px;display:grid;grid-template-columns:1fr 216px;gap:26px;
  align-items:stretch;flex:1;min-width:0}
/* EXACTLY TWO grid children: the track column and the rail. The stats line is a
   sibling of the slider in the markup, so without this wrapper the body had
   three children and grid wrapped the rail onto its own row underneath —
   rendering the rail full-width below the track with the stats line floated up
   into the rail's slot. Frame 10a is track-beside-rail; keep it two children. */
.pfd-col{min-width:0;display:flex;flex-direction:column;justify-content:center}

/* ── The track ───────────────────────────────────────────────────────────── */
.pfd-slider{position:relative;padding-top:22px;min-width:0}
.pfd-above{position:relative;height:0}
.pfd-al{position:absolute;top:-22px;transform:translateX(-50%);font-size:11px;
  color:rgba(255,255,255,.45);white-space:nowrap;font-variant-numeric:tabular-nums}
.pfd-al--max{right:0;left:auto;transform:none}

.pfd-track{position:relative;height:10px;background:rgba(255,255,255,.07);border-radius:5px}
.pfd-run{position:absolute;top:0;height:10px;background:rgba(34,197,94,.22);border-radius:5px}
.pfd-band{position:absolute;top:0;height:10px;background:rgba(34,197,94,.65);border-radius:5px}
.pfd-tick{position:absolute;top:-4px;width:2px;height:18px;background:rgba(255,255,255,.85);
  border-radius:1px;transform:translateX(-50%)}
.pfd-call{position:absolute;top:-6px;width:2px;height:22px;transform:translateX(-50%);
  background:repeating-linear-gradient(to bottom,#22c55e 0 3px,transparent 3px 6px)}
.pfd-dot{position:absolute;top:50%;width:20px;height:20px;background:#22c55e;border-radius:50%;
  transform:translate(-50%,-50%);box-shadow:0 0 0 4px rgba(34,197,94,.18),0 2px 10px rgba(0,0,0,.5)}
.pfd-thumb{position:absolute;top:50%;width:22px;height:22px;background:#111;
  border:2.5px solid rgba(255,255,255,.5);border-radius:50%;transform:translate(-50%,-50%);
  cursor:grab;touch-action:none}
.pfd-thumb:focus-visible{outline:2px solid var(--focus-ring,rgba(34,197,94,.55));outline-offset:2px}
.pfd-slider:not(.is-readonly) .pfd-track{cursor:pointer;touch-action:none}

/* Locked: everything greys out except the running-gross dot, which is the one
   thing still moving. */
.pfd-head--off ~ .pfd-body .pfd-run,
.pwf-card--locked .pfd-run{background:rgba(255,255,255,.12)}
.pwf-card--locked .pfd-band{background:rgba(255,255,255,.3)}
.pwf-card--locked .pfd-call{background:repeating-linear-gradient(to bottom,rgba(255,255,255,.6) 0 3px,transparent 3px 6px)}

.pfd-bubble{position:absolute;top:-6px;transform:translate(-50%,-100%);background:#27272a;
  color:rgba(255,255,255,.7);font-size:11px;font-weight:700;border-radius:8px;padding:3px 10px;
  white-space:nowrap;border:1px solid rgba(255,255,255,.12);pointer-events:none}
.pfd-bubble::after{content:"";position:absolute;left:50%;bottom:-5px;transform:translateX(-50%);
  width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;
  border-top:5px solid #27272a}

/* Two label rows below the track. placeDeskLabels() moves the users label down
   to row 2 when it would collide with "so far", and clamps anything that runs
   past an edge — the labels are positioned off live data, so overlap is a
   question of when, not if. */
.pfd-row{position:relative;height:16px;margin-top:10px}
.pfd-row--2{margin-top:3px}
.pfd-l{position:absolute;transform:translateX(-50%);white-space:nowrap;font-size:11.5px;
  font-weight:600;font-variant-numeric:tabular-nums}
.pfd-l--now{color:rgba(255,255,255,.65)}
.pfd-l--users{color:rgba(255,255,255,.6)}
.pfd-l--you{color:#22c55e;font-weight:700}
.pfd-l--you.is-muted{color:rgba(255,255,255,.75)}
.pfd-stats{font-size:11px;color:rgba(255,255,255,.4);margin-top:12px}

/* ── Right rail ──────────────────────────────────────────────────────────── */
.pfd-rail{border-left:1px solid rgba(255,255,255,.07);padding-left:26px;display:flex;
  flex-direction:column;justify-content:center;gap:18px;text-align:center}
.pfd-kick{font-size:10px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:#22c55e}
.pfd-kick--off{color:rgba(255,255,255,.45)}
.pfd-static{font-size:26px;font-weight:800;color:#fff;letter-spacing:-.01em}
.pfd-static--empty{color:rgba(255,255,255,.35)}

/* The input IS the displayed number — 10a's dashed-underline value — rather
   than a display node shadowing a hidden field, so the rail and the track can
   never show two different figures. */
.pfd-rail .pwf-value{margin:0;font-size:26px;font-weight:800;letter-spacing:-.01em;color:#fff;
  background:none;border:none;border-bottom:1px dashed rgba(255,255,255,.4);
  text-align:center;width:100%;padding:0 0 2px;font-family:inherit;cursor:text}
.pfd-rail .pwf-value:focus{outline:none;border-bottom-color:#22c55e}
.pfd-rail .pwf-value::placeholder{color:rgba(255,255,255,.35)}
.pfd-rail .pwf-count{display:none}
.pfd-rail .pwf-note{font-size:11px;margin:-8px 0 0}
.pfd-rail .pwf-note:empty{display:none}

.pfd-cta{width:100%;border-radius:100px;font-size:11.5px;font-weight:800;letter-spacing:.07em;
  text-transform:uppercase;text-align:center;display:flex;align-items:center;justify-content:center;
  gap:7px;white-space:nowrap;font-family:inherit;text-decoration:none;
  /* min-height keeps the four CTA variants the same size: the mock's solid
     button is padded 13px and the two bordered bars 12px, which renders three
     different heights as the card cycles through its states. */
  min-height:44px;padding:12px 0;border:1px solid transparent;box-sizing:border-box}
.pfd-cta--go{background:#22c55e;color:#052e16;cursor:pointer}
.pfd-cta--go:hover{opacity:.85}
.pfd-cta--rest{background:rgba(34,197,94,.1);color:#22c55e;border-color:rgba(34,197,94,.35);cursor:default}
.pfd-cta--locked{background:#18181b;color:rgba(255,255,255,.55);border-color:rgba(255,255,255,.1);
  cursor:default;font-size:10.5px;letter-spacing:.05em}
.pfd-cta--result{background:rgba(34,197,94,.12);color:#22c55e;border-color:rgba(34,197,94,.4)}
.pfd-cta--result:hover{background:rgba(34,197,94,.2)}
.pfd-cta[disabled]{opacity:1}

.pfd .pwf-bar-empty{font-size:12.5px;color:var(--text-faint);line-height:1.6;align-self:center}
.pwf-err{font-size:11.5px;color:#f87171}
.pwf-saved{font-size:11.5px;color:var(--accent-green-text)}

.pwf-empty{max-width:1100px;margin:0 auto;padding:18px 64px 0;font-size:13.5px;
  color:var(--text-faint);line-height:1.7;text-align:center}

/* 641–900px was the one band the redesign left behind: too wide for the mobile
   card, too narrow for a 216px rail beside a readable track. The rail unstacks
   into a row under the slider instead of being squeezed beside it. */
@media(max-width:900px){
  .pwf-intro,.pwf-list,.pwf-empty{padding-left:20px;padding-right:20px}
  .pfd{grid-template-columns:110px 1fr}
  .pfd-body{grid-template-columns:1fr;gap:18px;padding:20px 18px 18px}
  .pfd-col{display:block}
  .pfd-rail{border-left:none;border-top:1px solid rgba(255,255,255,.07);padding-left:0;
    padding-top:16px;display:grid;grid-template-columns:1fr auto;align-items:center;
    gap:6px 18px;text-align:left}
  .pfd-kick{grid-column:1;align-self:end}
  .pfd-static,.pfd-rail .pwf-value{grid-column:1;text-align:left;font-size:22px}
  .pfd-cta{grid-column:2;grid-row:1 / span 2;width:auto;padding:12px 26px}
  .pfd-rail .pwf-count,.pfd-rail .pwf-note{grid-column:1}
}

/* ═══════════════════════════════════════════════════════════════════════════
   PREDICT THE FINAL — MOBILE CARD (design handoff rev 3, frames 8a + 8b)
   ---------------------------------------------------------------------------
   The desktop card is a poster + bar + right rail grid. Below 640px that grid
   was a squeeze: the absolutely-positioned .pred-bar labels overlapped, the
   rail stranded a "Your call" row, and the button orphaned left. Rather than
   patch it, ≤640px swaps to a purpose-built card: backdrop header with a
   per-film lock chip, and a slider whose scale labels sit in a static flex row
   BELOW the track so they can never collide.

   One source of truth: the slider writes into the SAME hidden .pwf-value input
   the desktop rail uses, and .pwfm-cta forwards its click to the rail's real
   button — so saving, validation and RLS errors all run through the existing
   wire() path untouched.
   ═══════════════════════════════════════════════════════════════════════════ */
.pwfm-head, .pwfm-body { display: none; }

@media (max-width: 640px) {
  /* One switch, not a list of structural selectors. The old rule hid the
     desktop pieces individually via `.pwf-card > div > .pwf-title` and friends,
     which made an anonymous <div> wrapper load-bearing — remove or rename it
     and the desktop text reappeared on top of the mobile card. The desktop
     subtree is a single element now, so hiding it is one rule that no DOM
     change can quietly defeat. */
  .pwf-card { display: block; padding: 0; grid-template-columns: none; gap: 0;
              background: #111; border: 1px solid rgba(255,255,255,.09);
              border-radius: 18px; overflow: hidden; }
  .pfd { display: none !important; }

  .pwfm-head, .pwfm-body { display: block; }

  /* ── Backdrop header ─────────────────────────────────────────────────── */
  .pwfm-head { position: relative; height: 88px; }
  .pwfm-bg { position: absolute; inset: 0; width: 100%; height: 100%;
             object-fit: cover; object-position: center 25%; filter: brightness(.4); }
  .pwfm-card--locked .pwfm-bg { filter: brightness(.3) saturate(.7); }
  .pwfm-fade { position: absolute; inset: 0;
               background: linear-gradient(to top,#111 5%,rgba(17,17,17,.2) 100%); }
  .pwfm-chip { position: absolute; top: 10px; right: 10px; display: inline-flex;
               align-items: center; gap: 5px; font-size: 10px; font-weight: 700;
               letter-spacing: .08em; text-transform: uppercase; border-radius: 100px;
               padding: 4px 10px; background: rgba(10,10,10,.65);
               -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
               color: #eab308; border: 1px solid rgba(234,179,8,.3); }
  .pwfm-chip--urgent { color: #f87171; border-color: rgba(248,113,113,.35); }
  .pwfm-chip--locked { color: rgba(255,255,255,.6); border-color: rgba(255,255,255,.15); }
  .pwfm-chip--settled { color: #052e16; background: #22c55e; border-color: #22c55e; }
  .pwfm-thumb { position: absolute; left: 16px; bottom: -26px; width: 52px;
                border-radius: 7px; overflow: hidden; box-shadow: 0 8px 24px rgba(0,0,0,.6);
                border: 1px solid rgba(255,255,255,.12); }
  .pwfm-thumb img { width: 100%; aspect-ratio: 2/3; object-fit: cover; display: block; }
  .pwfm-name { position: absolute; left: 82px; bottom: 10px; right: 16px;
               font-size: 16.5px; font-weight: 800; color: #fff; letter-spacing: -.01em;
               line-height: 1.1; text-shadow: 0 2px 12px rgba(0,0,0,.6); }

  /* ── Body ────────────────────────────────────────────────────────────── */
  .pwfm-body { padding: 34px 16px 18px; display: flex; flex-direction: column; gap: 18px; }
  .pwfm-meta { font-size: 11.5px; color: rgba(255,255,255,.45); }
  .pwfm-meta b { color: rgba(255,255,255,.65); font-weight: 600; }

  /* ── Slider ──────────────────────────────────────────────────────────── */
  .pwfm-slider { position: relative; padding-top: 30px; touch-action: none; }
  .pwfm-bubble { position: absolute; top: 0; transform: translateX(-50%);
                 background: #22c55e; color: #052e16; font-size: 13px; font-weight: 800;
                 border-radius: 8px; padding: 4px 10px; white-space: nowrap;
                 border: 1px solid transparent; cursor: pointer; }
  .pwfm-bubble::after { content: ''; position: absolute; left: 50%; bottom: -5px;
                        transform: translateX(-50%); width: 0; height: 0;
                        border-left: 5px solid transparent; border-right: 5px solid transparent;
                        border-top: 5px solid #22c55e; }
  .pwfm-bubble--empty { background: #27272a; color: rgba(255,255,255,.7); font-size: 12px;
                        font-weight: 700; border-color: rgba(255,255,255,.12); }
  .pwfm-bubble--empty::after { border-top-color: #27272a; }
  .pwfm-bubble--muted { background: #27272a; color: #fff; border-color: rgba(255,255,255,.12); }
  .pwfm-bubble--muted::after { border-top-color: #27272a; }
  .pwfm-bubble--final { background: #fff; color: #0a0a0a; }
  .pwfm-bubble--final::after { border-top-color: #fff; }

  .pwfm-track { position: relative; height: 12px; background: rgba(255,255,255,.07);
                border-radius: 6px; }
  .pwfm-fill { position: absolute; top: 0; height: 12px; left: 0; border-radius: 6px;
               background: linear-gradient(90deg,rgba(34,197,94,.12),rgba(34,197,94,.45)); }
  .pwfm-fill--grey { background: linear-gradient(90deg,rgba(255,255,255,.08),rgba(255,255,255,.22)); }
  .pwfm-tick { position: absolute; top: -4px; width: 2px; height: 20px;
               background: rgba(255,255,255,.7); transform: translateX(-50%); }
  .pwfm-tick--green { background: #22c55e; }
  .pwfm-dot { position: absolute; top: 50%; width: 24px; height: 24px; background: #22c55e;
              border: 4px solid #111; border-radius: 50%; transform: translate(-50%,-50%);
              box-shadow: 0 0 0 1.5px rgba(34,197,94,.6), 0 4px 14px rgba(34,197,94,.4);
              cursor: grab; touch-action: none; }
  .pwfm-dot:active { cursor: grabbing; }
  .pwfm-dot--hollow { background: transparent; border: 2.5px solid rgba(255,255,255,.5);
                      box-shadow: none; }
  .pwfm-dot--small { width: 18px; height: 18px; background: #3f3f46; border-width: 3px;
                     box-shadow: none; cursor: default; }
  .pwfm-dot--final { width: 18px; height: 18px; background: #fff; border-width: 3px;
                     box-shadow: none; cursor: default; }
  .pwfm-dot:focus-visible { outline: 2px solid var(--focus-ring, rgba(34,197,94,.55));
                            outline-offset: 3px; }

  .pwfm-scale { display: flex; justify-content: space-between; font-size: 10.5px;
                color: rgba(255,255,255,.4); margin-top: 8px; gap: 8px; }
  .pwfm-scale b { color: rgba(255,255,255,.6); font-weight: 600; }
  .pwfm-scale .pwfm-acc { color: #22c55e; font-weight: 600; }

  /* Keyboard entry: tapping the bubble reveals the real input in place. */
  .pwfm-edit { position: absolute; top: 0; left: 50%; transform: translateX(-50%);
               z-index: 3; display: none; }
  .pwfm-slider.is-editing .pwfm-edit { display: block; }
  .pwfm-slider.is-editing .pwfm-bubble { visibility: hidden; }
  .pwf-card .pwfm-edit .pwf-value { display: block !important; margin: 0; width: 130px;
               text-align: center; font-size: 13px; font-weight: 800; padding: 5px 8px;
               background: #18181b; color: #fff; border: 1px solid rgba(34,197,94,.5);
               border-radius: 8px; font-family: inherit; }

  /* ── No published model yet ──────────────────────────────────────────────
     A film that opened this Friday has no model until the weekend's numbers
     land, and there is no honest range to draw a slider against — so the
     rail's input is relocated here and simply shown, rather than hidden
     behind a bubble that was never rendered. The dashed underline is the
     weekend board's .pw-gross treatment, so "this number is yours to type"
     looks the same in both games. */
  .pwfm-entry { border: 1px solid rgba(255,255,255,.1); border-radius: 12px;
                background: #18181b; padding: 12px 14px 14px; }
  .pwfm-entry .k { font-size: 10px; font-weight: 700; letter-spacing: .08em;
                   text-transform: uppercase; color: rgba(255,255,255,.4);
                   margin-bottom: 9px; }
  .pwfm-edit--inline { position: static; transform: none; display: block; }
  .pwf-card .pwfm-edit--inline .pwf-value { width: 100%; text-align: left;
               font-size: 25px; font-weight: 800; letter-spacing: -.02em;
               padding: 0 0 4px; background: none; border: none; border-radius: 0;
               border-bottom: 1px dashed rgba(255,255,255,.35); transition: border-color .2s; }
  .pwf-card .pwfm-edit--inline .pwf-value:focus { outline: none;
               border-bottom-color: #22c55e; }
  .pwfm-hint { font-size: 11.5px; line-height: 1.5; color: rgba(255,255,255,.4); }

  /* ── CTA ─────────────────────────────────────────────────────────────── */
  .pwfm-cta { width: 100%; background: #22c55e; color: #052e16; border: none;
              border-radius: 100px; padding: 14px 0; font-size: 12px; font-weight: 800;
              letter-spacing: .08em; text-transform: uppercase; cursor: pointer;
              font-family: inherit; display: flex; align-items: center;
              justify-content: center; gap: 7px; text-decoration: none; }
  .pwfm-cta:active { opacity: .85; }
  .pwfm-cta--locked { background: #18181b; color: rgba(255,255,255,.55);
                      border: 1px solid rgba(255,255,255,.1); cursor: default; }
  .pwfm-cta--result { background: rgba(34,197,94,.12); color: #22c55e;
                      border: 1px solid rgba(34,197,94,.4); }
  /* Resting state: a call is saved and untouched, so there is nothing to do.
     Quiet confirmation rather than a primary action — it goes solid green only
     once the slider actually moves off the saved value. Disabled because it is
     a status, not a target: the slider and the bubble stay the ways to edit. */
  .pwfm-cta--rest { background: rgba(34,197,94,.12); color: #22c55e;
                    border: 1px solid rgba(34,197,94,.4); cursor: default; }
  .pwfm-cta--rest:active { opacity: 1; }
  .pwfm-cta[disabled] { opacity: 1; }
  .pwfm-note { font-size: 11.5px; color: #f87171; text-align: center; }
  .pwfm-note:empty { display: none; }

  /* Settled card gets a green frame (state 4). */
  .pwf-card.pwfm-card--settled { border-color: rgba(34,197,94,.35); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   REV 5 — LAUNCH
   ---------------------------------------------------------------------------
   Everything the rev 5 handoff adds on top of the shipped slice:

     · the shelf, regrouped      2a — three labelled groups + a search fail-safe
     · the dead lock button      ruling 2 — all five picks required to enter
     · 11a  .pw-noentry          locked out with no board, results still open
     · 11b  .pw-gate             signed out of /play (and of /play/board/,
                                 where it sits under a previewed board)
     · 11c  .pw-prov*            Sunday estimates, before Monday settles them
     · 3d   .pw-artband          the cinematic article banner (mirrored into the
                                 article's own <style>, since analysis pages do
                                 not load this file — keep the two in step)

   Base rules here, phone rules in the single @media at the bottom of the file.
   New class names throughout, so nothing above can be quietly overridden.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── The shelf, regrouped (2a) ──────────────────────────────────────────────
   The old shelf was one undifferentiated wall of posters, which quietly asked
   every player to remember which films were new and which were last weekend's.
   Three labelled groups answer that without a word of instruction. */
.pw-shelfnote{max-width:1100px;margin:10px auto 0;padding:0 64px;font-size:12.5px;color:var(--text-tertiary);text-align:center}
.pw-shelfsearch{max-width:420px;margin:16px auto 0;padding:0 64px;position:relative;display:block}
.pw-shelfsearch svg{position:absolute;left:78px;top:50%;transform:translateY(-50%);width:14px;height:14px;stroke:var(--text-faint);fill:none;stroke-width:2;pointer-events:none}
.pw-shelfsearch input{width:100%;background:var(--bg-card);border:1px solid var(--border-medium);border-radius:100px;padding:10px 16px 10px 36px;font-size:13px;color:#fff;font-family:inherit;transition:border-color .2s}
.pw-shelfsearch input::placeholder{color:var(--text-faint)}
.pw-shelfsearch input:focus{outline:none;border-color:var(--accent-green-border)}

.pw-shelfgrp{max-width:1100px;margin:0 auto;padding:22px 64px 0}
.pw-grouphead{font-size:10.5px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:var(--text-muted);padding-bottom:2px;border-bottom:1px solid var(--border-light)}
.pw-grouphead span{color:var(--accent-green-text)}
/* Left-aligned, not centred. .pw-shelf centres because the flat shelf was one
   block of posters; a group of two centred over a group of ten reads as two
   unrelated rows. Tiles are also a shade narrower here so last weekend's top 10
   fits on one line at full width — a group labelled "· 10" that wraps to two
   rows makes the count look like a mistake. */
.pw-shelfgrp .pw-shelf{padding:16px 0 0;justify-content:flex-start;gap:12px}
.pw-shelfgrp .pw-tile{width:86px}
/* A film already on the board stays visible but stops asking to be added —
   removing it would make the group counts lie. */
.pw-tile.is-on{opacity:.4}
.pw-tile.is-on .a{color:var(--text-faint)}
.pw-tile .n{font-size:9.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);margin-top:3px}
.pw-shelf-empty{padding:22px 4px;text-align:center;font-size:12.5px;color:var(--text-faint)}

/* ── Ruling 2: all five picks required ──────────────────────────────────────
   A 45%-opacity green pill still reads as "press me". The handoff asks for a
   button that is plainly not a button yet — flat #27272a, no green, and a
   cursor that says so. */
.pw-pill--dead,.pw-pill--dead:hover{background:#27272a;color:rgba(255,255,255,.45);cursor:not-allowed;opacity:1}

/* ── 11a — no entry, results still browsable ────────────────────────────────*/
.pw-noentry{max-width:880px;margin:22px auto 0;border:1px dashed rgba(255,255,255,.2);border-radius:14px;padding:34px 40px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:10px}
.pw-noentry .i{width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);display:inline-flex;align-items:center;justify-content:center}
.pw-noentry .i svg{width:19px;height:19px;stroke:rgba(255,255,255,.45);fill:none;stroke-width:2;stroke-linecap:round}
.pw-noentry h2{font-size:17px;font-weight:800;color:#fff}
.pw-noentry p{font-size:13px;color:var(--text-tertiary);line-height:1.7;max-width:520px}
.pw-noentry .pw-pill{margin-top:6px}

/* The actuals + podium strips that stay open to a player with no board. */
.pw-finals{max-width:880px;margin:26px auto 0;background:var(--bg-card);border:1px solid var(--border-medium);border-radius:12px;padding:16px 20px}
.pw-finals .l{font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--text-muted);margin-bottom:11px}
.pw-finals .list{display:flex;gap:22px;flex-wrap:wrap;font-size:12.5px;color:var(--text-secondary)}
.pw-finals .list .r{color:var(--text-faint);font-weight:700;margin-right:5px}
.pw-finals .list b{font-weight:700;color:#fff}
.pw-podstrip{max-width:880px;margin:14px auto 0;display:flex;align-items:center;gap:22px;flex-wrap:wrap;padding:0 4px}
.pw-podstrip .p{font-size:12.5px;color:var(--text-secondary)}
.pw-podstrip .p .r{color:var(--accent-yellow-text);font-weight:800;margin-right:6px}
.pw-podstrip .p b{color:#fff;font-weight:700}
.pw-podstrip .pw-link{margin-left:auto}

/* ── 11b — signed out of /play ──────────────────────────────────────────────
   The pitch above still renders for everyone; this is the card that replaces
   the board CTA, so a signed-out visitor reads the game and then meets exactly
   one door. */
.pw-gate{position:relative;max-width:1100px;margin:26px auto 0;border-radius:16px;overflow:hidden;border:1px solid var(--border-medium)}
.pw-gate-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 25%;filter:brightness(.3) blur(2px);transform:scale(1.06)}
.pw-gate-fade{position:absolute;inset:0;background:linear-gradient(90deg,rgba(10,10,10,.9),rgba(10,10,10,.6) 60%,rgba(10,10,10,.4))}
.pw-gate-body{position:relative;z-index:2;padding:40px 48px;text-align:center}
.pw-gate .k{display:inline-flex;align-items:center;gap:7px;font-size:10px;font-weight:800;letter-spacing:.2em;text-transform:uppercase;color:var(--accent-green-text);margin-bottom:12px}
.pw-gate .k svg{width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.pw-gate h2{font-size:26px;font-weight:800;letter-spacing:-.02em;color:#fff}
.pw-gate p{font-size:13.5px;color:var(--text-secondary);line-height:1.7;margin:8px auto 0;max-width:520px}
.pw-gate .pw-ctas{margin-top:20px}
.pw-gate .foot{margin-top:18px;display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;font-size:11.5px;color:var(--text-faint)}

/* ── The signed-out board (Aug 2026) ────────────────────────────────────────
   /play/board/ used to answer a signed-out visitor with a bare card: no field,
   no deadline, nothing that showed what the account bought them. It now draws
   the real board — this weekend's field, an example five, the live countdown —
   and puts the same .pw-gate door where the lock button lives for a member.
   Nothing here is playable: every poster, slot and gross field routes to the
   signup instead, so the cursor has to say 'this leads somewhere', not 'drag
   me'. */
.pw-gate--board{margin-top:34px}
/* The same door inside the field tab, between the consensus board and the
   film rows. Only the vertical rhythm differs: it sits between two .sec blocks
   rather than under the board. */
.pw-gate--field{margin-top:38px;margin-bottom:38px}
.pw-board--preview .pw-card{cursor:pointer}
.pw-board--preview .pw-card:hover{outline:1px solid var(--border-strong);outline-offset:2px}
.pw-board--preview .pw-gross{cursor:pointer}

/* ── A closed board (Aug 2026) ──────────────────────────────────────────────
   Between Thursday 11:59pm and Sunday's scoring the week sits in status 'locked'.
   The board stays on screen as the record of what was committed — read-only,
   no shelf, no unlock. An empty slot is a fact about that entry now, not an
   invitation, so it loses the button affordance. */
.pw-empty--closed{cursor:default;opacity:.5}
.pw-empty--closed .l span{color:var(--text-faint)}

/* ── 11c — Sunday provisional ───────────────────────────────────────────────
   Amber everywhere a number can still move. The rule this encodes: nothing on
   this screen is final until Monday, and the design refuses to let the player
   forget it. */
.pw-provchip{display:inline-flex;align-items:center;gap:6px;font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-yellow-text);background:rgba(234,179,8,.1);border:1px solid rgba(234,179,8,.32);border-radius:100px;padding:6px 13px;white-space:nowrap}
.pw-provchip svg{width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round}
.pw-provbox{max-width:880px;margin:24px auto 0;background:var(--bg-card);border:1px solid rgba(234,179,8,.25);border-radius:14px;padding:22px 26px;display:flex;align-items:center;gap:26px;flex-wrap:wrap}
.pw-provbox .tot{flex-shrink:0}
.pw-provbox .tot .v{font-size:44px;font-weight:800;line-height:1;letter-spacing:-.02em;color:var(--accent-yellow-text)}
.pw-provbox .tot .v span{font-size:17px;font-weight:700;color:var(--text-faint);margin-left:4px}
.pw-provbox .tot .k{font-size:10.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-yellow-text);margin-top:8px}
.pw-provbox .say{flex:1;min-width:260px;font-size:13px;line-height:1.7;color:var(--text-tertiary)}
.pw-provbox .say b{color:#fff;font-weight:600}

.pw-provrows{max-width:880px;margin:20px auto 0;border-top:1px solid var(--border-light)}
.pw-provrow{display:flex;align-items:center;gap:14px;padding:13px 6px;border-bottom:1px solid var(--border-subtle)}
.pw-provrow .s{width:38px;flex-shrink:0;font-size:11.5px;font-weight:800;color:var(--accent-green-text)}
.pw-provrow .s.shift{color:var(--accent-yellow-text)}
.pw-provrow .f{flex:1;min-width:0;font-size:13.5px;font-weight:600;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pw-provrow .c{font-size:12px;color:var(--text-muted);white-space:nowrap}
.pw-provrow .c em{font-style:normal;color:var(--accent-yellow-text)}
.pw-provrow .p{width:44px;text-align:right;font-size:15px;font-weight:800;color:#fff}
.pw-provfoot{max-width:880px;margin:16px auto 0;display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding:0 6px;font-size:12px;color:var(--text-faint)}
.pw-provfoot .pw-link{margin-left:auto}

/* ── 11c rev 2 — the tape ───────────────────────────────────────────────────
   Sunday's pick-by-pick. Every row is one bar on a scale shared by all five,
   so the rows can be read against each other: a $70M call and a $9M call must
   not draw the same length.

   The bar says three things at once. The grey fill is where the film actually
   landed. The white tick is what you called. The coloured span between them is
   the miss — and its DIRECTION is what the old rows could only tell you in
   words. It is encoded three ways deliberately: position (inside the fill when
   you were low, past its end when you were high), hue (orange high / blue low),
   and the word itself in the caption. Hue alone fails a colourblind reader;
   position alone is too quiet to catch while scrolling. Together they are
   unmissable, and any one of them alone is still correct.

   Deliberately NOT here: the gold bullseye stamp. That is Monday's treatment,
   because a bullseye on a studio estimate is a promise the data has not made. */
.pw-tapes{max-width:880px;margin:26px auto 0}
.pw-tape{display:flex;align-items:center;gap:18px;padding:16px 4px;border-bottom:1px solid var(--border-subtle)}
.pw-tape .art{width:52px;height:78px;flex:none;border-radius:7px;object-fit:cover;
  background:#141416;border:1px solid var(--border-medium)}
.pw-tape .art--ph{display:grid;place-items:center;font-size:15px;font-weight:800;color:var(--text-faint)}
.pw-tape--miss .art{filter:grayscale(1) brightness(.45)}
.pw-tape .mid{flex:1;min-width:0}
.pw-tape .h{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.pw-tape .slot{font-size:11px;font-weight:800;color:var(--accent-green-text);flex:none}
.pw-tape .slot.sh{color:var(--accent-yellow-text)}
.pw-tape .t{flex:1 1 0;min-width:0;font-size:14.5px;font-weight:700;color:#fff;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pw-tape .tag{font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-faint);margin-left:auto;flex:none}

.pw-tape .bar{position:relative;height:10px;border-radius:100px;background:rgba(255,255,255,.06);margin-top:12px}
.pw-tape .act{position:absolute;left:0;top:0;bottom:0;border-radius:100px;background:rgba(255,255,255,.2)}
.pw-tape .gap{position:absolute;top:0;bottom:0;border-radius:3px}
.pw-tape .arw{position:absolute;top:50%;width:0;height:0;
  border-top:6px solid transparent;border-bottom:6px solid transparent}
.pw-tape .tick{position:absolute;top:-5px;bottom:-5px;width:2px;background:#fff;border-radius:2px;
  box-shadow:0 0 0 2px rgba(10,10,10,.92)}

/* The two directions, in the game's own two inks rather than a third and fourth
   hue. #fde047 is the bright yellow already carrying the out-of-pool notice and
   the gold badge text; #22c55e is the site green.

   They are a weak pair for a protanope on their own — ΔE 4.2 against the flat
   #eab308, which is why this uses the brighter #fde047 (ΔE 13.4, above the 8
   target). Even so, hue is the THIRD signal here, not the first: position
   (inside the fill vs past its end) and the arrowhead both carry the direction
   on their own, and the caption writes the word. Any one of the three alone is
   still correct.

   Called it HIGH: the miss sits past the end of the fill, arrow out to the
   right — the direction you overshot in. */
.pw-tape--over  .gap{background:#fde047}
.pw-tape--over  .arw{border-left:7px solid #fde047;transform:translate(3px,-50%)}
/* Called it LOW: the miss sits inside the fill, arrow out to the left. */
.pw-tape--under .gap{background:#22c55e}
.pw-tape--under .arw{border-right:7px solid #22c55e;transform:translate(-100%,-50%);margin-left:-3px}

.pw-tape .n{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin-top:10px;font-size:12px}
.pw-tape .n .y{color:var(--text-muted)}
.pw-tape .n .a{color:#fff;font-weight:600}
.pw-tape .n .m{color:var(--text-faint)}
.pw-tape .n .e{margin-left:auto;font-weight:700}
.pw-tape--over  .n .e{color:#fde047}
.pw-tape--under .n .e{color:#22c55e}
.pw-tape--exact .n .e{color:#fff}
.pw-tape .p{width:62px;flex:none;text-align:right}
.pw-tape .p b{display:block;font-size:26px;font-weight:800;line-height:1;letter-spacing:-.02em;color:#fff}
.pw-tape--miss .p b{color:var(--text-faint)}
.pw-tape .p span{display:block;font-size:10px;color:var(--text-faint);margin-top:5px;font-weight:700}

.pw-tape-key{display:flex;gap:20px;flex-wrap:wrap;padding:14px 4px 0;font-size:11px;color:var(--text-faint)}
.pw-tape-key span{display:inline-flex;align-items:center;gap:7px}
.pw-tape-key i{width:14px;height:9px;border-radius:3px;display:inline-block;flex:none}
.pw-tape-key .k-tick{width:2px;height:13px;background:#fff;border-radius:2px}
.pw-tape-key .k-act{background:rgba(255,255,255,.2)}
.pw-tape-key .k-over{background:#fde047}
.pw-tape-key .k-under{background:#22c55e}

@media(max-width:700px){
  .pw-tapes{margin-left:16px;margin-right:16px}
  .pw-tape{gap:13px;padding:15px 0}
  .pw-tape .art{width:42px;height:63px}
  .pw-tape .tag{display:none}
  .pw-tape .t{font-size:13.5px}
  .pw-tape .n{gap:0 12px;font-size:11.5px}
  .pw-tape .n .e{flex:1 1 100%;margin-left:0;margin-top:5px}
  .pw-tape .p{width:46px}
  .pw-tape .p b{font-size:22px}
  .pw-tape-key{gap:12px 16px;font-size:10.5px}
}

/* ── 3d — the cinematic article banner ──────────────────────────────────────
   Also lives, verbatim, in the weekly article's own <style> block. This copy is
   for /play itself and any page that already loads play.css. */
.pw-artband{position:relative;overflow:hidden}
.pw-artband img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 25%;filter:brightness(.3)}
.pw-artband .sc{position:absolute;inset:0;background:linear-gradient(90deg,rgba(17,17,17,.9) 0%,rgba(17,17,17,.55) 55%,rgba(17,17,17,.3) 100%)}
.pw-artband .bd{position:relative;z-index:2;display:flex;align-items:center;gap:24px;padding:26px 72px}
.pw-artband .k{font-size:10px;font-weight:800;letter-spacing:.2em;text-transform:uppercase;color:var(--accent-green-text);margin-bottom:8px}
.pw-artband h3{font-size:22px;font-weight:800;letter-spacing:-.02em;color:#fff;line-height:1.15}
.pw-artband p{font-size:13px;color:rgba(255,255,255,.65);margin-top:6px}

/* ═══════════════════════════════════════════════════════════════════════════
   REV 5 — PHONE (≤700px, the site's breakpoint)
   The handoff draws these at 390. Everything below is the 390 frame's layout
   expressed as the site's own breakpoint, so the game breaks where the rest of
   the site breaks rather than at a second width nobody else uses.
   ═══════════════════════════════════════════════════════════════════════════ */
@media(max-width:700px){
  /* Shelf: groups stack, tiles go four across as mini posters. Four fits
     because the group label now carries the meaning the title used to have to,
     so a truncated title costs less than it did on the flat shelf. */
  .pw-shelfnote{padding:0 16px;text-align:left}
  .pw-shelfsearch{padding:0 16px;max-width:none}
  .pw-shelfsearch svg{left:30px}
  .pw-shelfgrp{padding:18px 16px 0}
  .pw-shelfgrp .pw-tile{width:calc(25% - 7.5px)}
  .pw-shelfgrp .pw-shelf{gap:10px;justify-content:flex-start}
  .pw-shelfgrp .pw-tile .t{font-size:10px;margin-top:5px}
  .pw-shelfgrp .pw-tile .a,.pw-shelfgrp .pw-tile .n{font-size:9px}

  /* The status card stacks: count, then countdown, then the button — the
     handoff's mobile 2a. Side by side, the countdown and the button fight over
     about 150px each and both wrap mid-phrase. */
  .pw-lockbar{flex-direction:column;align-items:stretch;text-align:center;gap:10px;padding:16px 18px}
  .pw-lockbar .pw-count{justify-content:center}

  .pw-noentry{margin:18px 16px 0;padding:26px 20px}
  .pw-noentry h2{font-size:15.5px}
  .pw-noentry p{font-size:12.5px}
  .pw-finals,.pw-podstrip,.pw-provbox,.pw-provrows,.pw-provfoot{margin-left:16px;margin-right:16px}
  .pw-finals .list{flex-direction:column;gap:7px}
  .pw-podstrip{gap:12px}
  .pw-podstrip .pw-link{margin-left:0}

  .pw-gate{margin:20px 16px 0;border-radius:14px}
  .pw-gate-img{filter:brightness(.3)}     /* blur is expensive and buys nothing at this size */
  .pw-gate-fade{background:linear-gradient(90deg,rgba(10,10,10,.92),rgba(10,10,10,.6))}
  .pw-gate-body{padding:28px 20px}
  .pw-gate h2{font-size:20px}
  .pw-gate p{font-size:12.5px}
  .pw-gate .pw-ctas{flex-direction:column}
  .pw-gate .pw-ctas .pw-pill{width:100%}

  /* Provisional: the total goes above the explanation, and each pick row drops
     its caption to a second line rather than squeezing it onto one. */
  .pw-provbox{flex-direction:column;align-items:flex-start;gap:14px;padding:18px 20px}
  .pw-provbox .tot .v{font-size:36px}
  .pw-provbox .say{min-width:0;font-size:12.5px}
  .pw-provrow{flex-wrap:wrap;gap:0 10px;padding:12px 4px}
  .pw-provrow .f{flex:1 1 auto}
  .pw-provrow .p{width:auto;min-width:34px}
  /* The caption drops to its own line; the points must NOT follow it down.
     Ordering the caption last is what keeps slot / film / points on line one,
     which is the line a player scans. */
  .pw-provrow .c{order:2;flex:1 1 100%;margin-top:4px;padding-left:48px;white-space:normal;font-size:11.5px}
  .pw-provfoot .pw-link{margin-left:0}

  .pw-artband .bd{flex-direction:column;align-items:flex-start;padding:22px 16px}
  .pw-artband h3{font-size:19px}
  .pw-artband .pw-pill{width:100%}
}

/* ── The field (Aug 2026) ────────────────────────────────────────────────────
   /play/score/ between Thursday's lock and Sunday's scores. The week is over as
   a thing you can act on and not yet a thing you can be ranked by, and until now
   that window rendered as one sentence promising scores later. This is what goes
   there: the shape of the field, with nobody named but you.

   All aggregate, deliberately. Naming the boards behind the extremes before the
   week is scored turns the leaderboard into something you can partly read early,
   and pins an outlier to a person while they still have to live with it.

   COLOUR. One ordinal ramp, slot 1 → 5, single hue, monotone lightness with
   adjacent steps at least .06 apart, dim end at 2.78:1 on this ground — stepped
   for the dark surface rather than flipped from a light one. Nothing else on the
   page carries colour meaning: films are identified by poster and name, never by
   hue, so the ramp is free to mean rank and only rank. */
/* Slot 1-5 fills. Five steps of one green was the honest ordinal choice — the
   colour carried the order — but five steps cannot separate on a dark surface:
   the old ramp's worst adjacent pair (#22c55e vs #4ade80) measured ΔE 7.9 to
   normal vision against a floor of 15, and slot 5 (#166534) sat at 2.48:1 on
   the card. Unreadable, so it goes categorical: five hues far enough apart to
   be told apart, with the order itself carrying no meaning.

   Slot 1 is gold because slot 1 IS the podium's top step. Literal silver and
   bronze could not follow it: silver is grey by definition (chroma 0.008, below
   the 0.10 floor at which a hue stops doing identity work) and gold beside
   bronze measures ΔE 10.6 — still under the floor, because they are neighbouring
   hues. The medal read survives at slot 1; slots 2-5 are chosen for separation.

   This order was enumerated, not eyeballed: of the 159 orderings of the eight
   documented hues that open on gold and clear every gate, it maximises the
   minimum adjacent distance — CVD ΔE 26.8 (protan/deutan, Machado 2009) and
   normal-vision ΔE 27.5, both better than 3x the old ramp. Re-check with
   scripts/validate_palette.js in the dataviz skill before touching these.

   --fi* is the numeral that sits ON each fill. Near-black clears 5:1 or better
   on four of the five; green is the one that wants white (4.95:1 vs 4.00:1). */
.pw-field{
  max-width:1100px;margin:0 auto;padding:0 40px}

.pw-field .sec{margin-top:44px}
/* Heading and kicker stack; they never share a line. Pushing the kicker right
   with margin-left:auto worked only while both were short — as soon as either
   grew, "The consensus board" and "MOST-PICKED FILM PER SLOT" each wrapped to
   two lines and interleaved down the middle of the page. A block heading with
   the kicker beneath it cannot collide at any width. */
.pw-field .sec-h{display:block;margin-bottom:18px}
.pw-field .sec-h h2{font-size:19px;font-weight:800;letter-spacing:-.015em;color:#fff}
.pw-field .sec-h .c{display:block;margin-top:6px;font-size:11px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--text-faint)}
/* .sec-p and .pw-legend .say are gone: every section's explainer paragraph was
   removed Aug 2026. The charts say it themselves — a heat cell that gets darker
   with more boards does not need a sentence saying so, and the prose was most of
   the page's height. */

/* Tiles. Four facts about the week, no plot — a number this size IS the chart. */
.pw-tiles{display:grid;grid-template-columns:repeat(4,1fr);margin-top:24px;
  border:1px solid var(--border-light);border-radius:14px;background:var(--bg-card);overflow:hidden}
.pw-tiles .t{padding:20px 22px;border-left:1px solid var(--border-light)}
.pw-tiles .t:first-child{border-left:none}
.pw-tiles .v{font-size:30px;font-weight:800;letter-spacing:-.02em;line-height:1;color:#fff;
  font-variant-numeric:tabular-nums}
.pw-tiles .v small{font-size:15px;font-weight:700;color:var(--text-muted);margin-left:3px}
.pw-tiles .l{font-size:10.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-faint);margin-top:9px}
.pw-tiles .n{font-size:11.5px;color:var(--text-muted);margin-top:5px;line-height:1.45}

/* The consensus board — the five most-picked films by slot. Same card language
   as the board's own five, so it reads as a board rather than a chart. */
.pw-cboard{display:grid;grid-template-columns:repeat(5,1fr);gap:10px}
.pw-ccard{position:relative;border-radius:12px;overflow:hidden;background:var(--bg-card);
  border:1px solid var(--border-light)}
.pw-ccard .pw-art,.pw-ccard .pw-ph{border-radius:0;box-shadow:none}
.pw-ccard .pw-art img{filter:brightness(.6)}
.pw-ccard .chip{position:absolute;top:9px;left:9px;width:24px;height:24px;border-radius:7px;
  background:var(--accent-green);color:var(--accent-green-on);font-size:12px;font-weight:800;
  display:flex;align-items:center;justify-content:center;z-index:2}
.pw-ccard .agree{position:absolute;top:9px;right:9px;font-size:10px;font-weight:800;letter-spacing:.04em;
  background:rgba(10,10,10,.72);border:1px solid var(--border-medium);border-radius:100px;
  padding:3px 8px;color:#fff;z-index:2}
.pw-ccard .bd{position:absolute;left:0;right:0;bottom:0;padding:40px 12px 12px;z-index:2;
  background:linear-gradient(transparent,rgba(0,0,0,.92) 55%)}
.pw-ccard .f{font-size:11.5px;font-weight:700;line-height:1.25;color:#fff}
.pw-ccard .g{font-size:19px;font-weight:800;letter-spacing:-.01em;margin-top:6px;color:#fff;
  font-variant-numeric:tabular-nums}
.pw-ccard .s{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-faint);margin-top:3px}

/* Per-film rows. */
.pw-frows{border:1px solid var(--border-light);border-radius:14px;background:var(--bg-card);overflow:hidden}
.pw-frows .hd,.pw-frow{display:grid;grid-template-columns:210px 84px 1fr 220px;gap:20px;
  align-items:center;padding:14px 20px}
.pw-frows .hd{border-bottom:1px solid var(--border-light);background:rgba(255,255,255,.02)}
.pw-frows .hd div{font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--text-faint)}
.pw-frow{border-top:1px solid var(--border-subtle)}
.pw-frow:first-child{border-top:none}
.pw-frow .film{display:flex;align-items:center;gap:11px;min-width:0}
.pw-frow .film .pw-art,.pw-frow .film .pw-ph{width:32px;flex:none;border-radius:5px;box-shadow:none;font-size:11px}
.pw-frow .film .t{font-size:13px;font-weight:700;line-height:1.25;letter-spacing:-.01em;color:#fff}
.pw-frow .film .s{font-size:10.5px;color:var(--text-faint);margin-top:3px;font-variant-numeric:tabular-nums}
.pw-frow .pick{font-size:15px;font-weight:800;color:#fff;font-variant-numeric:tabular-nums}
.pw-frow .pick span{font-size:10.5px;color:var(--text-faint);font-weight:700;display:block;margin-top:2px}

/* Slot distribution, as a five-cell heat row.

   This was a stacked bar with one colour per slot, and five hues cannot be told
   apart at this size on this surface — the green ramp it shipped with measured
   ΔE 7.9 between its worst adjacent pair against a floor of 15, and re-hueing it
   only traded that for a rainbow. Position has no such limit: the cells are fixed
   and equal, so slot N is the same place on every row, the whole column can be
   compared straight down, and one hue is enough.

   Intensity is share of ALL boards, never of the film's own picks — normalised
   per row, a six-board film would read as "everyone put this fifth". The 2px
   gaps are surface, not borders. The 1 and 5 at the ends are the axis; per-cell
   digits would repeat eight times down the table for no gain. */
.pw-slots{display:flex;gap:2px;height:26px;align-items:stretch}
.pw-slots .ax{flex:none;width:10px;align-self:center;text-align:center;font-size:9px;
  font-weight:800;color:var(--text-xfaint);font-variant-numeric:tabular-nums}
.pw-slots .cell{flex:1;min-width:0;border-radius:3px;display:flex;align-items:center;
  justify-content:center;font-size:10px;font-weight:800;font-variant-numeric:tabular-nums}
/* Nobody put the film here. A bare tile, not the palest step of the ramp. */
.pw-slots .cell--none{background:rgba(255,255,255,.035)}

/* The called range. The rule's LENGTH is how far apart the room is on that film
   (low-to-high against its median, scaled to the widest row); the dot inside is
   where the median sits in that range. One shared money axis cannot hold a $4M
   film and a $175M one without rendering every row but the biggest as a dot. */
.pw-range{position:relative;height:42px}
/* Every rule is the same length and spans the column. It used to be scaled to
   the film's spread, which gave eight rows eight different lengths with nothing
   to line them up against, and left the tightest rows too short to fit their own
   end labels — which is what the old 96px floor was patching over. The range is
   now stated by the two end labels; the rule is the axis they sit on and the dot
   is where the median falls between them. One shared axis per row means the dots
   are comparable straight down the column, which is the thing worth reading. */
.pw-range .rule{position:absolute;top:0;left:0;right:0;height:42px}
/* 42px, not 26. At 26 the two end labels sat directly on the rule and the
   median label directly under it, so the row read as one dense smear of digits
   with a green line through it. The numbers are the content here; the rule is
   the axis they hang off, and it needs air on both sides of it. */
.pw-range .track{position:absolute;top:20px;left:0;right:0;height:4px;border-radius:2px;
  background:rgba(34,197,94,.28)}
.pw-range .med{position:absolute;top:16px;width:12px;height:12px;border-radius:50%;
  background:var(--accent-green);border:2px solid var(--acc-ground);transform:translateX(-50%)}
.pw-range .lab{position:absolute;top:0;font-size:9.5px;color:var(--text-faint);font-variant-numeric:tabular-nums}
.pw-range .lab.r{right:0}
.pw-range .medlab{position:absolute;bottom:0;font-size:10.5px;font-weight:800;color:#fff;
  transform:translateX(-50%);white-space:nowrap;font-variant-numeric:tabular-nums}

.pw-legend{display:flex;align-items:center;gap:10px;margin-top:14px;font-size:10.5px;
  color:var(--text-faint);font-weight:700;letter-spacing:.1em;text-transform:uppercase;flex-wrap:wrap}
.pw-legend .sw{display:flex;gap:2px}
.pw-legend .sw i{width:22px;height:9px;border-radius:2px;display:block}

/* The #1 call. One series, one colour — the middle-half story is told by the band
   under the axis rather than by a second fill, which would double-encode height. */
/* Your five against the room's medians — the one attributed board on the page. */
.pw-cmp{display:grid;grid-template-columns:repeat(5,1fr);gap:10px}
.pw-cmp .c{border:1px solid var(--border-light);border-radius:12px;background:var(--bg-card);padding:14px 14px 13px}
.pw-cmp .s{font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--text-faint)}
.pw-cmp .f{font-size:12.5px;font-weight:700;margin-top:8px;line-height:1.25;color:#fff}
.pw-cmp .n{font-size:17px;font-weight:800;margin-top:8px;color:#fff;font-variant-numeric:tabular-nums}
.pw-cmp .d{font-size:11px;margin-top:4px;font-variant-numeric:tabular-nums;color:var(--text-muted)}
.pw-cmp .d.hi{color:var(--accent-green-text)}
.pw-cmp .d.lo{color:#f59e0b}

.pw-fnote{margin-top:14px;font-size:12px;color:var(--text-faint);line-height:1.6;display:flex;gap:9px}
.pw-fnote b{color:var(--text-secondary);font-weight:700}

@media(max-width:900px){
  .pw-field{padding:0 16px}
  .pw-tiles{grid-template-columns:repeat(2,1fr)}
  .pw-tiles .t:nth-child(3){border-left:none}
  .pw-tiles .t:nth-child(n+3){border-top:1px solid var(--border-light)}
  /* The consensus board is one horizontal strip on a phone, exactly as the
     weekend board is — same reason, and the same numbers so the two screens
     scroll identically. Two-up-and-wrap made each card ~179px, so slot 1 and 2
     filled the screen and 3-5 sat below the fold: this is a ranked five and it
     has to be readable AS an order. Negative margin so the cards reach the
     screen edge and it reads as a scroller rather than a clipped grid; the
     padding puts the gutter back inside. No scroll-snap, matching .pw-board
     and the homepage strips. */
  .pw-cboard{display:flex;flex-wrap:nowrap;justify-content:flex-start;
    overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;
    margin:0 -16px;padding:0 16px 6px}
  .pw-cboard::-webkit-scrollbar{display:none}
  .pw-ccard{flex:0 0 auto;width:clamp(132px,38vw,150px)}
  .pw-cmp{grid-template-columns:1fr}
  /* The row's four columns become two rows of two: the film and its share on one
     line, the two plots underneath at full width, where 26px of bar has room to
     be read rather than being crushed into a 90px column. */
  .pw-frows .hd{display:none}
  .pw-frow{grid-template-columns:1fr 92px;gap:18px 16px;padding-top:18px;padding-bottom:18px}
  .pw-slots,.pw-range{grid-column:1 / -1}
}

/* ── The field on /play/ ────────────────────────────────────────────────────
   The landing page draws the same field the score page does, above the slate,
   with its own divider over it. No band, no summary: since migration 0012 the
   whole thing is one ~2KB call, so showing less would have cost a click and
   saved nothing. */
.pw-div--field span i{font-style:normal;color:var(--accent-green-text)}
.pw-div--field{margin-top:40px}
/* The field's own container is narrower than the slate below it, which is
   deliberate — a wall of numbers reads better at a shorter measure than a row
   of posters does. */
.pw-fmore{max-width:1100px;margin:26px auto 0;padding:0 40px;text-align:right}
@media(max-width:900px){
  .pw-fmore{padding:0 16px;text-align:center}
  .pw-fmore .pw-pill{width:100%}
}

/* ── The scored week, on /play/ ─────────────────────────────────────────────
   Between Sunday's scoring and Tuesday's new board there is no week in status
   'open' or 'locked', so PW.currentWeek() correctly returns null and /play/ had
   nothing to draw but "No board open right now" — for the two days the game is
   at its most interesting.

   What goes there instead leads with the weekend itself: the #1 film's own
   backdrop, the podium, and the actual top five as poster cards. The podium and
   the marquee share one 726px measure (three 230px cards and two 18px gaps) so
   they read as a single block rather than two differently-sized things stacked.
   Everything that was on this page before still sits underneath it. */
/* No backdrop image here. The hero directly above this already carries one and
   two photographs stacked read as one mis-registered image rather than two
   sections. The separation is a hairline and a barely-there wash instead. */
.pw-rband{position:relative;border-top:1px solid var(--border-subtle);
  background:radial-gradient(ellipse 60% 70% at 50% 0%,rgba(234,179,8,.05),transparent 70%)}
.pw-rband-body{position:relative;z-index:2;max-width:1100px;margin:0 auto;
  padding:34px 40px 40px;text-align:center}
.pw-rband-h{font-size:31px;font-weight:800;letter-spacing:-.025em;color:#fff;line-height:1.12}
.pw-rband-h a{color:inherit;text-decoration:none;border-bottom:2px solid rgba(234,179,8,.4);
  transition:border-color .15s,color .15s}
.pw-rband-h a:hover{color:var(--accent-yellow-text);border-bottom-color:var(--accent-yellow-text)}
/* Number first and big enough to be read. At 12px in a grey sentence these four
   were decoration; they are the shape of the week. */
.pw-rband-stats{display:flex;gap:44px;flex-wrap:wrap;justify-content:center;margin-top:22px}
.pw-rband-stats > span{display:flex;flex-direction:column;align-items:center;gap:6px}
.pw-rband-stats b{font-size:26px;font-weight:800;line-height:1;letter-spacing:-.02em;color:#fff}
.pw-rband-stats i{font-style:normal;font-size:10px;font-weight:800;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-faint)}
/* The marquee's own heading, above it. The old caption sat underneath at 10.5px
   and ran to nine words, which is a footnote, not a label. */
.pw-rmq-h{margin-top:34px}
.pw-rmq-h h3{font-size:19px;font-weight:800;letter-spacing:-.015em;color:#fff}
.pw-rmq-h span{display:block;margin-top:6px;font-size:11px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-faint)}
/* 230 * 3 + 18 * 2 = 726 — the podium's own natural width, which the marquee
   below then shares so the two read as one block. The cards are flexed rather
   than left at their fixed 230px: at exactly 726 the three of them plus two
   gaps fill the box to the pixel, and sub-pixel rounding was tipping the third
   card onto its own row. */
.pw-rband .pw-podium{max-width:726px;margin:0 auto;padding:26px 0 0;gap:18px;flex-wrap:nowrap}
.pw-rband .pw-pod{width:auto;flex:1 1 0;min-width:0;padding:20px 14px}
.pw-rmq{max-width:726px;margin:16px auto 0;display:grid;grid-template-columns:repeat(5,1fr);gap:12px}
.pw-rmq-t{position:relative;aspect-ratio:2/3;border-radius:11px;overflow:hidden;
  border:1px solid rgba(255,255,255,.14);background:#141416}
.pw-rmq-t img{width:100%;height:100%;object-fit:cover}
.pw-rmq-t .ph{width:100%;height:100%;display:grid;place-items:center;font-size:15px;
  font-weight:800;color:var(--text-faint)}
.pw-rmq-t .fade{position:absolute;inset:0;
  background:linear-gradient(to top,rgba(8,8,9,.96) 0%,rgba(8,8,9,.5) 34%,rgba(8,8,9,0) 60%)}
.pw-rmq-t .rk{position:absolute;top:7px;left:7px;width:21px;height:21px;border-radius:50%;
  display:grid;place-items:center;font-size:11px;font-weight:800;color:#fff;
  background:rgba(10,10,10,.72);border:1px solid rgba(255,255,255,.2)}
.pw-rmq-t .bd{position:absolute;left:0;right:0;bottom:0;padding:0 9px 10px;text-align:left}
.pw-rmq-t .ti{font-size:11px;font-weight:700;color:#fff;line-height:1.25}
.pw-rmq-t .gr{font-size:14px;font-weight:800;color:var(--accent-green-text);margin-top:3px;
  letter-spacing:-.01em}

/* ── Your week, on /play/ ───────────────────────────────────────────────────
   The old version of this was a total and a paragraph, which told a player
   nothing about their own week: 43 does not say whether you called the order
   right and the numbers wrong, or the other way round. The ring is against the
   week's REAL ceiling, the cards are the five films you actually called with
   their points on them, and the split is spelled out. */
.pw-yw{max-width:1100px;margin:22px auto 0;padding:0 40px}
.pw-yw-h{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-bottom:14px}
.pw-yw-h h3{font-size:19px;font-weight:800;letter-spacing:-.015em;color:#fff}
.pw-yw-b{display:flex;align-items:center;gap:26px;flex-wrap:wrap;background:var(--bg-card);
  border:1px solid var(--border-light);border-radius:16px;padding:20px 24px}
.pw-yw-b .ring{position:relative;width:108px;height:108px;flex:none}
.pw-yw-b .ring svg{width:100%;height:100%;display:block}
.pw-yw-b .rv{position:absolute;inset:0;display:grid;place-items:center;align-content:center;line-height:1}
.pw-yw-b .rv b{font-size:34px;font-weight:800;color:#fff;letter-spacing:-.02em}
.pw-yw-b .rv span{font-size:10.5px;font-weight:700;color:var(--text-faint);margin-top:5px}
.pw-yw-b .cards{display:flex;gap:9px;flex:none}
.pw-ywc{position:relative;width:60px;border-radius:8px;overflow:hidden;border:1px solid var(--border-medium);
  background:#141416}
.pw-ywc img{width:100%;display:block;aspect-ratio:2/3;object-fit:cover}
.pw-ywc .ph{aspect-ratio:2/3;display:grid;place-items:center;font-size:13px;font-weight:800;color:var(--text-faint)}
.pw-ywc .fade{position:absolute;inset:0;background:linear-gradient(to top,rgba(8,8,9,.95),rgba(8,8,9,0) 55%)}
.pw-ywc .sl{position:absolute;top:5px;left:5px;font-size:9.5px;font-weight:800;color:#fff;
  background:rgba(10,10,10,.75);border-radius:100px;padding:1px 6px}
.pw-ywc.sh .sl{color:var(--accent-yellow-text)}
.pw-ywc .pt{position:absolute;left:0;right:0;bottom:5px;text-align:center;font-size:19px;font-weight:800;color:#fff}
.pw-ywc.no img,.pw-ywc.no .ph{filter:grayscale(1) brightness(.4)}
.pw-ywc.no .pt{color:var(--text-faint)}
.pw-yw-b .meta{flex:1;min-width:220px;display:flex;gap:26px;flex-wrap:wrap;align-items:baseline}
.pw-yw-b .mr b{font-size:26px;font-weight:800;color:#fff}
.pw-yw-b .mr span{font-size:11.5px;color:var(--text-faint);margin-left:6px}
.pw-yw-b .ml{display:flex;align-items:baseline;gap:5px}
.pw-yw-b .ml span{font-size:10.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--text-faint)}
.pw-yw-b .ml b{font-size:17px;font-weight:800;color:#fff}
.pw-yw-b .ml i{font-style:normal;font-size:11px;color:var(--text-faint)}

.pw-resctas{display:flex;justify-content:center;align-items:center;gap:12px;flex-wrap:wrap;margin-top:26px}

@media(max-width:900px){
  /* One row that scrolls, not two that wrap. Wrapping to 3 + 2 left a ragged
     second row with a hole beside it and pushed everything below it down by a
     whole poster; a swipeable rail keeps the weekend to one band and keeps #5
     — where the out-of-pool surprise lands — reachable rather than cut.
     Bleeds to both edges so the rail reads as scrollable at a glance. */
  .pw-rmq{display:flex;max-width:none;overflow-x:auto;gap:10px;
    margin:16px -16px 0;padding:0 16px 2px;
    scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
    scrollbar-width:none}
  .pw-rmq::-webkit-scrollbar{display:none}
  .pw-rmq-t{flex:0 0 134px;scroll-snap-align:start}
}
@media(max-width:700px){
  .pw-rband-body{padding:26px 16px 28px}
  .pw-rband-h{font-size:22px}
  /* Four counts wrapping 3 + 1 looks like a mistake. Two by two. */
  .pw-rband-stats{display:grid;grid-template-columns:1fr 1fr;gap:18px 12px;margin-top:20px}
  .pw-rband-stats b{font-size:22px}
  .pw-rmq-h{margin-top:26px}
  .pw-rmq-h h3{font-size:16px}
  .pw-rband .pw-podium{padding:22px 0 0;flex-wrap:wrap}
  .pw-rband .pw-pod{flex:0 0 auto;width:100%;max-width:none}
  .pw-rmq{gap:9px;margin-top:18px}
  .pw-yw{padding:0 16px}
  .pw-yw-b{gap:18px;padding:18px 16px}
  .pw-yw-b .cards{flex-wrap:wrap}
  .pw-resctas .pw-pill{width:100%}
}

/* ── Loading skeletons ──────────────────────────────────────────────────────
   Even three waves of queries is a few hundred milliseconds on a phone, and
   content appearing into empty space reads as a glitch rather than as loading.
   These block out the SAME geometry the real thing occupies, so when the data
   lands nothing moves — the shimmer is replaced in place rather than pushing
   the page around, which is the half of this that actually matters.

   They are only ever drawn once the page knows the real thing is coming, so a
   skeleton never appears for content that then turns out not to exist.

   The .pw-sk primitive itself — the gradient and the sweep — now lives in
   account/account.css, because the profile pages needed the same shimmer and
   do not load this file. Every page that loads play.css loads account.css
   first, so it is always defined by the time these rules are read; what stays
   here is only the geometry, which is the part that IS specific to the game. */

.pw-skband .pw-rband-body{display:flex;flex-direction:column;align-items:center}
.pw-skband .sk-eyebrow{width:230px;height:11px;border-radius:100px}
.pw-skband .sk-head{width:min(520px,86%);height:31px;margin-top:16px}
.pw-skband .sk-stats{display:flex;gap:44px;flex-wrap:wrap;justify-content:center;margin-top:24px}
.pw-skband .sk-stats span{display:flex;flex-direction:column;align-items:center;gap:8px}
.pw-skband .sk-stats i{display:block;font-style:normal}
.pw-skband .sk-num{width:44px;height:26px}
.pw-skband .sk-lab{width:78px;height:10px;border-radius:100px}
.pw-skband .sk-pods{display:flex;gap:18px;max-width:726px;width:100%;margin:26px auto 0}
.pw-skband .sk-pod{flex:1 1 0;height:236px;border-radius:14px}
.pw-skband .sk-mqh{width:210px;height:19px;margin-top:34px}
.pw-skband .sk-mq{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;max-width:726px;width:100%;margin:22px auto 0}
.pw-skband .sk-mq div{aspect-ratio:2/3;border-radius:11px}

.pw-sk-pod{width:230px;height:236px;border-radius:14px}
@media(max-width:700px){.pw-sk-pod{width:auto;height:86px}}

/* ── The stage skeleton ────────────────────────────────────────────────────
   /play/score/ and /play/board/ both draw their whole screen into an empty
   #pw-stage, which meant the reader got the nav, the footer and about a
   thousand pixels of nothing until the last query came back. Long enough on a
   phone to read as a broken page rather than a loading one.

   So this ships IN the HTML, above the stage, and is on screen at first paint —
   before supabase-js has downloaded, let alone answered. It is deliberately
   generic: a hero, a card, and a column of rows. Every branch of those pages
   (signed in, signed out, no entry, provisional, final) opens on that shape,
   so the skeleton is honest whichever one wins, and the swap is a removal
   rather than a reflow.

   Heights are matched to the real thing rather than guessed — .sk-hero to
   .pw-hero--mid's 200px, .sk-row to a .pw-tape at 78px of poster plus its
   padding — because a skeleton of the wrong size does the one thing it exists
   to prevent, which is move the page under the reader. */
.pw-skstage{animation:pwSkIn .25s ease-out both}
@keyframes pwSkIn{from{opacity:0}to{opacity:1}}
@media(prefers-reduced-motion:reduce){.pw-skstage{animation:none}}

.pw-skstage .sk-hero{position:relative;min-height:200px;padding:74px 64px 20px;
  display:flex;flex-direction:column;justify-content:flex-end;
  background:linear-gradient(to top,#0a0a0a 0%,#151517 100%)}
.pw-skstage .sk-crumb{width:190px;height:11px;border-radius:100px}
.pw-skstage .sk-h1{width:min(340px,70%);height:32px;margin-top:14px}

.pw-skstage .sk-card{max-width:880px;margin:24px auto 0;height:114px;border-radius:14px}
.pw-skstage .sk-rows{max-width:880px;margin:26px auto 0}
/* min-height, not height: the bars inside carry the texture, and this pins the
   row to what a real .pw-tape measures — 111px wide, 123px narrow, where the
   caption wraps to a second line. Measured against the rendered page rather
   than derived, because the row's height comes from whichever of the poster
   and the text column is taller and that swaps over at the breakpoint. */
.pw-skstage .sk-row{display:flex;align-items:center;gap:18px;padding:16px 4px;
  min-height:111px;box-sizing:border-box;
  border-bottom:1px solid var(--border-subtle)}
.pw-skstage .sk-art{width:52px;height:78px;flex:none;border-radius:7px}
.pw-skstage .sk-mid{flex:1;min-width:0}
.pw-skstage .sk-t{width:min(230px,60%);height:14px}
.pw-skstage .sk-bar{height:10px;border-radius:100px;margin-top:12px}
.pw-skstage .sk-n{width:min(300px,78%);height:11px;margin-top:12px;border-radius:100px}
.pw-skstage .sk-p{width:62px;height:26px;flex:none}

/* The rows fade out down the column. The page is saying how much is coming, not
   claiming to know — the far end of a list is the part it is least sure about,
   so it says so quietly rather than drawing five equally confident
   placeholders and then landing three. */
.pw-skstage .sk-row:nth-child(2){opacity:.82}
.pw-skstage .sk-row:nth-child(3){opacity:.64}
.pw-skstage .sk-row:nth-child(4){opacity:.46}
.pw-skstage .sk-row:nth-child(5){opacity:.28}

/* ── The board's own shape ─────────────────────────────────────────────────
   /play/board/ draws five posters in a row, not five rows in a column, so it
   gets the same primitive in its own geometry rather than the score page's.
   Mirrors .pw-board exactly, including the phone treatment where the five
   become one horizontal strip that bleeds to the screen edge — a skeleton that
   wrapped to a grid there would promise a layout the page never draws. */
.pw-skboard{display:flex;justify-content:center;align-items:stretch;flex-wrap:wrap;
  gap:16px;padding:32px 64px 0}
.pw-skboard .sk-cd{width:190px;aspect-ratio:2/3;border-radius:12px;flex:0 0 auto}
.pw-skboard .sk-cd:nth-child(4){opacity:.7}
.pw-skboard .sk-cd:nth-child(5){opacity:.5}
@media(max-width:700px){
  .pw-skboard{flex-wrap:nowrap;justify-content:flex-start;overflow:hidden;
    gap:10px;padding:32px 16px 0;margin:0 -16px}
  .pw-skboard .sk-cd{width:clamp(132px,38vw,150px)}
}

/* ── Predict the Final's card ──────────────────────────────────────────────
   /play/final/ already fetches in one Promise.all, so its wait is short — but
   short is not nothing, and until the four queries came back the two "Open
   now" and "Settled" dividers sat directly on top of each other with the whole
   page's reason-to-exist missing between them.

   Not the .pw-sk gradient here: the real card is a solid #111 panel with a
   border, and a sweeping block would be a different object arriving at the
   same place. This is that panel with its own contents shimmering inside it,
   which is what the card genuinely looks like a moment before it fills.
   206px desktop, measured off .pfd; the phone card is the taller .pwfm
   subtree. Two skeleton cards, because the fold cuts in below the second. */
/* No container rules. This class rides on the real .pwf-list element, which
   stays put and keeps its own max-width and padding — including the 20px it
   takes below 700px. Styling the container here would out-order that rule and
   quietly reset the gutter on every card the page later draws into it. Only
   the children, which are gone the moment render() runs, are styled. */
.pw-skfinal .sk-fc{margin-top:18px;height:206px;background:#111;border-radius:18px;
  border:1px solid rgba(255,255,255,.09);overflow:hidden;display:grid;
  grid-template-columns:150px 1fr}
.pw-skfinal .sk-fc:nth-child(2){opacity:.55}
.pw-skfinal .sk-fp{background:rgba(255,255,255,.045);border-right:1px solid rgba(255,255,255,.08)}
.pw-skfinal .sk-fm{padding:20px 24px;display:flex;flex-direction:column;gap:16px}
.pw-skfinal .sk-fm .t{width:min(280px,64%);height:18px}
.pw-skfinal .sk-fm .s{width:min(200px,48%);height:12px;border-radius:100px}
.pw-skfinal .sk-fm .tr{height:10px;border-radius:5px;margin-top:auto}
.pw-skfinal .sk-fm .b{width:150px;height:34px;border-radius:100px}
@media(max-width:640px){
  /* Mirrors the .pwfm mobile card: no poster column, an 88px backdrop band at
     the top, and a taller body underneath. */
  .pw-skfinal .sk-fc{display:block;height:292px}
  .pw-skfinal .sk-fp{height:88px;border-right:none;
    border-bottom:1px solid rgba(255,255,255,.08)}
  .pw-skfinal .sk-fm{padding:22px 16px 18px;gap:14px;height:auto}
  .pw-skfinal .sk-fm .b{width:100%}
}

@media(max-width:700px){
  /* 170 rather than the hero's own 150 minimum: on a phone the status chip
     wraps below the headline instead of sitting beside it, and that second row
     is the shape the reader is actually about to get. */
  .pw-skstage .sk-hero{min-height:170px;padding:74px 16px 18px}
  .pw-skstage .sk-h1{height:23px}
  .pw-skstage .sk-card{margin:20px 16px 0;height:176px}
  .pw-skstage .sk-rows{margin-left:16px;margin-right:16px}
  .pw-skstage .sk-row{gap:13px;padding:15px 0;min-height:123px}
  .pw-skstage .sk-art{width:42px;height:63px}
  .pw-skstage .sk-p{width:46px;height:22px}
}

.pw-sktable{max-width:860px;margin:0 auto;padding:26px 20px 0}
.pw-sktable .r{display:flex;align-items:center;gap:14px;padding:13px 0;
  border-bottom:1px solid var(--border-subtle)}
.pw-sktable .a{width:34px;height:34px;border-radius:50%;flex:none}
.pw-sktable .n{flex:1;height:13px;max-width:210px}
.pw-sktable .p{width:44px;height:15px}

@media(max-width:700px){
  .pw-skband .sk-head{height:22px}
  .pw-skband .sk-stats{display:grid;grid-template-columns:1fr 1fr;gap:18px 12px}
  .pw-skband .sk-pods{flex-direction:column;gap:9px;padding:0 16px}
  .pw-skband .sk-pod{height:86px}
  .pw-skband .sk-mq{display:flex;gap:10px;padding:0 16px;overflow:hidden}
  .pw-skband .sk-mq div{flex:0 0 134px}
  .pw-sktable{padding:20px 16px 0}
}

/* ── Out-of-pool notice ────────────────────────────────────────────────────
   Drawn by PW.outOfPoolNote on /play/score/ and /play/leaderboard/ whenever a
   film placed in the top five without having been on that week's board. Amber
   rather than red: it is an explanation, not an error. */
.pw-oop{display:flex;gap:12px;align-items:flex-start;max-width:880px;margin:22px auto 18px;
  padding:14px 16px;border-radius:12px;font-size:13px;line-height:1.65;
  background:rgba(234,179,8,.07);border:1px solid rgba(234,179,8,.28);color:#d8d8dd}
.pw-oop .i{flex:none;width:20px;height:20px;border-radius:50%;display:grid;place-items:center;
  background:rgba(234,179,8,.22);color:#fde047;font-weight:800;font-size:12px;margin-top:1px}
.pw-oop b{color:#fde047;font-weight:700}
@media(max-width:700px){.pw-oop{margin:18px 16px 16px;font-size:12.5px}}


/* On the podium the medal sits above the handle and earns a little more light. */
.pw-pod--champ .pw-champ--lg .pw-champ-medal{
  filter:drop-shadow(0 2px 10px rgba(234,179,8,.5))}

@media(max-width:700px){
  .pw-champ--lg .pw-champ-medal{width:52px;height:52px}
  .pw-champ--lg .pw-champ-t{font-size:11px}
}

/* ── Placing badge ─────────────────────────────────────────────────────────
   Drawn by PW.champBadge(). One shape, three tints; the numeral inside carries
   the placing so it never depends on colour alone. */
.pw-champ{display:inline-flex;align-items:center;gap:8px;vertical-align:middle}
.pw-champ-medal{display:inline-grid;place-items:center;flex:none}
.pw-champ-medal svg{width:100%;height:100%;display:block;overflow:visible}
.pw-champ-medal .lf{opacity:.75}
.pw-champ-t{font-weight:800;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap}

.pw-champ--gold   .pw-champ-medal{color:#f5c542;filter:drop-shadow(0 1px 3px rgba(234,179,8,.35))}
.pw-champ--gold   .pw-champ-t{color:#f5c542}
.pw-champ--silver .pw-champ-medal{color:#cbd2da;filter:drop-shadow(0 1px 3px rgba(203,210,218,.25))}
.pw-champ--silver .pw-champ-t{color:#cbd2da}
.pw-champ--bronze .pw-champ-medal{color:#cc8b52;filter:drop-shadow(0 1px 3px rgba(204,139,82,.3))}
.pw-champ--bronze .pw-champ-t{color:#cc8b52}

.pw-champ--sm .pw-champ-medal{width:22px;height:22px}
.pw-champ--sm .pw-champ-t{font-size:9px;letter-spacing:.08em}
.pw-champ--md .pw-champ-medal{width:32px;height:32px}
.pw-champ--md .pw-champ-t{font-size:10px}
.pw-champ--lg{flex-direction:column;gap:9px}
.pw-champ--lg .pw-champ-medal{width:64px;height:64px}
.pw-champ--lg .pw-champ-t{font-size:11px;letter-spacing:.14em}
.pw-pod--champ .pw-champ--lg .pw-champ-medal{filter:drop-shadow(0 2px 10px rgba(234,179,8,.5))}
@media(max-width:700px){.pw-champ--lg .pw-champ-medal{width:52px;height:52px}}

/* Separator between the listed top of the table and a member's own row pinned
   below it — names the size of the gap so the jump in rank is not a glitch. */
.pw-gaprow{display:flex;align-items:center;gap:12px;padding:9px 0;opacity:.6}
.pw-gaprow::before,.pw-gaprow::after{content:"";flex:1;height:1px;background:rgba(255,255,255,.12)}
.pw-gaprow span{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted)}

/* Footer body text + inline links (TMDB). These were missing here, so the
   TMDB link rendered as a default blue underlined link on every movie page. */
.site-footer p{margin:0 0 4px;line-height:1.7}
.site-footer a{color:var(--text-faint);text-decoration:none;transition:color .2s}
.site-footer a:hover{color:var(--text-tertiary)}

/* Footer nav row — About / Privacy / Terms / Contact. Higher specificity than
   .site-footer a so it wins regardless of source order. */
.site-footer .footer-links{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 20px;margin:0 0 14px;padding:0}
.site-footer .footer-links a{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted);text-decoration:none;transition:color .2s}
.site-footer .footer-links a:hover{color:var(--text-primary)}
@media(max-width:560px){.site-footer .footer-links{gap:6px 13px}.site-footer .footer-links a{font-size:10.5px;letter-spacing:.05em}}

/* The game had a second navigation bar here for about an hour on 21 Aug 2026 —
   Board / Week N / Leaderboard / Rules, stacked directly under .optb-nav. Two
   bars of chrome above every hero is worse than the four navigation idioms it
   replaced: it pushed the hero down, it competed with the site nav for the same
   glance, and with the board merged into the week page there were only ever two
   destinations for it to hold. The two views are switched by the hero toggle
   instead, the leaderboard sits in the week nav at the foot of the page, and the
   rules sit in the legal line. Do not bring it back without solving the stacking
   problem first. */


/* ── The archive index on /play/ ──────────────────────────────────────────
   APPENDED Aug 2026 with the /play/week/ split. /play/ used to close with the
   results band — one scored week rendered in full — and that whole block moved
   to the week's own page. What went in its place is every scored week as a
   single line, so week 31 is reachable from the landing page at all.

   Deliberately a LIST and not cards. The band it replaces was the loudest
   thing on the page and it sat above the pitch; this sits below the slate and
   under the door, where its job is to be scannable and to prove the game has a
   history, not to compete with the hero for attention.

   Four columns on a grid rather than flex space-between: the week numbers and
   the champion scores have to line up down the page or the eye cannot read a
   column, and space-between lines up nothing when the dates labels are
   different lengths. `1fr` on the dates absorbs the difference. */
.pw-arch{max-width:1100px;margin:0 auto;padding:14px 64px 4px}
.pw-arch-i{
  display:grid;grid-template-columns:88px 1fr auto auto;align-items:baseline;gap:16px;
  padding:13px 10px;border-bottom:1px solid var(--border-subtle);
  text-decoration:none;border-radius:6px;transition:background .15s
}
.pw-arch-i:hover{background:rgba(255,255,255,.035)}
.pw-arch-i:focus-visible{outline:2px solid var(--accent-green-text);outline-offset:-2px}
.pw-arch-i .n{font-size:13.5px;font-weight:800;color:var(--text-primary)}
.pw-arch-i .d{font-size:13px;color:var(--text-tertiary)}
/* The status word is a database fact dressed as a label, so it reads as one:
   monospace and tiny, the same treatment the game nav gives its own meta. */
.pw-arch-i .s{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-faint);
  white-space:nowrap
}
.pw-arch-i .w{font-size:12.5px;color:var(--text-muted);white-space:nowrap;text-align:right}
.pw-arch-i .w b{font-weight:800;color:var(--accent-green-text)}
/* Both the status and the champion are best-effort — a week with no rank-1 row
   still renders an empty cell so the grid does not reflow around it. min-width
   keeps that empty cell from collapsing the column it belongs to. */
.pw-arch-i .s:empty,.pw-arch-i .w:empty{min-width:1px}
.pw-arch-empty{
  max-width:1100px;margin:0 auto;padding:26px 64px;
  font-size:13.5px;color:var(--text-tertiary);text-align:center
}
/* Never silently truncated: the count of what is not shown is a line of its
   own, faint but present. */
.pw-arch-more{
  max-width:1100px;margin:0 auto;padding:14px 74px 0;
  font-size:12px;color:var(--text-faint)
}
@media(max-width:700px){
  .pw-arch{padding:10px 16px 4px}
  /* Two rows on a phone: identity on top, the verdict underneath. The four
     columns are 20px of text each at this width and unreadable side by side. */
  .pw-arch-i{grid-template-columns:auto 1fr;gap:4px 12px;padding:12px 6px}
  .pw-arch-i .n{grid-column:1}
  .pw-arch-i .d{grid-column:2;text-align:right;font-size:12.5px}
  .pw-arch-i .s{grid-column:1}
  .pw-arch-i .w{grid-column:2}
  .pw-arch-empty{padding:22px 16px}
  .pw-arch-more{padding:12px 22px 0}
}

/* ══ Scored field view ═══════════════════════════════════════════════════════
   Only reachable once a week has results. Everything here rides the tokens and
   the geometry the unscored field already uses — the point is that the tab
   changes its QUESTION when the week is scored, not that it becomes a different
   screen. */

/* Top score leads in the accent; the rest of the tiles stay ink, so the eye
   lands on the number that is the week's headline. */
.pw-tiles .t .v .win{color:var(--accent-green)}

/* ── The result, against the room ─────────────────────────────────────────── */
.pw-ccard--res .bd .g{color:var(--accent-green)}
.pw-ccard--res .agree.warn{color:#ffb020;border-color:rgba(255,176,32,.4)}
.pw-ccard--res .callrow{display:flex;justify-content:space-between;align-items:baseline;
  gap:8px;margin-top:11px;padding-top:10px;border-top:1px solid var(--border-light);
  font-size:11.5px;color:var(--text-faint)}
.pw-ccard--res .callrow b{color:var(--text-secondary);font-weight:700;
  font-variant-numeric:tabular-nums}
/* Over / under / spot-on are a status, so they ship with the words as well as
   the colour — "Room was $1.1M high" reads without the hue doing any work. */
.pw-ccard--res .delta{margin-top:6px;font-size:11px;font-weight:700;line-height:1.35}
.pw-ccard--res .delta.spot{color:var(--accent-green)}
.pw-ccard--res .delta.over{color:#ffb020}
.pw-ccard--res .delta.under{color:#7dd3fc}

/* ── Where the room landed ────────────────────────────────────────────────── */
/* Scored, the green dot becomes the ACTUAL and the median call steps back to a
   neutral tick. Both hang off the same 22px centre the track already uses, so
   they cannot drift apart. */
.pw-frow.is-scored .pw-range .med.is-call{top:15px;width:2px;height:14px;border-radius:1px;
  background:rgba(255,255,255,.65);border:0}
.pw-range .act{position:absolute;top:16px;width:12px;height:12px;border-radius:50%;
  background:var(--accent-green);border:2px solid var(--acc-ground);transform:translateX(-50%)}
.pw-frow .pick.verdict{font-size:12px;font-weight:800;letter-spacing:.02em;line-height:1.3}
.pw-frow .pick.verdict.in{color:var(--accent-green)}
.pw-frow .pick.verdict.out{color:#ffb020}
.pw-frow .pick.verdict span{display:block;margin-top:3px;font-size:10px;font-weight:600;
  letter-spacing:0;color:var(--text-faint)}

/* ── How the field scored ─────────────────────────────────────────────────── */
.pw-two{display:grid;grid-template-columns:1.05fr 1fr;gap:14px;align-items:stretch}
.pw-panel{display:flex;flex-direction:column;background:var(--bg-card);
  border:1px solid var(--border-light);border-radius:12px;padding:18px}
.pw-panel h3{font-size:13px;font-weight:800;color:#fff;letter-spacing:-.01em}
.pw-panel .ph{font-size:11px;color:var(--text-faint);margin-top:4px}
.pw-hist{display:flex;align-items:flex-end;gap:7px;height:150px;margin-top:22px}
.pw-hist .hb{flex:1;display:flex;flex-direction:column;justify-content:flex-end;
  align-items:center;gap:6px;height:100%}
/* One hue, one series: the median band is the only step up, and the caption
   under the chart names it so the fill is never the only cue. */
.pw-hist .bar{width:100%;min-height:5px;border-radius:4px 4px 0 0;
  background:rgba(34,197,94,.16);border:1px solid rgba(34,197,94,.3)}
.pw-hist .hb.med .bar{background:var(--accent-green);border-color:var(--accent-green)}
.pw-hist .cnt{font-size:11px;font-weight:700;color:var(--text-secondary)}
.pw-hist .hb.med .cnt{color:var(--accent-green)}
.pw-panel .hx{display:flex;gap:7px;margin-top:8px;padding-top:8px;
  border-top:1px solid var(--border-light)}
.pw-panel .hx div{flex:1;text-align:center;font-size:10px;color:var(--text-faint)}
.pw-panel .medline{margin-top:auto;padding-top:14px;font-size:11.5px;color:var(--text-secondary)}
.pw-panel .medline b{color:var(--accent-green);font-weight:700}
.pw-lb{margin-top:2px}
.pw-lb .lbr{display:grid;grid-template-columns:26px 1fr auto auto;gap:11px;align-items:center;
  padding:8px 0;border-top:1px solid var(--border-light);font-size:13px}
.pw-lb .lbr:first-child{border-top:0}
.pw-lb .pos{font-size:11px;font-weight:800;color:var(--text-faint);text-align:right}
.pw-lb .lbr.p1 .pos,.pw-lb .lbr.p2 .pos,.pw-lb .lbr.p3 .pos{color:var(--accent-green)}
.pw-lb .who{color:#fff;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pw-lb .be{font-size:11px;color:var(--text-faint)}
.pw-lb .tot{font-weight:800;color:#fff;font-variant-numeric:tabular-nums}
.pw-lb .lbr.p1 .tot{color:var(--accent-green)}
.pw-more{display:inline-block;margin-top:14px;font-size:11.5px;color:var(--accent-green);
  font-weight:700;text-decoration:none}

@media (max-width:900px){
  .pw-two{grid-template-columns:1fr}
}

/* ── The winning board (leaderboard) ──────────────────────────────────────
   Sits between the podium and the table. Its own container rather than a
   slot inside .pw-col, because the table's column is a list and this is a
   strip: on a phone the strip has to reach the screen edge to read as a
   scroller, and .pw-col's padding would clip it. The 860px matches .pw-col
   so the two stack on one axis, and the 16px side padding at the same 900px
   breakpoint .pw-cboard uses is what its -16px margin pulls against. */
.pw-cwin{max-width:860px;margin:0 auto;padding:26px 20px 0}
.pw-cwin .hd{display:flex;justify-content:space-between;align-items:baseline;
  gap:14px;flex-wrap:wrap;margin-bottom:14px}
.pw-cwin h2{font-size:19px;font-weight:800;letter-spacing:-.015em;color:#fff}
.pw-cwin .c{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-faint)}
/* A slot the winner called in the wrong place still earns its gross points, so
   it keeps its card — the chip goes quiet instead of green to say the order
   point did not land. */
.pw-ccard--win .chip.miss{background:rgba(255,255,255,.14);color:var(--text-secondary)}
@media(max-width:900px){
  .pw-cwin{padding:22px 16px 0}
}

/* ── The member hub (/play/, signed in) ──────────────────────────────────────
   /play/ used to forward a signed-in member straight to their board, on the
   reasoning that everything they came to DO lives elsewhere. True, but it made
   this page the only screen carrying the switch between the two games and then
   guaranteed no member ever saw it — Predict the Final was reachable by typing
   the URL, from a movie page whose film happened to have an open window, or not
   at all. The forward is gone and this is what replaced it: both games as live
   cards, each drawn from the member's own state rather than from a pitch.

   Two cards, deliberately the same weight. Making the weekend game bigger
   because it is older is how the second game stays invisible, and the whole
   point of this page is that neither is subordinate. A third game drops in as
   a third grid cell and needs nothing else.

   The pitch is NOT deleted — a member who asks for it with ?stay=1 still gets
   the rules, the field and the archive exactly as a stranger does. */
.pw-hub{max-width:1100px;margin:0 auto;padding:30px 64px 8px;
  display:grid;grid-template-columns:1fr 1fr;gap:18px}
.pw-hubcard{background:var(--bg-card);border:1px solid var(--border-medium);
  border-radius:16px;padding:22px 24px;display:flex;flex-direction:column}
/* Live = something is open to this member right now. It is a state, not a
   game: whichever card is actionable wears it, and on a quiet Monday neither
   does. */
.pw-hubcard--live{border-color:var(--accent-green-border);
  background:linear-gradient(180deg,rgba(34,197,94,.06),rgba(34,197,94,0) 50%),var(--bg-card)}
.pw-hubcard .k{display:inline-flex;align-items:center;gap:8px;font-size:10px;font-weight:800;
  letter-spacing:.16em;text-transform:uppercase;color:var(--accent-green-text);margin-bottom:12px}
.pw-hubcard .k--wait{color:var(--text-faint)}
.pw-hubcard .k .dot{width:6px;height:6px;border-radius:50%;background:var(--accent-green);
  animation:pwPulse 2.4s ease infinite}
/* index.html has a bwPulse of its own for the homepage promo dot, but that
   keyframe lives in the homepage's inline styles and never reaches a play
   page. Same idea, declared where these dots can actually see it. */
@keyframes pwPulse{0%,100%{opacity:1}50%{opacity:.35}}
.pw-hubcard h2{font-size:20px;font-weight:800;letter-spacing:-.02em;color:#fff;margin-bottom:6px}
.pw-hubcard .st{font-size:13px;line-height:1.55;color:var(--text-tertiary);margin-bottom:16px}
.pw-hubcard .st b{color:#fff;font-weight:700}
/* The thumbnail strip is the card's evidence. Five slots on the weekend side
   (the board, filled or dashed), up to five posters on the Final side. Small
   enough that a missing poster is a shrug rather than a hole. */
.pw-hubmini{display:flex;gap:7px;margin-bottom:18px;min-height:66px}
.pw-hubmini .sl{width:44px;aspect-ratio:2/3;border-radius:6px;overflow:hidden;
  background:linear-gradient(160deg,#232326,#141416);display:flex;align-items:center;
  justify-content:center;font-size:11px;font-weight:800;color:rgba(255,255,255,.3);flex:none}
.pw-hubmini .sl img{width:100%;height:100%;object-fit:cover;display:block}
.pw-hubmini .sl--empty{border:1px dashed rgba(255,255,255,.16);background:none}
/* margin-top:auto is what keeps the two CTAs on one line across cards whose
   status copy wraps to different heights. Without it the buttons stagger. */
.pw-hubfoot{margin-top:auto;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.pw-hubwhen{font-size:11.5px;font-weight:700;color:var(--accent-yellow-text);margin-left:auto}
.pw-hubwhen--quiet{color:var(--text-muted);font-weight:400}
/* One column well before the 700px game breakpoint: two cards each carrying a
   five-poster strip and a pill stop being readable at about 860px, long before
   the phone rules would catch them. */
@media(max-width:860px){
  .pw-hub{grid-template-columns:1fr;padding:24px 16px 4px;gap:14px}
  .pw-hubcard{padding:20px}
}
/* The base pill is sized for a hero. Inside a card it needs to read as one
   action among several, not as the page's headline gesture. */
.pw-hubfoot .pw-pill{padding:10px 22px;font-size:11.5px;letter-spacing:.05em}
