:root{
  --bg:#f2f4f7;--paper:#ffffff;--ink:#1c2230;--muted:#5d6675;--line:#d9dee6;--soft:#eef1f5;
  --ball:#ffffff;--ballink:#1c2230;--ballring:#b9c1cc;--pb:#d3232c;--pbink:#ffffff;
  --ok:#1f7a4d;--okbg:#e6f4ec;--warn:#b5471b;--warnbg:#fbeee6;--accent:#1f4fd8;--accentink:#fff;
  box-sizing:border-box;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);
  font-family:"IBM Plex Sans",-apple-system,"Segoe UI",Roboto,sans-serif;font-variant-numeric:tabular-nums;
}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){
  --bg:#0f141c;--paper:#161d28;--ink:#e8edf4;--muted:#98a3b3;--line:#2b3542;--soft:#1e2734;
  --ball:#f4f6f8;--ballink:#1c2230;--ballring:#3b4756;--okbg:#153426;--ok:#6fd39a;--warnbg:#3a1f12;--warn:#f0a07a;--accent:#5b85ff;}}
:root[data-theme="dark"]{
  --bg:#0f141c;--paper:#161d28;--ink:#e8edf4;--muted:#98a3b3;--line:#2b3542;--soft:#1e2734;
  --ball:#f4f6f8;--ballink:#1c2230;--ballring:#3b4756;--okbg:#153426;--ok:#6fd39a;--warnbg:#3a1f12;--warn:#f0a07a;--accent:#5b85ff;}
html{scroll-padding-top:env(safe-area-inset-top,0px);scroll-behavior:smooth}
@media (prefers-reduced-motion: reduce){html{scroll-behavior:auto}}
*{box-sizing:border-box} body{margin:0;background:var(--bg);color:var(--ink);line-height:1.5}
.wrap{max-width:1040px;margin:0 auto;padding:0 18px 60px}
header{padding:22px 0 8px;display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}
.brand{font-weight:700;font-size:18px;display:flex;align-items:center;gap:8px}
nav a{color:var(--muted);text-decoration:none;font-size:14px;margin-left:16px} nav a:hover{color:var(--ink)}
.hero{padding:36px 0 22px}
h1{font-size:clamp(28px,4.5vw,42px);font-weight:700;line-height:1.1;letter-spacing:-.02em;margin:0 0 12px;max-width:16ch}
.lead{font-size:18px;color:var(--muted);max-width:60ch;margin:0 0 22px}
h2{font-size:20px;font-weight:600;margin:0 0 10px;letter-spacing:-.01em}
p{margin:0 0 10px} .muted{color:var(--muted);font-size:14px}
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin:22px 0}
.stat{background:var(--paper);border:1px solid var(--line);border-radius:10px;padding:14px 16px}
.stat b{display:block;font-size:24px;font-weight:600;letter-spacing:-.02em}
.stat span{font-size:13px;color:var(--muted)}
section{background:var(--paper);border:1px solid var(--line);border-radius:12px;padding:20px;margin:16px 0}
section.plain{background:none;border:none;padding:8px 0}
.row{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
input,select,button{font:inherit;font-size:16px;padding:10px 12px;border-radius:8px;border:1px solid var(--line);background:var(--paper);color:var(--ink)}
input.n{width:60px;text-align:center;font-weight:600} input[type=date]{width:165px}
button{cursor:pointer;background:var(--accent);color:var(--accentink);border-color:var(--accent);font-weight:500}
button.quiet{background:var(--soft);color:var(--ink);border-color:var(--line)}
button:focus-visible,input:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.balls{display:inline-flex;gap:5px;vertical-align:middle}
.ball{width:34px;height:34px;border-radius:50%;background:var(--ball);color:var(--ballink);border:1.5px solid var(--ballring);display:inline-flex;align-items:center;justify-content:center;font-weight:600;font-size:15px}
.ball.pb{background:var(--pb);color:var(--pbink);border-color:var(--pb)}
.ball.hit{box-shadow:0 0 0 3px var(--ok)}
.big .ball{width:44px;height:44px;font-size:18px}
.msg{margin-top:12px;padding:12px 14px;border-radius:8px;font-size:16px}
.ok{background:var(--okbg);color:var(--ok)} .warn{background:var(--warnbg);color:var(--warn)}
table{width:100%;border-collapse:collapse;font-size:14px;margin-top:10px}
th,td{padding:8px 6px;border-bottom:1px solid var(--line);text-align:left;vertical-align:middle;white-space:nowrap}
th{color:var(--muted);font-weight:500;position:sticky;top:0;background:var(--paper)}
.scroll{max-height:440px;overflow:auto;border:1px solid var(--line);border-radius:8px;margin-top:10px}
.scroll table{margin:0} .tablewrap{overflow-x:auto}
.struck td.combo{opacity:.55} .prize{font-weight:600;color:var(--ok)}
pre{background:var(--soft);padding:10px 12px;border-radius:8px;overflow-x:auto;font-size:13px;margin:10px 0 0}
.tiny{font-size:13px} label{font-size:14px;color:var(--muted)}
.btn{display:inline-block;padding:10px 14px;border-radius:8px;background:var(--accent);color:var(--accentink);text-decoration:none;font-weight:500}.btn.quiet{background:var(--soft);color:var(--ink);border:1px solid var(--line)}
.del{background:none;border:none;color:var(--muted);padding:2px 6px;font-size:16px}
.latest{display:flex;flex-wrap:wrap;align-items:center;gap:14px;margin:10px 0 0}
.odds td:first-child{white-space:normal}
footer{margin-top:40px;padding-top:18px;border-top:1px solid var(--line);color:var(--muted);font-size:13px;max-width:80ch}
.localnote{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--warn);margin:-8px 0 10px}
.localnote[hidden]{display:none}
.localnote::before{content:"!";flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:16px;height:16px;border-radius:50%;border:1px solid currentColor;font-size:11px;font-weight:600}

/* ============================================================
   Cinematic shell: fixed ball backdrop, pinned hero panels,
   theme switch, disclaimer sheet. Everything below is layered
   on top of the plain app styles above, so if it were deleted
   the checker would still work exactly as before.
   ============================================================ */
:root{
  --ease:cubic-bezier(.22,.61,.36,1);
  --display:"Inter Tight","IBM Plex Sans",-apple-system,"Segoe UI",Roboto,sans-serif;
  --veilc:242,244,247;   /* the page background as a raw triplet, for rgba() washes */
  --veilmid:.50;         /* how much paper sits under the headline (see .veil) */
  --ballA:#ffffff; --ballB:#b6c1d0; --ballEdge:#8d99a9; --ballNum:#1c2230;
  --glass:rgba(255,255,255,.72);
}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){
  --veilc:15,20,28;
  --veilmid:.66;
  --ballA:#e9edf3; --ballB:#9aa5b6; --ballEdge:#6b7686; --ballNum:#141a24;
  --glass:rgba(22,29,40,.72);
}}
:root[data-theme="dark"]{
  --veilc:15,20,28;
  --veilmid:.66;
  --ballA:#e9edf3; --ballB:#9aa5b6; --ballEdge:#6b7686; --ballNum:#141a24;
  --glass:rgba(22,29,40,.72);
}
body{overflow-x:hidden}
h1,h2,.brand,.mark{font-family:var(--display);letter-spacing:-.022em}

/* ---- fixed backdrop: canvas balls + wash + grain ---- */
.bgstage{position:fixed;inset:0;z-index:0;overflow:hidden;background:var(--bg);pointer-events:none}
#balls{position:absolute;inset:0;display:block;width:100%;height:100%}
/* the radial is a soft pool of paper UNDER the headline: the balls stay
   readable at the edges of the frame and never fight the type in the middle */
.veil{position:absolute;inset:0;pointer-events:none;background:
  radial-gradient(72% 56% at 50% 46%, rgba(var(--veilc),var(--veilmid)) 0%, rgba(var(--veilc),calc(var(--veilmid) * .45)) 58%, rgba(var(--veilc),0) 100%),
  linear-gradient(to bottom, rgba(var(--veilc),.86) 0%, rgba(var(--veilc),.18) 26%, rgba(var(--veilc),.26) 72%, rgba(var(--veilc),.90) 100%);}
/* fine noise so the flat wash never bands on a wide gradient */
.grain{position:absolute;inset:-50%;opacity:.10;mix-blend-mode:multiply;pointer-events:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='.5'/></svg>");}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .grain{mix-blend-mode:screen;opacity:.05}}
:root[data-theme="dark"] .grain{mix-blend-mode:screen;opacity:.05}

/* ---- scroll progress hairline ---- */
.meter{position:fixed;top:0;left:0;z-index:60;height:2px;width:100%;transform:scaleX(0);transform-origin:0 50%;background:var(--pb);opacity:.9}

/* ---- fixed chrome ---- */
.chrome{position:fixed;left:0;right:0;top:0;z-index:50;display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:max(12px,calc(env(safe-area-inset-top,0px) + 10px)) clamp(14px,3.2vw,40px) 12px;
  background:linear-gradient(to bottom, rgba(var(--veilc),.95) 0%, rgba(var(--veilc),.80) 68%, rgba(var(--veilc),0) 100%);}
.mark{display:flex;align-items:center;gap:9px;font-size:15px;font-weight:600;color:var(--ink);min-width:0;flex-shrink:1;text-decoration:none}
.chrome .nav{display:flex;align-items:center;gap:clamp(10px,2.1vw,24px);flex-shrink:0}
.chrome .nav a:not(.pill){margin-left:0;color:var(--ink);opacity:.78;font-size:14.5px;text-decoration:none;transition:opacity .3s var(--ease)}
.chrome .nav a:not(.pill):hover{opacity:1}
.pill{display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 20px;border-radius:999px;
  background:var(--ink);color:var(--bg);-webkit-text-fill-color:var(--bg);border:1px solid transparent;
  font-size:14.5px;font-weight:500;letter-spacing:-.008em;text-decoration:none;white-space:nowrap;cursor:pointer;
  transition:transform .4s var(--ease),opacity .3s var(--ease)}
.chrome .nav .pill{color:var(--bg);-webkit-text-fill-color:var(--bg)}
.pill:hover,.pill:focus-visible{transform:translateY(-2px)}
.pill:focus-visible{outline:2px solid var(--pb);outline-offset:2px}
.pill.ghost{background:transparent;color:var(--ink);-webkit-text-fill-color:var(--ink);border-color:var(--line)}
.themed{width:40px;height:40px;padding:0;border-radius:999px;background:transparent;border:1px solid var(--line);color:var(--ink);
  display:inline-flex;align-items:center;justify-content:center;font-size:16px;line-height:1;cursor:pointer;flex-shrink:0}
.themed:hover{border-color:var(--ink)}
.skip{position:absolute;left:-9999px;top:0}
.skip:focus{left:8px;top:8px;z-index:70;background:var(--paper);color:var(--ink);padding:10px 14px;border-radius:8px;border:1px solid var(--line)}

/* ---- pinned hero panels (cross-faded from the scroll loop, not CSS transitions) ---- */
.herostage{position:fixed;inset:0;z-index:20;pointer-events:none}
.panel{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;
  padding:max(104px,calc(env(safe-area-inset-top,0px) + 88px)) clamp(20px,5vw,60px) max(96px,calc(env(safe-area-inset-bottom,0px) + 80px));
  opacity:0;will-change:opacity,transform}
.eyebrow{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:6px 12px;font-size:12.5px;letter-spacing:.045em;
  text-transform:uppercase;color:var(--muted);margin-bottom:clamp(14px,2vw,20px);max-width:min(52ch,100%)}
.panel h1{font-family:var(--display);font-weight:500;font-size:clamp(32px,6.6vw,84px);line-height:1;letter-spacing:-.036em;
  max-width:15ch;margin:0;text-wrap:balance}
.sub{margin-top:clamp(16px,2.2vw,26px);font-size:clamp(15px,1.25vw,19px);line-height:1.5;color:var(--muted);max-width:min(48ch,100%);text-wrap:pretty}
.cta{margin-top:clamp(24px,3.2vw,40px);pointer-events:auto;display:flex;flex-wrap:wrap;gap:10px;justify-content:center;width:100%}
.cta .pill{height:48px;padding:0 26px;font-size:15px;max-width:min(100%,320px)}
.panel .balls{margin-top:4px}
.scrollhint{position:fixed;left:0;right:0;bottom:max(14px,calc(env(safe-area-inset-bottom,0px) + 10px));z-index:21;text-align:center;
  font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);pointer-events:none}

/* the only thing that gives the hero its scroll length */
.track{position:relative;z-index:1;height:300vh;min-height:1800px}

/* ---- app content sits above the backdrop ---- */
.wrap{position:relative;z-index:10}
section{scroll-margin-top:86px;background:color-mix(in srgb,var(--paper) 86%,transparent);backdrop-filter:blur(10px) saturate(1.04);-webkit-backdrop-filter:blur(10px) saturate(1.04)}
.stat{background:color-mix(in srgb,var(--paper) 86%,transparent);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
footer{position:relative;z-index:10}
.linklike{background:none;border:none;padding:0;color:var(--accent);font:inherit;font-size:13px;text-decoration:underline;cursor:pointer}

/* ---- disclaimer sheet ---- */
.sheet{position:fixed;inset:0;z-index:100;display:flex;align-items:center;justify-content:center;padding:18px;
  background:rgba(8,11,16,.55);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
.sheet[hidden]{display:none}
.sheet-card{background:var(--paper);color:var(--ink);border:1px solid var(--line);border-radius:16px;max-width:560px;width:100%;
  max-height:min(86vh,720px);overflow:auto;padding:clamp(20px,3.4vw,30px);box-shadow:0 24px 70px rgba(8,11,16,.34)}
.sheet-card h2{font-size:clamp(20px,2.6vw,26px);margin-bottom:6px}
.sheet-card p{font-size:14.5px;color:var(--muted);margin:0 0 12px}
.sheet-card p strong{color:var(--ink);font-weight:600}
.sheet-badge{display:inline-flex;align-items:center;gap:8px;font-size:12px;letter-spacing:.05em;text-transform:uppercase;color:var(--pb);margin-bottom:10px}
.sheet-acts{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-top:16px}

/* ---- reduced motion / no-JS: hero becomes an ordinary block, nothing pinned ---- */
body.flat .herostage{position:relative;inset:auto;height:auto;pointer-events:auto}
body.flat .panel{position:relative;inset:auto;opacity:1 !important;transform:none !important;min-height:auto;
  padding:clamp(48px,7vw,84px) clamp(16px,4vw,32px)}
body.flat .track{display:none}
body.flat .scrollhint{display:none}
body.flat #balls{display:none}
.nojs .herostage{position:relative;inset:auto}
.nojs .panel{position:relative;opacity:1;padding:48px 16px}
.nojs .track{display:none}

@media (max-width:900px){
  .veil{background:
    radial-gradient(90% 62% at 50% 46%, rgba(var(--veilc),calc(var(--veilmid) + .22)) 0%, rgba(var(--veilc),calc(var(--veilmid) * .7)) 58%, rgba(var(--veilc),.12) 100%),
    linear-gradient(to bottom, rgba(var(--veilc),.90) 0%, rgba(var(--veilc),.32) 24%, rgba(var(--veilc),.40) 72%, rgba(var(--veilc),.94) 100%);}
}
@media (max-width:720px){
  .chrome .nav a:not(.pill){display:none}
  .mark{font-size:14px}
  .chrome .nav .pill{height:38px;padding:0 16px;font-size:13.5px}
  .themed{width:38px;height:38px}
  .panel h1{max-width:13ch;font-size:clamp(30px,9.2vw,50px)}
  .sub{font-size:15px;max-width:36ch}
  .panel{padding:max(92px,calc(env(safe-area-inset-top,0px) + 76px)) 18px max(88px,calc(env(safe-area-inset-bottom,0px) + 72px))}
  .track{height:260vh;min-height:1500px}
}
@media (max-width:420px){
  .panel h1{max-width:11ch;font-size:clamp(28px,10.2vw,40px)}
  .eyebrow{font-size:11px;letter-spacing:.04em;max-width:30ch}
  .cta{flex-direction:column;align-items:center}
  .cta .pill{width:100%;max-width:280px;height:44px;padding:0 20px;font-size:14px}
  .chrome .nav .pill{height:36px;padding:0 13px;font-size:13px}
}
@media (max-height:520px) and (orientation:landscape){
  .panel{padding:max(72px,calc(env(safe-area-inset-top,0px) + 56px)) 24px max(64px,calc(env(safe-area-inset-bottom,0px) + 48px))}
  .panel h1{font-size:clamp(26px,7.6vh,42px)}
  .sub{margin-top:10px;font-size:14px}
  .cta{margin-top:14px}
  .scrollhint{display:none}
}

/* Utility classes replacing former inline style attributes, so that the CSP
   can forbid inline styles outright (style-src 'self'). */
.ball-sm{width:26px;height:26px;font-size:11px}
.mt-lg{margin-top:18px}
.mt-md{margin-top:12px}
.mt-sm{margin-top:8px}
.mt-xs{margin-top:6px}
.w-filter{min-width:230px}
.p-sm{padding:4px}
.inline-row{display:inline-flex;gap:6px;align-items:center}
.pb-input{border-color:var(--pb)}


/* Draw-data status. The text states the condition; the dot only reinforces it,
   so the state is never communicated by colour alone (WCAG 1.4.1). */
.datastate{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--muted);margin:-8px 0 18px}
.datastate::before{content:"";flex:none;width:8px;height:8px;border-radius:50%;background:var(--muted)}
.datastate[data-state="loaded"]::before{background:var(--ok)}
.datastate[data-state="error"]::before,.datastate[data-state="offline"]::before{background:var(--warn)}
.datastate[data-state="error"],.datastate[data-state="offline"]{color:var(--warn)}

/* Local maintenance utility (dev-tools.html). Deliberately plain and visually
   distinct from the public site so it is never mistaken for it. */
.devhead{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:22px 0 8px}
.devhead a{color:var(--muted);font-size:14px}
.devwarn{border-color:var(--warn)}
.devwarn ul{margin:0 0 10px;padding-left:20px;font-size:14px;color:var(--muted)}
.devwarn li{margin:0 0 4px}
.devwarn strong{color:var(--ink)}
