/* App shell page CSS (owner: shell, WP1), after tokens.css and bundle.css: stage geometry and bands, the top-bar
   strip, the art stack, the bottom group, the layouts. index.html's critical CSS is generated from this file
   (tools/halloween/make-critical.mjs): edit here, never there. */

/* ---------- Page geometry (derived; not tokens) ---------- */
:root{
  /* 1u = 1% of the design width (phone width, capped at 480px on tablets) */
  --u:min(1vw,4.8px);
  --art-top:max(var(--sat),var(--sp-5));
  /* The dock's footprint: sp-3 + dock-h + max(sp-3, sab) (Dock) */
  --dock-total:calc(var(--sp-3) + var(--dock-h) + max(var(--sp-3),var(--sab)));
  --vh100:100vh;
  /* landscape cover art box: width = max(100vw, 177.68vh), height = max(56.28vw, 100vh) */
  --art-h:max(56.28vw,var(--vh100));
  /* The bottom group, anchored up from the dock: CTA, then the network/ticker line, then the chips. */
  --stack-cta:calc(var(--dock-total) + var(--sp-6));
  --stack-net:calc(var(--stack-cta) + var(--cta-h) + var(--sp-3));
  --stack-chips:calc(var(--stack-net) + var(--sp-8) + var(--sp-2));
  --net-h:calc(var(--lh-20) + 2 * var(--sp-1) + 2 * var(--hairline)); /* the InlineState stage pill: 30px */
  /* The gate stack's expected heights, to keep it clear of the bottom group on short screens (CountdownPlate box). */
  --digit-box:50px; /* .bf-numeral--countdown line box */
  --narr-h:calc(2 * var(--lh-20)); /* the narrator's two lines (one on compact) */
  --plate-h:calc(var(--sp-1) + var(--lh-18) + var(--sp-1) + var(--digit-box) + var(--sp-1) / 2 + var(--lh-16) + var(--sp-1) + var(--narr-h) + var(--sp-2) + 2 * var(--hairline));
  --banner-h:0px;
  --gate-h:calc(var(--plate-h) + var(--banner-h));
  --kick-h:calc(var(--lh-18) + 2 * var(--sp-1) + 2 * var(--hairline)); /* the 28px kicker pill */
  --tag-h:calc(var(--sp-6) + var(--sp-1)); /* a 28px Tag: the date, the preview ribbon */
  --title-h:80px; /* two t-title lines (40px line boxes) */
  /* The first free line under the top bar and the 28px band that holds the preview ribbon or the date. */
  --under-bar:calc(var(--sat) + var(--topbar-h) + var(--sp-2) + var(--tag-h) + var(--sp-2));
  --after-title-h:calc(2 * 36px + 2 * var(--sp-3) + 2 * var(--hairline)); /* the after title plate: two 36px t-live lines */
  /* Where the gate stack starts (art-cover portrait); the layouts below override it. The Witching banner reads it. */
  --gate-top:calc(var(--art-top) + 73.33 * var(--u));
  --lqip:url("data:image/webp;base64,UklGRsIAAABXRUJQVlA4ILYAAABQBQCdASogABIAPrVKnkmnJCKhMAgA4BaJbACdMtP0obNiVQDyQSCgZfN6CJjMDKWfhAAA/vhNnfxAEO9zyM8V9V4C97MOac0wncZA9Rn6mPm8PoVygb+azTm6XI/6MrWaIS2Bj46aelB/iSbxtk7pZIgvGB+cGpTWaub/DkftTc1aUGlTaQKfjQTmLw+zlItTVeOGXhPr0cFqmsBmvwgqdMzr+3R8LVvqBwf0IFTQNIcPhYAAAA==");
  /* The portrait hero's own LQIP (32×70), so the pre-decode placeholder matches the portrait art (V6). */
  --lqip-portrait:url("data:image/webp;base64,UklGRrABAABXRUJQVlA4IKQBAADQCACdASogAEYAPsFUnEunpSKhszqt+PAYCWwAxQsJith8GXqIdMNXDit13dKJhwFmRS3NUj8S99BpKKmTlH3FbcDP1f+jQiPa8icOf84AAP7+E+BH0UhJESLbjwAoab9iZJ4O4eLSZKUAhnTmz1r7AOhORQKrIp1gPHC8mybnLirREIAO2KG3yjz1eeB0XLVIvs8gfpVmWVLcGKD8TggCYVr8RpVPj+kvIPt53foechooK42ZlBcemZMUoHcz8onozkB7P/0G1Fmttcnd09NsbqBVA8EK44Sb9uu3orO09GMWMQx/ELIlxn9Ig3UyLQ/4hkTlN9dr+rMqqf927JIsOZB4qxocFd24SnlNIFAVpW0kd66yb5nNysWSCMJLtSpFChoCCkLMH7Y5lAxtl+5JePpu3/ac/CuIhKChaxoE22UP0kr1MqIhSI8m1yXYl0JD1rjqruCKbUoOPJPERmUUqccwSZszqnAJOOnx0SlRwGwVg9XyxbsH5KlepJTPLaacP2tLeUHgTNVBEey5WbFDGHOsyeOi03h1PR7EWUo8czywAAA=");
}
@supports (height:100dvh){:root{--vh100:100dvh}}
html:is([data-phase="live"],[data-phase="witching"]){
  /* live call (sp-2 + 36px t-live box) and the narrator */
  --plate-h:calc(var(--sp-1) + var(--sp-2) + 36px + var(--sp-1) + var(--narr-h) + var(--sp-2) + 2 * var(--hairline));
  --banner-h:calc(var(--sp-2) + 2 * var(--lh-20) + 2 * var(--sp-2) + 2 * var(--hairline)); /* gap + the live banner (up to two lines) */
}
/* While the Showdown card shows, it takes the banner's place: a three-line message. */
html:is([data-phase="live"],[data-phase="witching"]):has(#showdownSlot:not([hidden])){--banner-h:calc(var(--sp-2) + 3 * var(--lh-18) + 2 * var(--sp-2) + 2 * var(--hairline))}
html[data-phase="after"]{--plate-h:calc(2 * var(--sp-1) + var(--narr-h) + var(--sp-2) + 2 * var(--hairline))} /* narrator only */
html.compact{--digit-box:42px;--narr-h:var(--lh-20)}

/* ---------- Page base (the bundle's foundations cover the rest) ---------- */
html,body{height:100%}
body{overflow:hidden;overscroll-behavior:none}
/* Dialogs the system does not style yet keep the old reset; every .bf-* dialog styles itself. */
dialog:not([class*="bf-"]){padding:0;border:0;margin:0;background:none;color:var(--text);max-width:none;max-height:none;font:inherit}
dialog:not([open]){display:none}
/* Layout containers on the stage never take a tap; their controls (PlatePill, Button, Dock) turn it back on. */
#topbar,#topCenter,#chips,#ambient,#gateStack{pointer-events:none}
/* Calm keeps the art reveal as a fade (#artVariant's crossfade re-declares its own in scene.css). */
html[data-calm] #bg{transition-duration:var(--dur-ui)!important}

/* ---------- Stage: fixed, never scrolls ---------- */
#stage{position:fixed;inset:0;overflow:hidden;background:linear-gradient(var(--night-950),var(--surface));isolation:isolate}
#sceneBackdrop{position:absolute;inset:-8%;background:var(--lqip) center/cover no-repeat;filter:blur(12px) brightness(.5);transform:scale(1.1)}
/* Cover plate (portrait art-cover): the whole painted arch fits the width (§2.3) */
#sceneArt{position:absolute;z-index:var(--z-art);width:calc(229.04 * var(--u));aspect-ratio:1672/941;left:calc(50% - 114.39 * var(--u));top:var(--art-top);background:var(--bg)}
#sceneArt::before{content:"";position:absolute;inset:0;background:var(--lqip) center/100% 100% no-repeat;filter:blur(4px)}
#sceneSil,#heroPic,#bg,#artVariant{position:absolute;inset:0;width:100%;height:100%;display:block}
#bg{opacity:0;transition:opacity var(--dur-reveal) var(--ease-out);object-fit:cover}
html.art-ready #bg{opacity:1}
#artVariant{opacity:0;object-fit:cover}
#hotspots,#fog,#artFrame{position:absolute;inset:0}
/* Frame 0 silhouette: the moon follows the act (moon), the arch is night-950 (CSS, so the tokens reach it). */
#silMoon stop{stop-color:var(--lilac-300)}
#silMoon stop:first-child{stop-color:var(--moon)}
#sceneSil g{fill:var(--night-950)}
#sceneSil g[fill=none]{fill:none;stroke:var(--night-950)}
#fx,#ambient{position:absolute;inset:0}
#fx{z-index:var(--z-fx)}
#ambient{z-index:var(--z-ambient)}
/* #artFrame is the box the art is painted in, so hotspots, perches and FX stay on their features (V2).
   Portrait art is anchored at the top (D15). */
@media (orientation:portrait){
  html.art-portrait #sceneArt{left:0;top:0;width:100%;height:100%;aspect-ratio:auto;container-type:size}
  html.art-portrait #artFrame{inset:auto;left:50%;top:0;translate:-50% 0;aspect-ratio:1290/2796;width:max(100%,100vh * 1290 / 2796);width:max(100%,100dvh * 1290 / 2796);width:max(100cqw,100cqh * 1290 / 2796)}
  html.art-portrait #sceneArt::before{background-image:var(--lqip-portrait);background-size:cover;background-position:50% 0}
  html.art-portrait :is(#bg,#artVariant){object-position:50% 0}
  html.art-portrait #sceneSil,html.art-portrait #sceneBackdrop{display:none}
}

/* ---------- Top bar strip (brand left, the centre slot, sound right) ---------- */
#topbar{position:fixed;z-index:var(--z-chrome);top:0;left:0;right:0;height:calc(var(--topbar-h) + var(--sat));padding:var(--sat) calc(var(--sp-3) + var(--sar)) 0 calc(var(--sp-3) + var(--sal));display:flex;align-items:center;gap:var(--sp-2);background:linear-gradient(var(--night-950) 0,transparent)}
#soundBtn{margin-left:auto}
#topCenter{flex:1 1 auto;min-width:0;display:flex;justify-content:center;gap:var(--sp-2)}
#topCenter>.bf-tag{flex:0 1 auto;min-width:0}
#liveChip .live-rest{white-space:pre} /* keeps the leading space inside the inline-flex tag */
/* Narrow bar with both centre tags (F35): each tag's second half goes screen-reader-only; app.js collapses the
   brand and sound pills to icons at the same width. */
@media (max-width:479px){
  #topbar.has-both :is(.live-rest,.presence-rest){position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap} /* the .bf-vh recipe */
}
/* Preview (any ?t=): the preview Tag hangs under the top bar, centred. */
#previewRibbon{position:fixed;z-index:var(--z-chrome);top:calc(var(--sat) + var(--topbar-h));left:0;right:0;width:fit-content;max-width:calc(100% - 2 * var(--sp-3));margin:0 auto;pointer-events:none}

/* ---------- Title card: kicker, h1 and date placed on the painted bands ---------- */
#titleCard{position:absolute;z-index:var(--z-content);left:0;right:0;top:var(--art-top);height:calc(128.9 * var(--u))}
#kicker,#partyTitle,#partyWhen{position:absolute;left:0;right:0}
#kicker,#partyWhen{width:fit-content;max-width:100%;margin-inline:auto}
#kicker{top:calc(13.07 * var(--u))}
#partyTitle{top:calc(20.53 * var(--u) + var(--sp-1))}
#partyWhen{top:calc(63.73 * var(--u))}
html:is([data-preview],[data-phase="offseason"]) #kicker{display:none}
html:is([data-phase="live"],[data-phase="witching"],[data-phase="after"],[data-phase="offseason"]) #partyWhen{display:none}
/* After the party the h1 reads the recap title on its plate (TitleCard --after), in the gate. */
html[data-phase="after"] #partyTitle{top:calc(73.33 * var(--u))}
html[data-phase="after"]{--gate-top:calc(var(--art-top) + 73.33 * var(--u) + var(--after-title-h) + var(--sp-2))}

/* ---------- Gate stack (D14): the plate, then the live banner or the Showdown card; sp-2 inside (gap S3) ---------- */
#gateStack{position:absolute;z-index:var(--z-content);left:0;right:0;top:var(--gate-top);display:flex;flex-direction:column;align-items:center;gap:var(--sp-2)}
#showdownSlot{position:static;width:var(--content-w)}
#showdownSlot>*{pointer-events:auto}
#showdownSlot>.bf-stage-banner{width:auto;margin-inline:0} /* the slot already has the content width: the card's edges match the plate */
#liveBanner:has(.bf-stage-banner__sub:empty){display:none}
#stage:has(#showdownSlot:not([hidden])) #liveBanner{display:none}

/* ---------- Bottom group: chips, network line or ticker, the CTA ---------- */
#chips,#netStatus,#ticker,#playCta{position:absolute;z-index:var(--z-content);left:0;right:0;margin-inline:auto}
#chips{bottom:var(--stack-chips);width:var(--content-w);display:flex;gap:var(--sp-2)}
#netStatus,#ticker{bottom:var(--stack-net);max-width:var(--content-w)}
#playCta{bottom:var(--stack-cta);width:var(--cta-w)}
/* Hype voting closes with the party; the goal chip takes the whole row. */
html:is([data-phase="after"],[data-phase="offseason"]) #hypeChip{display:none}

/* ---------- Compact: portrait under 740px tall. No ticker; the network line sits above the chips ---------- */
html.compact #ticker{display:none}
/* One narrator line, so the plate fits between the moon and the chips (gap S3). */
html.compact .bf-countdown-plate__narrator{-webkit-line-clamp:1;line-clamp:1}
html.compact #chips{bottom:var(--stack-net)}
html.compact #netStatus{bottom:calc(var(--stack-net) + var(--hit) + var(--sp-2))}

/* ---------- States ---------- */
/* Hidden page: pause every CSS animation (P6) */
#stage.paused *,#stage.paused *::before,#stage.paused *::after{animation-play-state:paused!important}
/* Arena open: ambient life steps aside (U8, U14); the takeover's own rule is in the bundle. */
html.arena-open #ambient,html.arena-open #fx{visibility:hidden}

/* ---------- TV mode (?tv=1): the shell steps back; tv.js owns #tv (visuals: css/tv.css) ---------- */
html.tv #topbar,html.tv #dock,html.tv #chips,html.tv #playCta,html.tv #ticker,html.tv #netStatus,html.tv #ambient,html.tv #hotspots,html.tv #previewRibbon{display:none}
html.tv,html.tv *{cursor:none}

/* ---------- Portrait art: text on the painting's bands (V7, V3, V10) ----------
   --fh/--ft: #artFrame's height and top, so a percentage is one of the painting. hero-portrait-v1: arch crown
   18–27%, moon 30–40%, gate doors 42–66%. Kicker at 6%, the h1 under it, the date under the moon (39.5%), the gate
   stack in the doors, held sp-2 clear of the bottom group (--bottom-top) on short screens. */
@media (orientation:portrait){
  html.art-portrait{
    --fh:max(100vh,100vw * 2796 / 1290);--fh:max(100dvh,100vw * 2796 / 1290);
    --ft:0px;
    --kick-top:max(calc(var(--sat) + var(--topbar-h) + var(--sp-2)),calc(var(--ft) + var(--fh) * .06));
    --title-top:calc(var(--kick-top) + var(--kick-h) + var(--sp-1));
    --title-floor:calc(var(--title-top) + var(--title-h) + var(--sp-2)); /* the first line under the h1 */
    --bottom-top:calc(var(--vh100) - var(--stack-chips) - var(--hit));
    --when-raw:max(var(--title-floor),calc(var(--ft) + var(--fh) * .395));
    /* The date rides on the plate, but never above the title floor (the plate follows it down). */
    --gate-top:max(calc(var(--title-floor) + var(--tag-h) + var(--sp-1)),min(calc(var(--when-raw) + var(--tag-h) + var(--sp-1)),calc(var(--bottom-top) - var(--sp-2) - var(--gate-h))));
    --when-top:calc(var(--gate-top) - var(--tag-h) - var(--sp-1));
  }
  /* Compact: the h1 takes the kicker's band; the net line is reserved only while it shows. The date moves under
     the h1, so the plate can start under the moon (40%). */
  html.art-portrait.compact{
    --title-top:var(--kick-top);
    --bottom-top:calc(var(--vh100) - var(--stack-net) - var(--hit));
    --when-top:var(--title-floor);
    --gate-top:max(calc(var(--title-floor) + var(--tag-h) + var(--sp-2)),min(calc(var(--ft) + var(--fh) * .4 + var(--sp-1)),calc(var(--bottom-top) - var(--sp-2) - var(--gate-h))));
  }
  html.art-portrait.compact:has(#netStatus:not([hidden])){--bottom-top:calc(var(--vh100) - var(--stack-net) - var(--hit) - var(--sp-2) - var(--net-h))}
  html.art-portrait.compact[data-preview]{--title-top:max(var(--kick-top),var(--under-bar) - var(--sp-2))}
  /* Live and Witching: the date is old news, so the plate takes its slot. */
  html.art-portrait:is([data-phase="live"],[data-phase="witching"]){
    --gate-top:max(var(--title-floor),min(calc(var(--when-raw) - var(--sp-1)),calc(var(--bottom-top) - var(--sp-2) - var(--gate-h))));
  }
  /* After: the h1 plate in the gate (50%), the narrator's plate under it (V10). */
  html.art-portrait[data-phase="after"]{
    --after-top:min(calc(var(--ft) + var(--fh) * .5),calc(var(--bottom-top) - var(--sp-2) - var(--gate-h) - var(--sp-2) - var(--after-title-h)));
    --gate-top:calc(var(--after-top) + var(--after-title-h) + var(--sp-2));
  }
  /* Compact after: Batface (28–35%) and the sun (40–45%) leave no room in the gate, so the thanks plate takes the
     h1's band and the narrator's plate sits low in the gate. */
  html.art-portrait.compact[data-phase="after"]{
    --after-top:var(--title-top);
    --gate-top:max(calc(var(--after-top) + var(--after-title-h) + var(--sp-2)),min(calc(var(--ft) + var(--fh) * .5),calc(var(--bottom-top) - var(--sp-2) - var(--gate-h))));
  }
  html.art-portrait #titleCard{top:0;height:0}
  html.art-portrait #kicker{top:var(--kick-top)}
  html.art-portrait #partyTitle{top:var(--title-top)}
  html.art-portrait #partyWhen{top:var(--when-top)}
  html.art-portrait[data-phase="after"] #partyTitle{top:var(--after-top)}
  /* The Witching Hour banner sits in the plate's slot (the plate steps aside while it shows). */
  html.art-portrait #witchingBanner{top:calc(var(--gate-top) - var(--sp-5))}
}

/* ---------- Landscape (all): full art, cover-style; the painted title shows (§2.6, §2.7) ---------- */
@media (orientation:landscape){
  :root{
    /* The plate centres on the gate line (69% of the art box); vh100/2, so it means the same in every box. */
    --gate-top:calc(var(--vh100) / 2 + .19 * var(--art-h) - var(--plate-h) / 2);
  }
  html[data-phase="after"]{--gate-top:calc(var(--vh100) / 2 + .28 * var(--art-h) + var(--sp-2))}
  #sceneBackdrop{display:none}
  #sceneArt{width:max(100vw,calc(var(--vh100) * 1.7768));left:50%;top:50%;transform:translate(-50%,-50%)}
  #titleCard{top:calc(50% - var(--art-h) / 2);height:var(--art-h)}
  #kicker{display:none}
  /* 16% of the art box, but never under the top bar. */
  #partyTitle{top:max(16%,calc(var(--sat) + var(--topbar-h) + var(--sp-2) + var(--art-h) / 2 - var(--vh100) / 2))}
  #partyWhen{top:49.4%}
  /* After: the thanks plate sits sp-2 above the narrator's plate (bottom measured from the art box's bottom). */
  html[data-phase="after"] #partyTitle{top:auto;bottom:calc(var(--art-h) / 2 + var(--vh100) / 2 - var(--gate-top) + var(--sp-2))}
}

/* Landscape phones: rail dock, bottom-left action row (§2.6); the stage centres left of the rail (G15). */
@media (orientation:landscape) and (max-height:500px){
  :root{
    /* The action row (CTA, chips) and, while the net line shows above it, that line too. */
    --row-h:var(--sp-12);--net-r:0px;
    --row-top:calc(var(--vh100) - var(--sp-3) - var(--sab) - var(--row-h) - var(--sp-2) - var(--net-r));
    /* On the gate line, but never under the h1 (it sits under the date or the preview ribbon) and sp-2 clear of the
       action row. */
    --gate-top:max(calc(var(--under-bar) + var(--title-h) + var(--sp-2)),min(calc(var(--vh100) / 2 + .1 * var(--art-h) - var(--plate-h) / 2),calc(var(--row-top) - var(--plate-h))));
    --digit-box:42px;
  }
  /* A CTA with a sub-line (a Showdown's, a final-hour's) grows past sp-12; while the net line shows, the sub-line
     gives way to it (there is no room for both under the plate). */
  html:has(#ctaSub:not([hidden])):not(:has(#netStatus:not([hidden]))){--row-h:calc(var(--sp-12) + var(--lh-16))}
  html:has(#netStatus:not([hidden])) #ctaSub{display:none}
  html:has(#netStatus:not([hidden])):not(:has(#showdownSlot:not([hidden]))){--net-r:calc(var(--net-h) + var(--sp-2))}
  /* While the Showdown card shows (bottom left, over the CTA), the plate moves to the right of it. */
  #gateStack:has(>#showdownSlot:not([hidden])) #countdownPlate{width:min(var(--content-w),100% - 2 * var(--gutter) - min(360px,50vw) - var(--sp-2));margin-inline:auto var(--gutter)}
  /* The h1 sits under the date (fixed top left) or the preview ribbon. */
  #partyTitle{top:calc(var(--under-bar) + var(--art-h) / 2 - var(--vh100) / 2)}
  /* After: the thanks plate on the gate line, sp-2 above the action row, clear of the plaque and Batface. */
  html[data-phase="after"] #partyTitle{top:auto;bottom:calc(var(--art-h) / 2 + var(--vh100) / 2 - var(--row-top))}
  #topbar{padding-right:calc(var(--rail-w) + var(--sp-2) + var(--sar))}
  #titleCard,#gateStack{right:var(--rail-w)}
  #partyWhen{position:fixed;top:calc(var(--sat) + var(--topbar-h) + var(--sp-2));left:calc(var(--gutter) + var(--sal));right:auto;margin:0;max-width:calc(50vw - 2 * var(--gutter))}
  #previewRibbon{left:calc(50vw - var(--gutter) + var(--sal));right:calc(var(--rail-w) + var(--sar))} /* centred right of the date's half */
  #narrator,#ticker,#liveBanner{display:none}
  html[data-phase="after"] #countdownPlate{display:none} /* its narrator is the only thing on it */
  #showdownSlot{position:fixed;bottom:calc(var(--sp-3) + var(--sab) + var(--row-h) + var(--sp-2));left:calc(var(--gutter) + var(--sal));width:min(360px,50vw)}
  #playCta{left:calc(var(--gutter) + var(--sal));right:auto;margin:0;bottom:calc(var(--sp-3) + var(--sab));width:200px;min-height:var(--sp-12)}
  #chips,html.compact #chips{left:calc(var(--gutter) + var(--sal) + 200px + var(--sp-2));right:auto;margin:0;bottom:calc(var(--sp-3) + var(--sab));width:auto;max-width:calc(100% - var(--rail-w) - var(--sar) - var(--sal) - 200px - 3 * var(--gutter))}
  #chips>.bf-plate-pill{flex:0 0 auto}
  #netStatus,html.compact #netStatus{left:calc(var(--gutter) + var(--sal));right:auto;margin:0;bottom:calc(var(--sp-3) + var(--sab) + var(--row-h) + var(--sp-2))}
  /* The Showdown card takes the net line's slot: the line moves up into the date's band (hidden while live). */
  #stage:has(#showdownSlot:not([hidden])) #netStatus{top:calc(var(--sat) + var(--topbar-h) + var(--sp-2));bottom:auto}
}
@media (orientation:landscape) and (max-height:500px){
  :root{--plate-h:calc(var(--sp-1) + var(--lh-18) + var(--sp-1) + var(--digit-box) + var(--sp-1) / 2 + var(--lh-16) + var(--sp-2) + 2 * var(--hairline))} /* no narrator here */
  html:is([data-phase="live"],[data-phase="witching"]){--plate-h:calc(var(--sp-1) + var(--sp-2) + 36px + var(--sp-2) + 2 * var(--hairline))}
}

/* Landscape tablets and desktop: floating pill dock, left action column, right drawers (§2.7). */
@media (orientation:landscape){
  html:is([data-phase="live"],[data-phase="witching"]):has(#showdownSlot:not([hidden])){--banner-h:calc(var(--sp-2) + 4 * var(--lh-18) + 2 * var(--sp-2) + 2 * var(--hairline))} /* the card's kicker shows: four lines */
}
@media (orientation:landscape) and (min-height:501px){
  :root{--gate-top:min(calc(var(--vh100) / 2 + .19 * var(--art-h) - var(--plate-h) / 2),calc(var(--vh100) - var(--sp-6) - var(--dock-h) - var(--sab) - var(--sp-2) - var(--gate-h)))}
  #playCta{left:calc(var(--sp-6) + var(--sal));right:auto;margin:0;bottom:calc(var(--sp-6) + var(--dock-h) + var(--sp-4) + var(--sab));width:260px}
  #ticker,#netStatus{left:calc(var(--sp-6) + var(--sal));right:auto;margin:0;max-width:260px;bottom:calc(var(--sp-6) + var(--dock-h) + var(--sp-4) + var(--sab) + var(--cta-h) + var(--sp-3))}
  /* Sized by content within the 260px action column (G7), wrapping upward to a second row on party-night numbers
     ("14,144 / 20,000 spooked"), so no chip truncates (V14) and none reaches the plate. */
  #chips,html.compact #chips{left:calc(var(--sp-6) + var(--sal));right:auto;margin:0;width:auto;max-width:260px;flex-wrap:wrap;bottom:calc(var(--sp-6) + var(--dock-h) + var(--sp-4) + var(--sab) + var(--cta-h) + var(--sp-3) + var(--sp-8) + var(--sp-2))}
  #chips>.bf-plate-pill{flex:0 0 auto}
  /* The centre column never reaches the left action column (G7). */
  :is(#titleCard,#countdownPlate,#liveBanner,#showdownSlot){width:min(var(--content-w),100vw - 2 * (var(--sp-6) + 260px + var(--sp-4)))}
}
@media (orientation:landscape) and (min-height:501px){
  html[data-phase="after"]{--gate-top:min(calc(var(--vh100) / 2 + .28 * var(--art-h) + var(--sp-2)),calc(var(--vh100) - var(--sp-6) - var(--dock-h) - var(--sab) - var(--sp-2) - var(--gate-h)))}
}

/* ---------- Goal sheet (goal.js): Meter, ListRow and StatusCircle; .goal-ms and .goal-state stay as hooks ---------- */
.goal-meter{margin:0 0 var(--sp-3)}
