/* MilliCheck. See DIRECTION.md for the world this implements.

   A lit near-black room: the page is the dark, the light falls in one shaft
   over the machine, and the only colour that means anything is the gold on
   money. Two self-hosted faces, one self-hosted library, no request to anybody
   but us. */

@font-face {
  font-family: "Display";
  src: url("../fonts/archivo-var.de2f1fe81758.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}
@font-face {
  font-family: "Mono";
  src: url("../fonts/jetbrains-mono-var.b058178d7f30.woff2") format("woff2-variations");
  font-weight: 100 800;
  font-display: swap;
}

:root {
  /* ---- the surface ladder, darkest to lightest ---- */
  --bg: #020202;
  --card: #090909;
  --raised: #15151F;
  --elevated: #242424;
  --accent-line: #44444C;

  --text: #FFFFFF;
  /* 5.5:1 on the ground, so a label is quiet without being unreadable. The
     reference site's own labels sit near 2.9:1 and that is the single defect
     this redesign started from. */
  --muted: #84837D;

  --line: rgba(255, 255, 255, .05);
  --line-2: rgba(255, 255, 255, .09);

  /* The ambient light. Spent on the beam, the progress bar and one word in the
     headline, and nowhere else. */
  --indigo-1: #38319E;
  --indigo-2: #1E1A70;
  --lilac: #9C95FF;

  --gold: #FFC23A;      /* money, the primary action, and the live second */
  --live: #FF4D2E;      /* the Powerball, the on-air dot, an error */
  --win: #5FE39B;

  --ball: #F6F3EA;
  --ball-ink: #0B0D12;

  /* ---- elevation ---- */
  --e-subtle: rgba(255, 255, 255, .016) 0 0 0 1px inset;
  --e-medium: rgba(0, 0, 0, .62) 0 1px 1px -.5px;
  --e-strong: rgba(255, 255, 255, .22) 0 -18px 48px -34px;

  /* ---- radius by hierarchy, rather than one value on everything ---- */
  --r-chip: 3px;
  --r-card: 6px;
  --r-btn: 7px;
  --r-panel: 10px;
  --r-pill: 999px;

  /* ---- 4px grid ---- */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 28px; --s7: 76px; --s8: 96px;

  --ease: cubic-bezier(.16, 1, .3, 1);
  --t-fast: .18s; --t-mid: .22s; --t-slow: .24s;

  /* Two values the palette above has no other home for. Both are real
     colours rather than pointers, which is why they survived the alias block
     that the rest of the old names lived in.

     `--live-text` is the on-air red at a value that reads as small text: the
     red itself is 3.1:1 on the ground and legible only as a large figure or a
     dot. `--gold-panel` is a gold-tinted surface, which is what a highlighted
     row in a lit room looks like. A pale slab would be a different world. */
  --live-text: #FF6A4A;
  --gold-panel: #1E1708;

  --display: "Display", system-ui, "Helvetica Neue", Arial, sans-serif;
  --body: "Display", system-ui, "Helvetica Neue", Arial, sans-serif;
  --mono: "Mono", ui-monospace, SFMono-Regular, monospace;

  --measure: 34rem;
  --wide: 66rem;
}

* { box-sizing: border-box; }
html { color-scheme: dark; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--display);
  font-size: 16px;
  line-height: 1.62;
  -webkit-text-size-adjust: 100%;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.wrap { max-width: var(--wide); margin: 0 auto; padding: 0 var(--s5); }

/* ---- `hidden` means hidden ------------------------------------------------
   The browser's own rule for the attribute is `[hidden] { display: none }`,
   which any class here that sets a display beats on specificity. Several
   scripts on this site hide things with it: the sixth number box on a lottery
   that only has five, the bonus ball group on one that has none, and the
   submit button beside the state picker, which JavaScript takes away because
   choosing a state is the action once there is JavaScript to hear it.

   That last one had been on the page all along, because `.button` sets
   `display: inline-flex` and the attribute never stood a chance. This is the
   general fix rather than a fourth exception.
   ------------------------------------------------------------------------- */
[hidden] { display: none !important; }

/* The surfaces the browser draws and a design system usually forgets. */
::selection { background: var(--gold); color: var(--ball-ink); }
input, textarea, select { caret-color: var(--gold); }

.skip { position: absolute; left: -9999px; }
.skip:focus {
  left: 20px; top: 10px; z-index: 70;
  background: var(--gold); color: var(--ball-ink); padding: 10px 14px;
  border-radius: var(--r-btn);
}

a { color: var(--text); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { text-decoration-color: var(--gold); }
:focus-visible {
  outline: 1px solid rgba(255, 255, 255, .34);
  outline-offset: .35rem;
  border-radius: var(--r-chip);
}

/* Small tracked mono labels. */
.mono {
  font-family: var(--mono); font-size: .68rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
}

/* ---- Two fixed layers ------------------------------------------------------
   A hairline of progress, because a long page with eased scrolling needs one
   thing telling you where you are. And film grain, which is most of the
   difference between a flat black page and a lit one.
   --------------------------------------------------------------------------- */
.progress {
  position: fixed; inset: 0 0 auto; height: 2px; z-index: 60;
  background: linear-gradient(90deg, var(--indigo-1), var(--gold));
  transform-origin: 0 50%; transform: scaleX(0);
}
.grain {
  position: fixed; inset: -50%; z-index: 1; pointer-events: none; opacity: .028;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='120' height='120' filter='url(%23n)'/></svg>");
  animation: grain 1.1s steps(3) infinite;
}
@keyframes grain {
  0%   { transform: translate(0, 0); }
  33%  { transform: translate(-2%, 1%); }
  66%  { transform: translate(1%, -2%); }
  100% { transform: translate(0, 0); }
}

/* ---- The bar. A bug, not a floating nav. ---- */
.masthead {
  position: sticky; top: 0; z-index: 20;
  background: rgba(2, 2, 2, .72);
  backdrop-filter: blur(18px) saturate(140%);
  border-bottom: 1px solid var(--line);
}
.masthead .wrap {
  display: flex; align-items: center; gap: var(--s5); height: 64px;
}
.wordmark {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-weight: 600; font-size: 1.02rem; letter-spacing: -.03em;
  text-decoration: none; color: var(--text); margin: 0;
}
/* The on-air light. */
.wordmark .mark {
  width: 8px; height: 8px; flex: none; border-radius: 50%;
  background: var(--live); box-shadow: 0 0 0 3px rgba(255, 77, 46, .16);
}
.wordmark em { font-style: normal; color: var(--gold); }

.dateline { display: contents; }
.dateline > span { display: none; }
.dateline nav { display: flex; gap: var(--s1); margin-left: var(--s3); flex-wrap: wrap; }
.dateline nav a, .dateline .linkish {
  padding: 7px 13px; border-radius: var(--r-btn);
  font-family: var(--display); font-size: .9rem; font-weight: 500;
  color: var(--muted); text-decoration: none; border: 0; background: transparent;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.dateline nav a:hover, .dateline .linkish:hover { background: var(--raised); color: var(--text); }
.dateline nav a[aria-current] { background: var(--raised); color: var(--text); }
.masthead .inline-form { margin-left: auto; }

@media (max-width: 760px) {
  /* padding-block only: the shorthand would wipe the wrapper's side gutter and
     run the nav off both edges of the screen. */
  .masthead .wrap {
    height: auto; flex-direction: column; align-items: stretch;
    gap: var(--s2); padding-block: var(--s3);
  }
  .dateline nav { margin-left: 0; gap: 0; justify-content: space-between; }
  .dateline nav a, .dateline .linkish { padding: 6px 8px; font-size: .82rem; }
  .masthead .inline-form { margin-left: 0; }
}

/* ---- Headings ---- */
h1, h2, h3 {
  font-family: var(--display); font-weight: 350; font-stretch: 96%;
  letter-spacing: -.045em; line-height: .96; text-wrap: balance;
}
h1 { font-size: clamp(2.3rem, 5.6vw, 3.9rem); margin: var(--s7) 0 var(--s3); max-width: 20ch; }
h2 { font-size: clamp(1.7rem, 3.8vw, 2.5rem); margin: 0 0 var(--s4); letter-spacing: -.05em; }
h3 { font-weight: 500; font-size: 1.08rem; margin: 0; letter-spacing: -.025em; line-height: 1.2; }

/* `.kicker` is retired rather than removed: it survives in templates not yet
   rebuilt, and a tracked-caps label above a heading is the most reliable piece
   of generated template furniture there is. It renders as a plain mono label. */
.kicker {
  font-family: var(--mono); font-size: .68rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
  margin: 0 0 var(--s2);
}
.lede { font-size: 1.08rem; color: var(--muted); max-width: 54ch; margin: 0 0 var(--s6); }
.meta, .hint, .note { font-family: var(--display); font-size: .88rem; color: var(--muted); }
.note { max-width: var(--measure); }
.empty { color: var(--muted); padding: var(--s5) 0; }
.unknown { color: var(--live-text); }
.fine { font-size: .88rem; color: var(--muted); max-width: var(--measure); }

section { margin-bottom: var(--s8); }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s4); flex-wrap: wrap;
  border-bottom: 1px solid var(--line-2);
  padding-bottom: var(--s3); margin-bottom: var(--s5);
}
.section-head h2 { margin: 0; }

/* ---- Buttons ---- */
.button, button {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--display); font-size: .95rem; font-weight: 600;
  letter-spacing: -.01em;
  background: var(--gold); color: var(--ball-ink);
  border: 0; border-radius: var(--r-btn);
  padding: 13px 19px; min-height: 44px;
  text-decoration: none; cursor: pointer;
  box-shadow: var(--e-subtle), var(--e-medium);
  transition: transform var(--t-fast) var(--ease),
              box-shadow var(--t-fast) var(--ease), opacity var(--t-fast);
}
.button:hover, button:hover { transform: translateY(-1px); opacity: .92; }
.button:active, button:active { transform: translateY(1px) scale(.992); }
/* The quiet one is the same shape with the fill taken out, so a page with
   several actions still has exactly one gold thing on it. */
.button.quiet, .button.secondary {
  background: #171719; color: var(--text);
  box-shadow: var(--e-subtle), var(--e-medium);
}
.button.quiet:hover { background: #1E1E21; opacity: 1; }
.linkish.danger { color: var(--live-text); background: none; box-shadow: none;
  padding: 0; min-height: 0; font-size: .88rem; text-decoration: underline; }
.linkish.danger:hover { transform: none; opacity: .85; }

/* ---- Panels. The one container. ---- */
.stub, .panel {
  position: relative;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--e-subtle), var(--e-medium);
  padding: var(--s6);
}
.stub::before { content: none; }
.panel.lit {
  border-color: rgba(255, 194, 58, .24);
  box-shadow: var(--e-subtle), var(--e-strong);
}
.stub-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap;
  border-bottom: 1px solid var(--line); padding-bottom: var(--s3); margin-bottom: var(--s4);
}
.stub-head h3 a { text-decoration: none; }
.stub-head h3 a:hover { color: var(--gold); }
.stub-head .when { font-family: var(--mono); font-size: .7rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); }
.stub-grid { display: grid; gap: var(--s5); grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); }
.stub-grid .stub { display: flex; flex-direction: column; }
.stub-grid .stub > p:last-child { margin-top: auto; margin-bottom: 0; }

/* ---- Balls ------------------------------------------------------------------
   The one object this product shows that exists physically, so it is rendered
   as an object. One gradient makes a disc with a light patch on it; a sphere
   needs a broad diffuse falloff, a sharp specular where the lamp is, a dark
   terminator on the far side, and a cool bounce along the bottom edge from the
   surface underneath. The printed ring is the last tell: a real ball carries
   its number inside one.
   --------------------------------------------------------------------------- */
.balls { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s2); margin: 0 0 var(--s4); padding: 0; }
.ball {
  position: relative; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: 50%;
  font-family: var(--display); font-weight: 650; font-stretch: 88%;
  font-size: .95rem; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ball-ink);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .45);
  background: radial-gradient(circle at 34% 28%,
    #FFFEFC 0%, #F7F3E9 26%, #E4DECF 52%, #B3AC9A 78%, #837D6E 100%);
  box-shadow:
    inset -10px -14px 24px rgba(28, 24, 16, .42),
    inset 10px 12px 20px rgba(255, 255, 255, .5),
    inset -3px -4px 10px rgba(150, 165, 220, .32),
    0 16px 22px -14px rgba(0, 0, 0, .95);
  border: 0;
}
/* The printed ring. */
.ball::before {
  content: ""; position: absolute; inset: 19%;
  border-radius: 50%; border: 1.5px solid rgba(20, 22, 28, .13);
}
/* The specular. */
.ball::after {
  content: ""; position: absolute; left: 19%; top: 14%; width: 26%; height: 19%;
  border-radius: 50%; background: #fff; filter: blur(4px); opacity: .9;
}
.ball.special {
  color: #fff; text-shadow: 0 1px 2px rgba(80, 14, 0, .5);
  background: radial-gradient(circle at 34% 28%,
    #FF9E86 0%, #F4573A 26%, #DC3318 54%, #96200C 80%, #5E1406 100%);
  box-shadow:
    inset -10px -14px 24px rgba(40, 6, 0, .55),
    inset 10px 12px 20px rgba(255, 190, 170, .4),
    inset -3px -4px 10px rgba(150, 165, 220, .2),
    0 16px 22px -14px rgba(0, 0, 0, .95);
}
.ball.special::before { border-color: rgba(255, 255, 255, .14); }
.ball.special::after { opacity: .72; }
/* Each game's bonus ball in the colour that game actually prints it, so the
   colour carries information rather than decorating. */
.ball.special[data-ball="gold"] {
  color: var(--ball-ink); text-shadow: 0 1px 0 rgba(255, 255, 255, .4);
  background: radial-gradient(circle at 34% 28%,
    #FFF0C4 0%, #FFD469 26%, #F2AE12 54%, #A8710A 80%, #6B4704 100%);
  box-shadow:
    inset -10px -14px 24px rgba(50, 32, 0, .5),
    inset 10px 12px 20px rgba(255, 240, 200, .45),
    inset -3px -4px 10px rgba(150, 165, 220, .2),
    0 16px 22px -14px rgba(0, 0, 0, .95);
}
.ball.special[data-ball="gold"]::before { border-color: rgba(60, 40, 0, .18); }
/* A number you matched gets lit rather than recoloured, so the ball keeps its
   own material underneath. */
.ball.marked { box-shadow:
    inset -10px -14px 24px rgba(28, 24, 16, .42),
    inset 10px 12px 20px rgba(255, 255, 255, .5),
    0 0 0 3px var(--gold), 0 0 22px -2px rgba(255, 194, 58, .55);
  z-index: 1; }
.ball.small { width: 32px; height: 32px; font-size: .74rem; }
.stub .ball { width: 38px; height: 38px; font-size: .8rem; }
.stub .balls { gap: 6px; }

/* ---- Reveal on scroll, in both directions ----------------------------------
   Sections rise in as they arrive and settle back once properly gone, so
   scrolling up plays the same as scrolling down. The hiding is scoped to
   `html.js`, which only exists once the script has actually run: a reveal that
   leaves the page blank when its script fails is not an effect, it is an
   outage.
   --------------------------------------------------------------------------- */
.js [data-reveal] {
  opacity: 0; transform: translateY(22px);
  transition: opacity .62s var(--ease), transform .62s var(--ease);
}
.js [data-reveal].in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; transition: none; }
  .grain { animation: none; opacity: .02; }
  html { scroll-behavior: auto; }
}


/* ============================================================================
   The home page. Everything below is the first viewport and the pieces that
   only it uses.
   ========================================================================= */

/* ---- stage ---- */
.stage{position:relative;overflow:hidden;padding:var(--s6) 0 56px}
.beam{position:absolute;inset:-12% -20% auto;height:150%;pointer-events:none;z-index:0;will-change:transform}
.beam::before{content:"";position:absolute;left:50%;top:-16%;translate:-50% 0;
  width:min(820px,98vw);height:116%;
  background:
    radial-gradient(44% 58% at 50% 0%,rgba(56,49,158,.52),transparent 74%),
    radial-gradient(72% 26% at 50% 70%,rgba(30,26,112,.34),transparent 78%);
  filter:blur(28px)}
.beam::after{content:"";position:absolute;inset:0;opacity:.5;
  background-image:radial-gradient(rgba(255,255,255,.1) .6px,transparent .7px);
  background-size:4px 4px;
  -webkit-mask-image:radial-gradient(52% 46% at 50% 4%,#000,transparent 72%);
  mask-image:radial-gradient(52% 46% at 50% 4%,#000,transparent 72%)}
.stage .wrap{position:relative;z-index:1}

.badge{display:inline-flex;align-items:center;gap:var(--s2);
  padding:6px var(--s3) 6px 11px;border-radius:var(--r-pill);
  border:1px solid var(--line-2);background:var(--raised);box-shadow:var(--e-subtle)}
.badge i{width:6px;height:6px;border-radius:50%;background:var(--gold);
  box-shadow:0 0 8px 1px rgba(255,194,58,.7)}

h1{margin:var(--s6) 0 0;font-weight:350;font-stretch:96%;
  font-size:clamp(2.5rem,6vw,4.4rem);line-height:.92;letter-spacing:-.052em;
  max-width:17ch;text-wrap:balance}
h1 b{font-weight:350;color:#9C95FF}

/* The figure is a phrase, not a numeral. Set as "$317" alone it reads as three
   hundred and seventeen, says nothing about which lottery, and says nothing
   about what the number is. So the word is bound to the number at a size you
   cannot skip, and a line above names the game and the drawing. */
.jackpot{margin:var(--s6) 0 0}
.jackpot-of{margin:0 0 var(--s2)}
.amount{margin:0;color:var(--gold);display:flex;align-items:baseline;gap:.14em;flex-wrap:wrap}
.hero .amount{justify-content:center;gap:.24em}
.amount .big{font-weight:600;font-stretch:80%;letter-spacing:-.05em;
  font-size:clamp(3rem,8vw,5.6rem);line-height:.86}
.amount .scale{font-weight:500;font-stretch:88%;letter-spacing:-.03em;
  font-size:clamp(1.5rem,3.6vw,2.5rem);line-height:1}
.jackpot-note{margin:var(--s3) 0 0;max-width:46ch}

/* ---- the counter -----------------------------------------------------------
   A split flap board. Each unit is one card with a seam across its middle,
   which is the hinge the physical thing turns on. The seconds card is the only
   one carrying colour, because it is the only one visibly moving.
   --------------------------------------------------------------------------- */
.counter{display:flex;gap:var(--s3);margin:var(--s5) 0 0}
.unit{text-align:center}
.flap{position:relative;overflow:hidden;
  width:clamp(64px,8.6vw,94px);padding:var(--s4) var(--s2);
  border-radius:var(--r-panel);border:1px solid var(--line);
  background:linear-gradient(180deg,#2A2A2A 0%,#1C1C1C 52%,#121212 100%);
  box-shadow:var(--e-subtle),var(--e-medium),var(--e-strong)}
.flap .n{display:block;text-align:center;font-weight:300;font-stretch:92%;
  font-size:clamp(1.9rem,4.2vw,2.8rem);line-height:1;letter-spacing:-.03em}
/* the hinge */
.flap::after{content:"";position:absolute;left:0;right:0;top:50%;height:1px;
  background:rgba(0,0,0,.72);box-shadow:0 1px 0 rgba(255,255,255,.045)}
.unit p{margin:var(--s2) 0 0}
.unit.now .flap{border-color:rgba(255,194,58,.3)}
.unit.now .flap .n{color:var(--gold)}
.unit.now .flap::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,194,58,.10),transparent 58%)}
/* the flip itself: the top half tips forward as the digit changes */
.flap .n.turn{animation:turn .34s var(--ease)}
@keyframes turn{
  0%{transform:translateY(-6%) scaleY(.94);opacity:.55}
  100%{transform:none;opacity:1}
}

.under{display:flex;gap:var(--s3) var(--s6);flex-wrap:wrap;align-items:center;margin:var(--s4) 0 0}
.sub{color:var(--muted);font-size:.95rem}
.sub a{color:var(--text);border-bottom:1px solid rgba(255,255,255,.28)}
.sub a:hover{border-bottom-color:var(--gold)}

/* ---- tonight, under the checker ---------------------------------------------
   The jackpot used to be the first thing on the page and is now the third. It
   keeps the whole treatment, the figure and the countdown and the cutoff,
   because somebody who arrived for the jackpot must not have to go looking for
   it. What it gives up is scale: two thirds the size of the figure above it,
   which is the entire difference between a headline and a fact.
   --------------------------------------------------------------------------- */
.next-up{display:grid;grid-template-columns:1.12fr .88fr;gap:56px;align-items:start;
  margin:56px 0 0;padding-top:var(--s6);border-top:1px solid var(--line)}
.next-up .jackpot{margin:var(--s4) 0 0}
.next-up .amount .big{font-size:clamp(2.2rem,5vw,3.4rem)}
.next-up .amount .scale{font-size:clamp(1.1rem,2.4vw,1.6rem)}
.next-up .counter{margin:0}
.next-up .flap{width:clamp(56px,7vw,76px);padding:var(--s3) var(--s2)}
.next-up .flap .n{font-size:clamp(1.5rem,3.2vw,2.1rem)}
.next-up .cutoff{margin-top:var(--s5)}

/* ---- The figure the page opens with ----------------------------------------
   It inherited the jackpot's size, which was the size of a figure sharing the
   top of the page with a headline the same weight. It is not sharing any more,
   so it takes the room that argument implies: about half again on a desktop,
   where the left column was three hundred pixels wider than the number needed,
   and a larger floor on a phone.

   The numeral is sized to leave room for the word beside it rather than to
   fill the column, because "$2.61 billion" is one phrase and reads as one only
   while it is on one line. `.amount` still wraps if a bigger figure ever needs
   it to, which is the right failure and not the plan.
   --------------------------------------------------------------------------- */
.figure-unclaimed{position:relative;margin:var(--s6) 0 0}
.figure-unclaimed .amount{margin-top:var(--s3)}
.figure-unclaimed .amount .big{font-size:clamp(4rem,13vw,11.5rem)}
.figure-unclaimed .amount .scale{font-size:clamp(1.6rem,3.4vw,3.2rem)}
/* The gap under the figure is the one piece of space on this page doing real
   work. Above it a number, below it the sentence saying whose number it is,
   and run together they read as one block nobody finishes. */
.figure-unclaimed .jackpot-note{max-width:60ch;margin:var(--s6) auto 0;text-wrap:balance}

/* The number is the light source, and this is the light coming off it.
   `text-shadow` rather than a filter: a blur would soften the glyph itself and
   the whole point is a hard bright edge with a bloom around it, which is what
   a lit object looks like and what every other lit object on this page does.

   Two layers. The tight one is the halo that sits on the edge of the stroke,
   the wide one is the bloom it throws into the room. Both low enough that on a
   bright screen in daylight you would have to look for them. */
.figure-unclaimed .amount .big{
  text-shadow:0 0 18px rgba(255,194,58,.26),0 0 64px rgba(255,194,58,.14)}
.figure-unclaimed .amount .scale{text-shadow:0 0 14px rgba(255,194,58,.18)}

/* And the light it casts on the ground behind it. Anchored to the numeral
   rather than centred on the block, because the light comes from the glyphs
   and not from the paragraph they sit in. */
.figure-glow{
  position:absolute;z-index:0;pointer-events:none;
  left:50%;translate:-50% 0;top:-8%;width:88%;height:128%;
  background:radial-gradient(52% 50% at 50% 46%,
    rgba(255,194,58,.11),rgba(255,194,58,.04) 46%,transparent 72%)}
.figure-unclaimed > p{position:relative;z-index:1}


/* The headline under the figure, rather than over it. It was set to be the
   largest thing on the page and is not any more: two things competing to be
   the first thing read is the same as having neither. The figure keeps the
   size, the sentence comes down to where it can be read as a sentence, and it
   gets air above the paragraph that follows it. */
/* The headline opens the page and is no longer the biggest thing on it. It is
   set to sit clearly under the figure and clearly over everything else, which
   is what a line introducing a number is for. */
.hook h1{font-size:clamp(1.9rem,3.4vw,2.5rem);margin:0;max-width:24ch}
.hero-note{margin:var(--s4) auto 0;max-width:54ch;font-size:.92rem}

/* Between deploying this and running the loader there is a window where the
   figure is not there yet, and a 76px top margin on a heading that is suddenly
   the first thing in the column reads as a bug. */
.hook > :first-child{margin-top:0}

/* ---- Sixteen years of one figure ------------------------------------------
   A bar per year, and the only chart on the site. It is drawn with a div and a
   width rather than with a library, because a chart of sixteen numbers does not
   need thirty kilobytes of JavaScript and because a library would be a request
   to somebody else, which this site does not make.

   Flat gold, no gradient. The bars are a quantity, not an object in the room:
   the gradients here belong to things made of light, and a bar is not one.

   The state count rides along on the right and is not decoration. Every year
   here currently holds the same three states, and the day that stops being
   true it is the only thing keeping a rising coverage count from being read as
   a rising trend.
   --------------------------------------------------------------------------- */
.year-bars { list-style: none; margin: 0; padding: 0; }
.year-bars li {
  display: grid; grid-template-columns: 4.6rem minmax(0, 1fr) 7rem 5.6rem;
  gap: var(--s4); align-items: center;
  padding: var(--s3) 0; border-bottom: 1px solid var(--line);
}
.year-bars li:last-child { border-bottom: 0; }
.year-label { color: var(--muted); }
.bar-track {
  display: block; height: 10px; border-radius: 2px;
  background: rgba(255, 255, 255, .05);
}
.bar { display: block; height: 100%; border-radius: 2px; background: var(--gold); }
.year-figure {
  text-align: right; color: var(--gold);
  font-weight: 600; font-stretch: 84%; letter-spacing: -.02em;
}
.year-states { text-align: right; color: var(--muted); }

/* ---- the machine. Smaller: the balls are evidence, not the headline. ---- */
.machine{margin:var(--s6) 0 0;padding-top:var(--s6);border-top:1px solid var(--line)}
.tray{display:flex;gap:10px;justify-content:flex-start;align-items:center;flex-wrap:wrap}
/* One gradient makes a disc with a light patch on it. A sphere needs four
   things: a broad diffuse falloff, a sharp specular where the lamp is, a dark
   terminator on the far side, and a cool bounce along the bottom edge from the
   surface underneath. The printed ring is the last tell: a real ball carries
   its number inside one. */
.orb{position:relative;width:clamp(38px,4.4vw,54px);aspect-ratio:1;border-radius:50%;
  display:flex;align-items:center;justify-content:center;flex:none;
  font-weight:650;font-stretch:88%;letter-spacing:-.02em;
  font-size:clamp(.72rem,1.25vw,.95rem);
  color:var(--ball-ink);
  text-shadow:0 1px 0 rgba(255,255,255,.45);
  background:radial-gradient(circle at 34% 28%,
    #FFFEFC 0%, #F7F3E9 26%, #E4DECF 52%, #B3AC9A 78%, #837D6E 100%);
  box-shadow:
    inset -10px -14px 24px rgba(28,24,16,.42),
    inset 10px 12px 20px rgba(255,255,255,.5),
    inset -3px -4px 10px rgba(150,165,220,.32),
    0 18px 24px -15px rgba(0,0,0,.95);
  transition:filter var(--t-mid) var(--ease)}
.orb i{position:absolute;inset:19%;border-radius:50%;border:1.5px solid rgba(20,22,28,.13)}
.orb b{position:relative;z-index:2;font-weight:inherit}
.orb::before{content:"";position:absolute;left:19%;top:14%;width:26%;height:19%;
  border-radius:50%;background:#fff;filter:blur(4px);opacity:.9}
.orb:hover{filter:brightness(1.08)}
/* The bounce. Each ball carries its own spring, driven by how fast the page is
   actually moving, so scrolling shakes the tray the way scrolling a real tray
   of loose balls would. `--y` is written by the script. */
.orb{translate:0 calc(var(--y,0) * 1px)}
.orb.pb{color:#fff;text-shadow:0 1px 2px rgba(80,14,0,.5);
  background:radial-gradient(circle at 34% 28%,
    #FF9E86 0%, #F4573A 26%, #DC3318 54%, #96200C 80%, #5E1406 100%);
  box-shadow:
    inset -10px -14px 24px rgba(40,6,0,.55),
    inset 10px 12px 20px rgba(255,190,170,.4),
    inset -3px -4px 10px rgba(150,165,220,.2),
    0 18px 24px -15px rgba(0,0,0,.95)}
.orb.pb i{border-color:rgba(255,255,255,.14)}
.orb.pb::before{opacity:.72}
.orb.mb{color:var(--ball-ink);text-shadow:0 1px 0 rgba(255,255,255,.4);
  background:radial-gradient(circle at 34% 28%,
    #FFF0C4 0%, #FFD469 26%, #F2AE12 54%, #A8710A 80%, #6B4704 100%);
  box-shadow:
    inset -10px -14px 24px rgba(50,32,0,.5),
    inset 10px 12px 20px rgba(255,240,200,.45),
    inset -3px -4px 10px rgba(150,165,220,.2),
    0 18px 24px -15px rgba(0,0,0,.95)}
.orb.mb i{border-color:rgba(60,40,0,.18)}
/* the contact shadow, which tightens as the ball drops toward the surface */
.orb::after{content:"";position:absolute;left:18%;right:18%;bottom:-18%;height:10%;
  border-radius:50%;background:rgba(0,0,0,.9);filter:blur(7px);z-index:-1}
.caption{margin:var(--s5) 0 0}


/* ---- panels ---- */
.panel{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);
  box-shadow:var(--e-subtle),var(--e-medium);padding:var(--s6)}
.panel.lit{border-color:rgba(255,194,58,.24);box-shadow:var(--e-subtle),var(--e-strong)}
/* ---- The hero, centred -----------------------------------------------------
   It was two columns, figure left and checker right, which is the arrangement
   you use when neither one is more important than the other. One of them is.
   The figure is the whole argument for the site existing and it was sitting in
   a 538px column on a 1200px page, which is a hero the size of a sidebar.

   Centred, everything below it inherits the same axis and the page reads as
   one column of argument: what was left behind, over how long and from whose
   accounts, then the thing that does something about it. The checker is the
   end of that sentence, so it has to be visible without scrolling, which is
   what every measurement below is for.
   --------------------------------------------------------------------------- */
.hero{display:flex;flex-direction:column;align-items:center;text-align:center}
.hook{width:100%;max-width:60ch}
.hero .panel{width:100%;max-width:560px;text-align:left;margin-top:var(--s5)}
.hero h1{margin-inline:auto}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:var(--s5);align-items:start;margin-top:56px}
.pitch-h{font-weight:400;font-size:1.32rem;line-height:1.16;letter-spacing:-.032em;
  margin:var(--s3) 0 var(--s3);max-width:24ch}
.pitch-p{color:var(--muted);font-size:.95rem;margin:0}
.facts{list-style:none;margin:var(--s5) 0 0;padding:0}
.facts li{position:relative;padding:var(--s2) 0 var(--s2) var(--s5);
  border-bottom:1px solid var(--line);font-size:.92rem;color:var(--muted)}
.facts li:last-child{border-bottom:0}
.facts li::before{content:"";position:absolute;left:0;top:50%;translate:0 -50%;
  width:5px;height:5px;border-radius:50%;background:var(--gold)}

.slots{display:flex;gap:2.6%;margin:var(--s4) 0 0}
.slot{width:14%;aspect-ratio:1;border-radius:50%;text-align:center;
  background:rgba(255,255,255,.02);border:1px solid var(--line-2);color:var(--text);
  font-family:inherit;font-weight:600;font-size:1.05rem;-moz-appearance:textfield;
  transition:border-color var(--t-fast) var(--ease),background var(--t-fast) var(--ease)}
.slot::-webkit-outer-spin-button,.slot::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.slot::placeholder{color:rgba(255,255,255,.3)}
.slot:not(:placeholder-shown){
  background:radial-gradient(circle at 33% 26%,#FFFFFF 0%,var(--ball) 44%,#B9B3A4 100%);
  color:var(--ball-ink);border-color:transparent}
.slot.pb:not(:placeholder-shown){
  background:radial-gradient(circle at 33% 26%,#FF9C86 0%,var(--live) 44%,#8E1E0C 100%);color:#fff}
select{width:100%;margin-top:var(--s3);padding:11px var(--s3);border-radius:var(--r-btn);
  background:var(--raised);border:1px solid var(--line-2);color:var(--text);
  font-family:inherit;font-size:.96rem}
.alt{margin:var(--s3) 0 0;color:var(--muted);font-size:.9rem}
.alt a{color:var(--gold);border-bottom:1px solid rgba(255,194,58,.4)}

.row{display:flex;align-items:center;gap:var(--s3);padding:var(--s4) 0;border-bottom:1px solid var(--line)}
.row:last-of-type{border-bottom:0}
.row .n{flex:1;font-weight:500;font-size:.98rem}
.row .w{color:var(--muted);font-size:.78rem;font-family:"Mono",monospace;letter-spacing:.1em}
.row .f{font-weight:600;font-stretch:84%;font-size:1.12rem;color:var(--gold);letter-spacing:-.02em}

/* ---- the ticker ------------------------------------------------------------
   Every drawing we hold, moving past. The reference runs a marquee of client
   logos here; ours carries actual numbers, which is the version that is worth
   reading rather than just worth looking at. It pauses on hover so a row can
   be read, and stops entirely for anyone who asked for less motion.
   --------------------------------------------------------------------------- */
.ticker{overflow:hidden;border-block:1px solid var(--line);padding:var(--s4) 0;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.ticker-row{display:flex;width:max-content;animation:slide 46s linear infinite}
.ticker:hover .ticker-row{animation-play-state:paused}
.ticker-set{display:flex;gap:var(--s7);padding-right:var(--s7)}
.tick{display:inline-flex;align-items:center;gap:var(--s2);white-space:nowrap;
  font-size:.82rem;color:var(--muted)}
.tick em{font-style:normal;font-weight:600;color:var(--text);margin-right:var(--s1)}
.tick i{display:inline-flex;align-items:center;justify-content:center;font-style:normal;
  width:24px;height:24px;border-radius:50%;font-size:.66rem;font-weight:650;
  color:var(--ball-ink);
  background:radial-gradient(circle at 34% 28%,#FFFEFC 0%,#F0EBDF 48%,#A8A191 100%);
  box-shadow:inset -3px -4px 7px rgba(28,24,16,.32),0 4px 7px -4px rgba(0,0,0,.9)}
.tick i.r{color:#fff;background:radial-gradient(circle at 34% 28%,#FF9E86 0%,#E4401F 48%,#7C1A08 100%)}
.tick i.g{background:radial-gradient(circle at 34% 28%,#FFF0C4 0%,#F5B923 48%,#8C5D06 100%)}
@keyframes slide{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}

/* A pool of light that follows the pointer across the stage. Nothing reacts to
   it; it is the room lighting noticing where you are looking. */
.glow{position:absolute;inset:0;z-index:0;pointer-events:none;opacity:0;
  transition:opacity .5s var(--ease);
  background:radial-gradient(var(--glow-size,420px) circle at var(--mx,50%) var(--my,30%),
    rgba(156,149,255,.11),transparent 68%)}
/* A mouse lights it by being over the stage. A finger has no hover, so touch
   lights it by putting the class on directly. Both, so neither device has to
   pretend to be the other. */
.stage:hover .glow,
.glow.lit{opacity:1}
/* Under a finger the pool is smaller and brighter, because a fingertip covers
   the middle of it and what you actually see is the ring escaping around the
   edge. At the pointer's size and strength that ring is invisible. */
.glow.touch{--glow-size:260px;
  background:radial-gradient(var(--glow-size) circle at var(--mx,50%) var(--my,30%),
    rgba(156,149,255,.2),rgba(156,149,255,.05) 45%,transparent 70%);
  transition:opacity .22s var(--ease)}

/* Film grain. Two pixels of noise over everything, which is the difference
   between a flat black page and a lit one. */
.grain{position:fixed;inset:-50%;z-index:1;pointer-events:none;opacity:.028;
  background-image:url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'>\
<filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter>\
<rect width='120' height='120' filter='url("#n#n")'/></svg>");
  animation:grain 1.1s steps(3) infinite}
@keyframes grain{
  0%{transform:translate(0,0)}33%{transform:translate(-2%,1%)}66%{transform:translate(1%,-2%)}
  100%{transform:translate(0,0)}}





/* ---- The check form ---- */
/* Boxes are grouped and each group carries its own range underneath. One
   sentence saying "the last box is the Powerball, 1 to 26, the rest are 1 to
   69" reads in the wrong order: people take the first range they see and apply
   it to the box they are typing in, which is the first one. Put the range under
   the boxes it governs and there is nothing left to misread. */
.ball-row { display: flex; flex-wrap: wrap; gap: 8px 20px; margin-bottom: 10px; align-items: flex-start; }
.ball-group { display: flex; flex-direction: column; gap: 7px; }
.ball-boxes { display: flex; flex-wrap: wrap; gap: 10px; }
.range-label {
  font-family: var(--display); font-size: 0.72rem; font-weight: 600; color: var(--muted);
}
.ball-group.special .range-label { color: var(--live-text); }
/* An empty slot on the set: the outline of a ball that has not been drawn
   yet. It fills with the ball's own material as soon as it carries a number,
   which is the entry animation this page gets instead of a decorative one. */
.ball-input input {
  width: 60px; height: 60px; text-align: center;
  font-family: var(--display); font-size: 1.3rem; font-weight: 800;
  font-stretch: 88%; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  background: transparent; color: var(--text);
  border: 2px solid var(--line); border-radius: 50%;
  transition: border-color 120ms, background 120ms, color 120ms;
  -moz-appearance: textfield;
}
.ball-input input:not(:placeholder-shown) {
  background: radial-gradient(circle at 34% 28%, #FFFFFF 0%, var(--ball) 46%, #CFC9B9 100%);
  color: var(--ball-ink);
  border-color: transparent;
}
.ball-input.special input:not(:placeholder-shown) {
  background: radial-gradient(circle at 34% 28%, #FF8A73 0%, var(--live) 46%, #A6240F 100%);
  color: #fff;
}
.ball-input input::-webkit-outer-spin-button,
.ball-input input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.ball-input input::placeholder { color: #4E6494; }
.ball-input.special input { border-color: var(--live); }
main.plate .ball-input input:not(:placeholder-shown) { color: var(--ball-ink); }
/* A wash, not a white patch. The old value was near-white, which read as a hole
   punched in the cream page and now reads as one on newsprint. */
.ball-input.has-error input { border-color: var(--live); background: rgba(224,58,32,0.14); }

fieldset { border: 0; padding: 0; margin: 0 0 26px; }
legend {
  font-family: var(--display); font-size: 0.78rem; font-weight: 700; color: var(--muted);
  padding: 0; margin-bottom: 10px;
}
label { display: block; margin-bottom: 5px; font-family: var(--display); font-size: 0.9rem; }
select {
  font-family: var(--display); font-size: 1rem;
  padding: 11px 12px; width: 100%; max-width: 24rem; min-height: 44px;
  background: var(--card); color: var(--text);
  border: 2px solid var(--text); border-radius: 2px;
}
.checkbox { display: flex; align-items: center; gap: 10px; margin-top: 18px; }
.checkbox label { margin: 0; }
.checkbox input { width: 22px; height: 22px; accent-color: var(--live); }
.privacy-note { margin-top: 14px; max-width: var(--measure); }
.field-error, .errors { font-family: var(--display); font-size: 0.85rem; color: var(--live-text); }

/* ---- The answer ---- */
.answer { margin: 0 0 32px; padding: 24px; }
.answer .verdict {
  font-family: var(--display); font-weight: 800; letter-spacing: -0.025em;
  font-size: clamp(1.5rem, 5vw, 2.1rem); line-height: 1.1;
  margin: 0 0 4px;
}
/* The highlighter again, this time behind the verdict of a win. */
.answer.win .verdict mark { background: var(--gold); color: var(--ball-ink); padding: 2px 8px; }
.answer .amount {
  font-family: var(--display); font-weight: 800; font-size: clamp(2.2rem, 9vw, 3.6rem);
  letter-spacing: -0.03em; margin: 12px 0 0; color: var(--win);
}
.answer .amount.unknown { font-size: clamp(1.2rem, 4vw, 1.5rem); color: var(--live); max-width: 22ch; line-height: 1.25; }
.answer .drawn-label { font-family: var(--display); font-size: 0.78rem; font-weight: 600; color: var(--muted); margin: 20px 0 8px; }
.caveats { margin: 18px 0 0; padding-left: 20px; color: var(--muted); font-size: 0.95rem; max-width: var(--measure); }
.caveats li { margin-bottom: 8px; }

/* ---- Tables ---- */
table { width: 100%; border-collapse: collapse; margin-bottom: 14px; }
caption { text-align: left; font-family: var(--display); font-size: 0.85rem; color: var(--muted); margin-bottom: 8px; }
th, td { text-align: left; padding: 11px 12px 11px 0; border-bottom: 1px solid var(--line); vertical-align: middle; }
thead th {
  font-family: var(--display); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.1em; color: var(--muted);
  border-bottom: 2px solid var(--text);
}
tbody th { font-family: var(--display); font-weight: 600; }
td { font-family: var(--display); font-size: 0.95rem; }
tr.retired td, tr.retired th { color: var(--muted); }
.tag {
  font-family: var(--display); font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  border: 1px solid var(--line); padding: 1px 6px; white-space: nowrap;
}
.numbers { white-space: nowrap; }

/* ---- Index list, for games ---- */
/* ---- The lottery hub. Every lottery's four pages one click from here, which
   is the only route to the payout chart and odds pages besides a lottery's own
   navigation. ---- */
.lottery-index { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.lottery-index li { border-bottom: 1px solid var(--line); padding: 20px 0; }
.lottery-index h2 { font-size: 1.25rem; margin: 0 0 6px; }
.lottery-index h2 a { text-decoration: none; }
.lottery-index h2 a:hover { color: var(--live-text); }
.lottery-index .play { margin: 0 0 2px; max-width: var(--measure); }
.lottery-index .when { margin: 0; color: var(--muted); font-size: 0.92rem; }
.lottery-index .deep {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  margin: 12px 0 0; font-family: var(--display); font-size: 0.86rem;
}
.lottery-index .deep a { padding: 4px 0; }

/* ---- Prose ---- */
.columns { display: grid; gap: 32px; grid-template-columns: 1.15fr 1fr; align-items: start; }

footer.site {
  border-top: 3px solid var(--text);
  margin-top: 64px; padding: 24px 0 48px;
  font-size: 0.92rem;
}
/* The disclaimer is the one paragraph on this site with legal weight: it is
   what says we are not the lottery and your ticket is the only thing you can
   claim with. It is not fine print and is not set as such. */
footer.site p { max-width: 46rem; margin: 0 0 10px; }
footer.site .foot-nav { color: var(--text); }

@media (max-width: 760px) {
  .columns { grid-template-columns: 1fr; }
}

@media (max-width: 430px) {
  /* The two groups may wrap onto separate lines at this width. Each carries
     its own range label, so a wrap reads as two labelled groups rather than a
     bonus ball that has gone missing. */
  .ball-row { gap: 10px 14px; }
  .ball-boxes { gap: 7px; }
  .ball-input input { width: 50px; height: 50px; font-size: 1.1rem; }
  .balls { gap: 6px; }
  .ball { width: 40px; height: 40px; font-size: 0.95rem; }
  .ball.small { width: 30px; height: 30px; font-size: 0.78rem; }
  .stub-grid { grid-template-columns: 1fr; }
  .dateline nav { margin-left: 0; width: 100%; }
}

/* ---- Breadcrumbs. Real navigation, and the markup Google reads for the
   breadcrumb trail it shows under a result. ---- */
.crumbs { padding-top: 14px; }
.crumbs ol { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0; padding: 0;
  font-family: var(--display); font-size: 0.82rem; color: var(--muted); }
.crumbs li + li::before { content: "/"; margin-right: 6px; color: var(--line); }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--live-text); text-decoration: underline; }

/* ---- FAQ ---- */
.faq dl { margin: 0; max-width: 46rem; }
.faq .qa { border-bottom: 1px solid var(--line); padding: 16px 0; }
.faq dt { font-family: var(--display); font-weight: 700; font-size: 1.02rem; margin-bottom: 6px; }
/* The question is the label and the answer is the content, so the answer takes
   full ink. Greying it made the whole bottom third of the home page read as
   small print about itself. */
.faq dd { margin: 0; }

/* ---- Big single figures, used only where the figure is the point ---- */
.stat-line { display: flex; flex-direction: column; gap: 2px; margin: 0 0 18px; }
.stat-figure { font-family: var(--display); font-weight: 800; letter-spacing: -0.02em;
  font-size: clamp(1.5rem, 5vw, 2.1rem); }
.stat-label { font-family: var(--display); font-size: 0.8rem; color: var(--muted); }

/* ---- Pagination ---- */
.pager { display: flex; align-items: center; gap: 20px; margin-top: 20px;
  font-family: var(--display); font-size: 0.9rem; color: var(--muted); }
.pager a { color: var(--text); font-weight: 600; }

/* Wide tables scroll inside their own container so the page never does. */
.scroll { overflow-x: auto; }

.foot-nav { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-bottom: 18px;
  font-family: var(--display); font-size: 0.9rem; }
.foot-nav a { color: var(--text); }

/* Compact definition list, for short answers that do not need prose. */
.compact { margin: 0; max-width: 46rem; }
.compact .qa { border-bottom: 1px solid var(--line); padding: 13px 0; }
.compact dt { font-family: var(--display); font-weight: 700; font-size: 0.98rem; margin-bottom: 3px; }
.compact dd { margin: 0; color: var(--muted); font-size: 0.95rem; }

/* ---- The home page checker. The page's main event, so it gets the space. ---- */
.hero { margin-bottom: 28px; }
.checker { background: var(--card); border: 1px solid var(--line); padding: 24px; margin-bottom: 56px; }
.checker .answer { margin: 0 0 24px; border: 1px solid var(--line); }
.check-row { display: grid; grid-template-columns: minmax(200px, 15rem) 1fr; gap: 20px; align-items: start; }
.check-row label { font-family: var(--display); font-size: 0.78rem; font-weight: 700; color: var(--muted); margin-bottom: 8px; }
.checker .ball-row { margin-bottom: 0; }
.checker .ball-input[hidden] { display: none; }
.checker button[type="submit"] { margin-top: 18px; }
.signup { max-width: 22rem; }
.signup input[type="email"] {
  font-family: var(--display); font-size: 1rem; width: 100%; min-height: 44px;
  padding: 11px 12px; background: var(--card); color: var(--text);
  border: 2px solid var(--text); border-radius: 2px; margin-bottom: 12px;
}
.signup label { display: block; font-family: var(--display); font-size: 0.78rem; font-weight: 700; color: var(--muted); margin-bottom: 8px; }
.joined { background: var(--gold); color: var(--ball-ink); padding: 16px 18px; font-family: var(--display); font-weight: 700; }
.pitch .columns { align-items: start; }

@media (max-width: 700px) {
  .check-row { grid-template-columns: 1fr; gap: 16px; }
  .checker { padding: 18px; margin-left: -20px; margin-right: -20px; border-left: 0; border-right: 0; }
}

/* ---- A fact, set as an aside between sections. Yellow because the same
   highlighter marks a number you matched, so the colour already reads as
   "look here" everywhere else on the site. ---- */
.fact {
  position: relative;
  background: var(--gold-panel);
  color: var(--text);
  border: 1px solid var(--text);
  padding: 22px 26px;
  margin: 0 0 56px;
  max-width: 46rem;
}
.fact-head {
  font-family: var(--display); font-weight: 800; font-size: 1.1rem;
  letter-spacing: -0.015em; margin: 0 0 6px;
}
.fact-body { margin: 0; font-size: 1rem; line-height: 1.55; }
/* Dark mode keeps the yellow: a highlighter is yellow on paper and on screen
   alike, and black on it is 13.5:1 either way. */
@media (max-width: 560px) { .fact { padding: 18px 20px; } }

/* ---- Chips: plain navigation between lotteries. Square, like everything
   else here, rather than a pill row. ---- */
.chips { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; }
.chips a {
  display: inline-block; font-family: var(--display); font-size: 0.92rem; font-weight: 600;
  background: var(--card); color: var(--text);
  border: 1px solid var(--text); border-radius: 2px;
  padding: 9px 15px; text-decoration: none;
  transition: background 120ms, color 120ms;
}
.chips a:hover { background: var(--text); color: var(--bg); }

.official {
  margin-top: 36px; padding-top: 14px; border-top: 1px solid var(--line);
  color: var(--muted); font-size: 0.92rem; max-width: var(--measure);
}

/* ---- Account surfaces ---- */
.narrow { max-width: 34rem; }
.stack { display: grid; gap: 14px; justify-items: start; }
.stack label { font-family: var(--display); font-weight: 700; }
.stack input[type="email"], .stack input[type="text"], .stack select { width: 100%; max-width: 28rem; }
.fine { font-size: 0.88rem; color: var(--muted); max-width: var(--measure); }

.inline-form { display: inline; margin: 0; }
.linkish {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: inherit; text-decoration: underline;
}
.linkish:hover { color: var(--live-text); }
.linkish.danger { color: var(--muted); font-size: 0.88rem; }
.linkish.danger:hover { color: var(--live-text); }

/* Messages. Every action that changes something says so. */
.flash { list-style: none; margin: 0 0 24px; padding: 0; display: grid; gap: 8px; }
.flash li {
  padding: 12px 14px; border: 1px solid var(--text);
  font-family: var(--display); font-size: 0.95rem;
}
.flash-success { background: var(--gold-panel); color: var(--text); }
.flash-error { background: var(--live); color: #fff; border-color: var(--text); }
.flash-info { background: var(--paper-soft, transparent); }

.dash-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.dash-head p { margin: 0; }

.won { border: 2px solid var(--text); padding: 20px; margin-bottom: 40px; background: var(--gold-panel); color: var(--text); }
.won h2 { margin-top: 0; }
.win-list, .ticket-list { list-style: none; margin: 0; padding: 0; }
.win-list li + li { margin-top: 24px; padding-top: 24px; border-top: 1px solid var(--text); }

.ticket-list { border-top: 1px solid var(--line); }
.ticket-list li { border-bottom: 1px solid var(--line); padding: 18px 0; }
.ticket-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.ticket-head h3 { margin: 0; font-size: 1.05rem; }
.ticket-list .balls { margin: 10px 0; }
.ticket-list .meta { margin: 6px 0; }

/* How far through its drawings an advance-play ticket is. */
.ticket-list .coverage { font-family: var(--display); font-weight: 600; color: var(--text); }

/* Spent tickets. Present and readable, but visibly not the live list: these
   can never win again, and a dashboard that treats them the same invites
   somebody to keep waiting on paper that is finished. */
.finished { margin-top: 40px; }
.finished .section-head h2 { color: var(--muted); }
.ticket-list.spent li { opacity: 0.72; }
.ticket-list.spent li:hover, .ticket-list.spent li:focus-within { opacity: 1; }
.ticket-list.spent .ball { border-color: var(--line); }
.history { list-style: none; margin: 8px 0 0; padding: 0;
  font-family: var(--display); font-size: 0.85rem; color: var(--muted); }
.history li { padding: 2px 0; }

/* The drawings count. A number between 1 and 26 does not need a full-width
   input, and one that looks like the name field invites a name. */
.narrow-number { width: 6rem; }

.empty-state { border: 1px solid var(--line); padding: 24px; max-width: var(--measure); }
.empty-state p:first-child { margin-top: 0; }

/* The save form: one lottery, several lines. */
.lines { border: 0; padding: 0; margin: 0; }
.lines legend { font-family: var(--display); font-weight: 700; padding: 0; }
/* Top-aligned, not centred. Each group now carries a range label underneath,
   so centring put the line number against the middle of boxes-plus-label
   rather than against the boxes. */
.line { display: flex; align-items: flex-start; gap: 12px; margin: 16px 0; flex-wrap: wrap; }
.line-number {
  font-family: var(--display); font-size: 0.8rem; color: var(--muted);
  width: 1.4em; flex: none; text-align: right; padding-top: 19px;
}
.line-status { align-self: center; }

/* Checked as you type. A number outside its range or entered twice is marked
   at the keystroke, not after the form is submitted. */
.ball-input input.invalid {
  border-color: var(--live); border-width: 3px; color: var(--live-text);
}
.line-status {
  font-family: var(--display); font-size: 0.85rem; color: var(--muted);
  min-height: 1.2em;
}
.line-status.bad { color: var(--live-text); }
.line-status.ok { color: var(--win); font-weight: 700; }
.line-status.ok::before { content: "\2713\00a0"; }
.line-ok .ball-input:not([hidden]) input { border-color: var(--win); }

/* Disabled means disabled. Without overriding the hover rule it lights up red
   on hover as though it were about to do something. */
button[disabled] { opacity: 0.5; cursor: not-allowed; }
button[disabled]:hover {
  background: var(--text); border-color: var(--text); color: var(--bg);
}

.warn {
  border: 2px solid var(--live); padding: 14px 16px; margin: 0 0 28px;
  font-family: var(--display); font-size: 0.95rem; max-width: 46rem;
}

/* ---- What each lottery is playing for next. ---- */
.jackpot-row { list-style: none; margin: 0 0 14px; padding: 0;
  display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }
.jackpot-row li { border-left: 3px solid var(--text); padding: 2px 0 2px 14px; }
.jackpot-row a { display: block; font-family: var(--display); font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted); text-decoration: none; }
.jackpot-row a:hover { color: var(--live-text); }
.jackpot-row .figure { display: block; font-family: var(--display); font-weight: 800;
  font-size: clamp(1.6rem, 5vw, 2.3rem); letter-spacing: -0.03em; line-height: 1.05;
  margin: 2px 0; }
.jackpot-row .when { font-family: var(--display); font-size: 0.85rem; color: var(--muted); }
/* Drawn, but we do not have the numbers yet. The card stays, because a lottery
   disappearing for a few hours every drawing night reads as a broken site. It
   changes colour so nobody reads it as a drawing still to come. */
.jackpot-row li.waiting { border-left-color: var(--live); }
.jackpot-row .when.pending { color: var(--live-text); }

/* ---- Who won. The answer people arrive with the morning after. ---- */
.who-won {
  font-family: var(--display); font-weight: 700; font-size: 0.95rem;
  line-height: 1.35; margin: 10px 0 0;
  /* A coloured left border on a callout is on every list of generated-design
     tells and it was here. The emphasis it was reaching for is weight and
     colour on the text itself, which is cheaper and reads better. */
  color: var(--gold);
}
.winners .tier-winners { width: 100%; }
/* The jackpot line is the one people look for, so it is the one that looks
   different. Everything below it is reference.
   Deliberately not called .jackpot-row: that class belongs to the homepage
   strip, where it is a CSS grid, and putting a grid on a table row blockifies
   every cell in it. */
.tier-winners .top-tier th, .tier-winners .top-tier .count {
  font-size: 1.05rem; background: var(--gold-panel); color: var(--text);
}
.tier-winners .count { font-variant-numeric: tabular-nums; font-weight: 700; }
.tier-winners .amount-cell { white-space: nowrap; }
/* The split row carries a disclosure, not data, so it gets no cell borders of
   its own and sits tight under the tier it belongs to. */
.tier-winners .split-row td { border-top: 0; padding-top: 0; }
.tier-winners summary {
  font-family: var(--display); font-size: 0.8rem; font-weight: 600; color: var(--muted);
  cursor: pointer; padding: 2px 0;
}
.tier-winners summary:hover { color: var(--live-text); }
.splits { list-style: none; margin: 6px 0 4px; padding: 0;
  display: flex; flex-wrap: wrap; gap: 4px 22px; }
.splits li { font-family: var(--display); font-size: 0.85rem; }
.splits .mult { font-weight: 800; }
.splits .count { font-weight: 700; }

/* ---- The account pitch. ---- */
.what-we-store { border: 1px solid var(--text); padding: 20px 22px; }
.what-we-store h3 { font-size: 0.78rem;
  color: var(--muted); margin-bottom: 10px; }
.what-we-store ul { margin: 0; padding-left: 18px; }
.what-we-store li { margin-bottom: 7px; }
.what-we-store li:last-child { margin-bottom: 0; }

/* ---- Lottery news. Headlines out to the newsrooms, nothing republished. ---- */
.story-list { list-style: none; margin: 0 0 14px; padding: 0;
  border-top: 1px solid var(--line); }
.story-list li { border-bottom: 1px solid var(--line); padding: 14px 0; }
.story-list a { font-family: var(--display); font-weight: 700; font-size: 1.02rem;
  text-decoration: none; }
.story-list a:hover { color: var(--live-text); text-decoration: underline; }
.story-list .meta { margin: 4px 0 0; }

/* ---- State rules. A list of answers, each with the source beside it.
   Deliberately NOT .fact, which is the single yellow aside used elsewhere:
   five of those in a row reads as five separate alarms, and its 56px bottom
   margin was written for one. This is a reference list, so it is set as one. ---- */
/* ---- The receipt under a fact: where it came from and when it was read.
   Small and muted on purpose. It has to be there, because a figure with no
   source is indistinguishable from one somebody invented, but it is not the
   thing being said. ---- */
.receipt {
  display: block; margin-top: 6px;
  font-family: var(--display); font-size: 0.78rem; color: var(--muted);
}
.receipt a { color: var(--muted); }
p.receipt { margin-top: 18px; max-width: 46rem; }

/* ---- The state comparison table. The whole argument for these pages is that
   the numbers differ more than people expect, so they are set side by side. ---- */
.compare { max-width: 52rem; margin-bottom: 34px; }
.compare td:first-child { font-weight: 700; }
.compare .unknown { font-family: var(--body); font-style: italic; font-size: 0.92rem; }

/* ---- Checking a scanned ticket against the paper in somebody's hand.
   The numbers are set large and widely spaced because the entire job of this
   screen is making one wrong digit easy to notice. Body-sized text in a narrow
   box is exactly how a misread 43 for a 48 gets waved through. ---- */
.read-lines { list-style: none; margin: 0 0 8px; padding: 0; counter-reset: line; }
.read-line {
  counter-increment: line;
  /* The balls share their row, so the row has to be about as wide as the
     panel they were designed in. Left to fill a desktop page they end up a
     hand's width apart, which stops reading as one line of a ticket. */
  display: grid; grid-template-columns: 2.2rem minmax(0, 560px); gap: 0 12px;
  align-items: start; padding: var(--s5) 0 var(--s6);
  border-bottom: 1px solid var(--line);
}
.read-line::before {
  content: counter(line);
  font-family: var(--display); font-weight: 800; font-size: 1.1rem;
  color: var(--muted); padding-bottom: 10px;
}
/* The numbers themselves are the checker's balls, styled with it further down
   so the two screens cannot drift apart. What used to be here was one wide
   text box holding "6 7 8 11 15", which is the hardest shape there is to
   proofread a digit in. */
.read-line label { display: block; margin: 0; }

/* ------------------------------------------------------------------ scanning

   The scan offer sits above the typing form, so it has to read as the faster
   way without shouting over the thing somebody came to do. Card, brand rule
   down one edge, camera, and the free count stated plainly.
*/

.scan-offer {
  margin: 0 0 2.5rem;
}

.scan-form,
.scan-off {
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 3px solid var(--live);
  border-radius: 4px;
  padding: 1.25rem 1.25rem 1rem;
}

.scan-off {
  border-left-color: var(--line);
}

.scan-pitch h2,
.scan-off h2 {
  font-size: 1.15rem;
  margin: 0 0 0.25rem;
}

.scan-pitch p,
.scan-off p {
  margin: 0 0 1rem;
  color: var(--muted);
}

.scan-off p { margin-bottom: 0; }

/* The whole block is the tap target, which on a phone matters more than it
   does anywhere else: this is the one control somebody uses one-handed. */
.scan-drop {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.9rem 1rem;
  border: 2px dashed var(--line);
  border-radius: 4px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.scan-drop:hover,
.scan-drop:focus-within {
  border-color: var(--live);
  background: color-mix(in srgb, var(--live) 4%, transparent);
}

/* Off-screen rather than display:none, so it stays focusable by keyboard. */
.scan-drop input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.scan-icon { color: var(--gold); flex: 0 0 auto; }

.scan-drop-text { display: flex; flex-direction: column; gap: 0.15rem; }
.scan-drop-text strong { font-size: 1rem; }
.scan-drop-text small { color: var(--muted); font-size: 0.85rem; }

.scan-go { margin: 1rem 0 0; }
.scan-go .button { width: 100%; text-align: center; }

.scan-left {
  margin: 0.85rem 0 0;
  font-size: 0.9rem;
  color: var(--muted);
}

.scan-left strong { color: var(--text); }

/* The working panel replaces the offer rather than appearing beneath it. Two
   stacked cards, one of them an emptied husk of the form, reads as a bug. */
.scan-form.is-working { display: none; }

/* --------------------------------------------------------- the working state

   A slip with three rows of boxes and a beam passing over it. The boxes light
   as the beam reaches them, which is the only honest thing an animation can
   say here: something is being read, top to bottom.
*/

.scan-working {
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 4px;
  padding: 1.5rem 1.25rem 1.25rem;
  text-align: center;
}

.scan-art { display: flex; justify-content: center; margin-bottom: 1.1rem; }

.scan-slip {
  position: relative;
  width: 168px;
  padding: 0.85rem 0.7rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 3px;
  overflow: hidden;
}

.scan-row {
  display: flex;
  gap: 5px;
  justify-content: center;
  margin-bottom: 7px;
}

.scan-row:last-of-type { margin-bottom: 0; }

.scan-row i {
  display: block;
  width: 22px;
  height: 13px;
  border-radius: 2px;
  background: var(--line);
  opacity: 0.55;
}

/* The light that reads the ticket, in the same colour as every other light in
   this room. It was the on-air red, which is the colour this site uses for the
   Powerball, for the live dot and for an error, and a scanner that looks like
   an error is a scanner that looks like it failed. The beam over the machine
   is lilac and so is this one. */
.scan-beam {
  position: absolute;
  left: 0;
  right: 0;
  height: 34%;
  top: -34%;
  background: linear-gradient(
    to bottom,
    transparent,
    color-mix(in srgb, var(--lilac) 26%, transparent),
    transparent
  );
  border-bottom: 1px solid var(--lilac);
  animation: scan-sweep 1.7s ease-in-out infinite;
}

@keyframes scan-sweep {
  0%   { top: -34%; }
  100% { top: 100%; }
}

/* Each row lights in turn, a beat behind the beam that reaches it. */
.scan-row i { animation: scan-fill 1.7s ease-in-out infinite; }
.scan-slip .scan-row:nth-of-type(1) i { animation-delay: 0.25s; }
.scan-slip .scan-row:nth-of-type(2) i { animation-delay: 0.55s; }
.scan-slip .scan-row:nth-of-type(3) i { animation-delay: 0.85s; }

/* A row lights gold as the beam passes it, because what the beam is finding is
   numbers, and a number on this site is gold. Lilac light, gold findings. */
@keyframes scan-fill {
  0%, 12%  { background: var(--line); opacity: 0.55; }
  22%, 70% { background: var(--gold); opacity: 1; }
  100%     { background: var(--line); opacity: 0.55; }
}

.scan-stage {
  margin: 0 0 0.75rem;
  font-family: var(--display);
  font-size: 1.05rem;
}

.scan-bar {
  height: 4px;
  background: var(--line);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 0.75rem;
}

.scan-bar span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--gold);
  transition: width 0.2s ease;
}

/* Once the photo is up there is no percentage left to report, so the bar
   stops claiming one and shows movement instead of a number it does not have. */
.scan-working.is-reading .scan-bar span {
  width: 100% !important;
  animation: scan-pulse 1.4s ease-in-out infinite;
}

@keyframes scan-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

.scan-note {
  margin: 0;
  font-size: 0.88rem;
  color: var(--muted);
}

/* Somebody who has asked for less movement gets the words and none of it. */
@media (prefers-reduced-motion: reduce) {
  .scan-beam { animation: none; opacity: 0.5; top: 33%; }
  .scan-row i { animation: none; }
  .scan-working.is-reading .scan-bar span { animation: none; }
}

/* ------------------------------------------------------ a form that is busy

   Any submit button that has been pressed says so. The commonest reason a
   person submits a form twice is that the first press produced no evidence it
   had happened.

   There used to be a rule here reading `.button[data-busy]`, setting opacity
   and `pointer-events: none`. It was meant to style a button while a form was
   in flight. `data-busy` is not the state though, it is the WORDING: a
   template writes `data-busy="Saving your ticket..."` to say what the button
   should read once pressed, and it writes it when the page is built. So every
   button that offered its own wording was born greyed out and unclickable, and
   the two that did were the save button on the scan confirm screen and the
   save button on the type-it-in page: both ends of the only paid feature on
   the site.

   The state was already on the button. `_busy.html` sets `disabled`, and
   `button[disabled]` above already dims it and changes the cursor. So there is
   nothing to put back here. The lesson is the rule the test now enforces: a
   selector that disables something may key off state the browser owns, and
   never off an attribute a template author writes by hand. */




/* ============================================================================
   Pieces the rebuilt pages need that the old stylesheet had no equivalent for.
   ========================================================================= */

/* ---- The strip. Every lottery one tap away on every page, which is
   navigation and internal linking doing the same job. ---- */
.strip { border-bottom: 1px solid var(--line); }
.strip .wrap {
  display: flex; gap: var(--s6); padding-block: 11px;
  overflow-x: auto; scrollbar-width: none;
}
.strip .wrap::-webkit-scrollbar { display: none; }
.strip a {
  white-space: nowrap; color: var(--muted); text-decoration: none;
  transition: color var(--t-fast) var(--ease);
}
.strip a:hover { color: var(--text); }
.strip a::before { content: "\203A"; margin-right: 7px; color: var(--accent-line); }

/* ---- Sections that centre their own copy ---- */
.center { text-align: center; }
.center h2 { max-width: 20ch; margin: var(--s3) auto 0; }
.center .lede { margin-left: auto; margin-right: auto; }
.wrap-in { width: 100%; }
.three {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--s5); margin-top: 56px;
}
.three .panel { display: flex; flex-direction: column; }
.three h3 { margin: var(--s3) 0 var(--s2); }
.three p { color: var(--muted); font-size: .94rem; margin: 0; }

/* ---- Form controls, in the new world -------------------------------------
   Every select, text input and number box on the site. The old ones were
   2px ink outlines on a light page, which on a near-black page reads as a
   cutout rather than a field.
   ------------------------------------------------------------------------- */
select, input[type="email"], input[type="text"], input[type="number"], textarea {
  font-family: var(--display); font-size: .96rem;
  padding: 11px var(--s3); min-height: 44px; width: 100%; max-width: 28rem;
  background: var(--raised); color: var(--text);
  border: 1px solid var(--line-2); border-radius: var(--r-btn);
  transition: border-color var(--t-fast) var(--ease);
}
select:hover, input:hover, textarea:hover { border-color: rgba(255, 255, 255, .18); }
::placeholder { color: rgba(255, 255, 255, .3); }
label { display: block; margin-bottom: var(--s2);
  font-family: var(--display); font-size: .9rem; color: var(--muted); }
legend { font-family: var(--mono); font-size: .68rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted); padding: 0; margin-bottom: var(--s3); }
fieldset { border: 0; padding: 0; margin: 0 0 var(--s6); }
.checkbox { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s5); }
.checkbox label { margin: 0; color: var(--text); }
.checkbox input { width: 20px; height: 20px; min-height: 0; accent-color: var(--gold); }
button.block, .button.block { display: flex; width: 100%; }

/* ---- Tables. Data on a dark page wants rules, not boxes. ---- */
table { width: 100%; border-collapse: collapse; margin: var(--s5) 0; }
thead th {
  font-family: var(--mono); font-size: .66rem; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
  text-align: left; padding: var(--s3) var(--s3) var(--s3) 0;
  border-bottom: 1px solid var(--line-2);
}
tbody td, tbody th {
  text-align: left; font-weight: 400; padding: var(--s3) var(--s3) var(--s3) 0;
  border-bottom: 1px solid var(--line);
}
tbody tr:last-child td, tbody tr:last-child th { border-bottom: 0; }
tbody th { font-weight: 500; }
caption { caption-side: top; text-align: left; color: var(--muted);
  font-size: .88rem; padding-bottom: var(--s3); }
tr.retired td, tr.retired th { color: var(--muted); }

/* ---- Prose ---- */
.prose { max-width: 66ch; }
/* With a rail beside it, the measure belongs to the text column and not to the
   grid. Capping the grid squeezed both the prose and the rail into 66ch between
   them, which left a column of narrow text, a rail stranded in the middle, and
   the right third of the page empty: exactly the layout the rail exists to
   fix. */
.prose.with-rail { max-width: none; }
.prose.with-rail > div { max-width: 66ch; }
.prose p { margin: 0 0 var(--s5); }
.prose h2 { margin-top: var(--s7); }
.prose h3 { margin-top: var(--s6); margin-bottom: var(--s2); }
.prose ul, .prose ol { margin: 0 0 var(--s5); padding-left: var(--s5); }
.prose li { margin-bottom: var(--s2); }

/* ---- FAQ ---- */
.faq dl { margin: 0; max-width: 66ch; }
.faq .qa { border-bottom: 1px solid var(--line); padding: var(--s5) 0; }
.faq .qa:last-child { border-bottom: 0; }
.faq dt { font-weight: 500; font-size: 1.02rem; margin-bottom: var(--s2); }
.faq dd { margin: 0; color: var(--muted); }

/* ---- Breadcrumbs ---- */
.crumbs { padding-top: var(--s4); }
.crumbs ol { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0; padding: 0;
  font-family: var(--mono); font-size: .68rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); }
.crumbs li + li::before { content: "/"; margin-right: 6px; color: var(--accent-line); }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--text); }

/* ---- The five pages a game has ---- */
.game-nav { display: flex; flex-wrap: wrap; gap: var(--s1); margin: 0 0 var(--s7); }
.game-nav a {
  padding: 8px 14px; border-radius: var(--r-btn); font-size: .9rem;
  color: var(--muted); text-decoration: none;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.game-nav a:hover { background: var(--raised); color: var(--text); }
.game-nav a[aria-current="page"] { background: var(--raised); color: var(--text); }

/* ---- Chips ---- */
.chips { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s2); margin: 0; padding: 0; }
.chips a {
  display: inline-block; font-size: .9rem; font-weight: 500;
  background: #171719; color: var(--text);
  border: 0; border-radius: var(--r-btn); padding: 10px 15px; text-decoration: none;
  box-shadow: var(--e-subtle), var(--e-medium);
  transition: transform var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.chips a:hover { background: #1E1E21; transform: translateY(-1px); }

/* ---- Footer ---- */
footer.site {
  border-top: 1px solid var(--line);
  margin-top: var(--s8); padding: var(--s7) 0 var(--s8);
  font-size: .9rem;
}
footer.site p { max-width: 62ch; margin: 0 0 var(--s3); color: var(--muted); }
footer.site strong { color: var(--text); font-weight: 600; }
.foot-nav { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5); margin-bottom: var(--s5); }
.foot-nav a { color: var(--muted); text-decoration: none; }
.foot-nav a:hover { color: var(--text); }

/* ---- Flash messages ---- */
.flash { list-style: none; margin: var(--s5) 0 0; padding: 0; }
.flash li {
  padding: var(--s3) var(--s4); margin-bottom: var(--s2);
  border-radius: var(--r-card); border: 1px solid var(--line-2);
  background: var(--card); font-size: .94rem;
}
.flash-success { border-color: rgba(95, 227, 155, .3); }
.flash-error { border-color: rgba(255, 77, 46, .4); }

/* ---- A fact, set as an aside between sections ---- */
.fact {
  margin: var(--s8) 0; padding: var(--s6);
  border: 1px solid rgba(255, 194, 58, .18); border-radius: var(--r-card);
  background: var(--gold-panel); box-shadow: var(--e-subtle);
}
.fact-head { font-weight: 500; font-size: 1.06rem; margin: 0 0 var(--s2); color: var(--text); }
.fact-body { margin: 0; color: var(--muted); max-width: 70ch; }

@media (max-width: 900px) {
  .three { grid-template-columns: 1fr; }
  .stub-grid { grid-template-columns: 1fr; }
}


/* ---- The number boxes ------------------------------------------------------
   These come after the generic input rule on purpose: a ball slot is not a
   text field with a radius, it is an empty position in a tray that fills with
   the ball's own material the moment it carries a number. That fill is the
   entry animation this form gets instead of a decorative one.
   ------------------------------------------------------------------------- */
.ball-row { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5); margin-bottom: var(--s3); align-items: flex-start; }
.ball-group { display: flex; flex-direction: column; gap: var(--s2); }
.ball-boxes { display: flex; flex-wrap: wrap; gap: var(--s2); }
.range-label {
  font-family: var(--mono); font-size: .62rem; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.ball-group.special .range-label { color: var(--live-text); }

.ball-input input[type="number"] {
  width: 54px; height: 54px; min-height: 0; max-width: none; padding: 0;
  text-align: center; border-radius: 50%;
  font-family: var(--display); font-size: 1.1rem; font-weight: 650;
  font-stretch: 88%; font-variant-numeric: tabular-nums;
  background: rgba(255, 255, 255, .02); color: var(--text);
  border: 1px solid var(--line-2);
  -moz-appearance: textfield;
  transition: border-color var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.ball-input input::-webkit-outer-spin-button,
.ball-input input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.ball-input input:focus {
  border-color: rgba(255, 194, 58, .5);
  box-shadow: 0 0 0 3px rgba(255, 194, 58, .12);
}
/* Filled: the slot becomes the ball. */
.ball-input input:not(:placeholder-shown) {
  border-color: transparent; color: var(--ball-ink);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .45);
  background: radial-gradient(circle at 34% 28%,
    #FFFEFC 0%, #F7F3E9 26%, #E4DECF 52%, #B3AC9A 78%, #837D6E 100%);
  box-shadow:
    inset -8px -11px 19px rgba(28, 24, 16, .42),
    inset 8px 10px 16px rgba(255, 255, 255, .5),
    0 12px 18px -12px rgba(0, 0, 0, .95);
}
.ball-input.special input { border-color: rgba(255, 77, 46, .45); }
.ball-input.special input:not(:placeholder-shown) {
  color: #fff; text-shadow: 0 1px 2px rgba(80, 14, 0, .5);
  background: radial-gradient(circle at 34% 28%,
    #FF9E86 0%, #F4573A 26%, #DC3318 54%, #96200C 80%, #5E1406 100%);
}
.ball-input.has-error input { border-color: var(--live); background: rgba(255, 77, 46, .12); }

/* ---- The six boxes share their row, at every width -------------------------
   Six boxes at a fixed 54px plus their gaps come to more than the check panel
   is wide, anywhere. So the bonus ball dropped to a second line and took its
   label down with it: two rows where one would do, and the second one carrying
   a single ball, directly above the button.

   A fixed width is the wrong tool for a row that has to fit a panel on a
   desktop and a phone. The boxes share what there is instead, five parts to
   the main group and one to the bonus ball, which keeps the two groups reading
   as two groups at any size. `aspect-ratio` keeps them circular wherever they
   land, and the cap stops them growing past the size a ball is everywhere else
   on the site: unbounded, a 560px screen gave each one 74px, which is the
   panel shouting rather than the panel fitting.
   ------------------------------------------------------------------------- */
.hero .panel .ball-row,
.read-line .ball-row { flex-wrap: nowrap; gap: var(--s3); align-items: flex-start; }
.hero .panel .ball-group[data-group="main"],
.read-line .ball-group[data-group="main"] { flex: 5 1 0; min-width: 0; }
.hero .panel .ball-group.special,
.read-line .ball-group.special { flex: 1 1 0; min-width: 0; }
.hero .panel .ball-boxes,
.read-line .ball-boxes { gap: 5px; flex-wrap: nowrap; justify-content: space-between; }
.hero .panel .ball-input,
.read-line .ball-input { flex: 1 1 0; min-width: 0; display: flex; justify-content: center; }
.hero .panel .ball-input input,
.read-line .ball-input input {
  width: 100%; max-width: 54px; min-width: 0; height: auto;
  aspect-ratio: 1; font-size: 1rem;
}

/* ---- The rest of the form, the same way --------------------------
   The boxes were the loud problem. The quiet one was everything around
   them: three stacked labels, each on its own line above the thing it
   named, on a panel that has a heading saying what it is.

   So the lottery picker becomes one row, because a label reading "Lottery"
   beside a control that already reads "Powerball" does not need a line of
   its own. "Your numbers" goes to screen readers only, because the label
   printed under the boxes says the same thing with the range attached, and
   two of them was one too many at any width. And the bonus ball's range
   lifts out of the flow: it is a caption on a 45px column, so left in the
   flow it wrapped to three lines and set the height of the whole row.
   Absolute puts it on the same line as the other caption, reading right to
   left into the space beside it, which is empty.
   ---------------------------------------------------------------------- */
.hero .panel .pick { display: flex; align-items: center; gap: var(--s3); }
.hero .panel .pick label { flex: 0 0 auto; margin: 0; }
.hero .panel .pick select { flex: 1 1 auto; width: auto; min-width: 0; margin: 0; }
.hero .panel .entry { margin-top: var(--s4); }

.hero .panel .entry > label {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.hero .panel .ball-row,
.read-line .ball-row { margin-bottom: 0; }
.hero .panel .ball-group.special,
.read-line .ball-group.special { position: relative; }
.hero .panel .ball-group.special .range-label,
.read-line .ball-group.special .range-label {
  position: absolute; top: 100%; right: 0;
  margin-top: var(--s2); white-space: nowrap;
}

.hero .panel .hint { margin: var(--s3) 0; }

/* The two captions sit on one line beside each other, so they are set smaller
   and tighter here than a caption is elsewhere. The narrowest that line ever
   gets is the panel in the two column hero just before it collapses, where
   thirteen pixels separated them at the site's usual tracking. */
.hero .panel .range-label,
.read-line .range-label { font-size: .58rem; letter-spacing: .1em; }

/* ---- The state picker, inline rather than stacked ---- */
.cutoff { margin: var(--s5) 0 0; }
.cutoff form { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.cutoff label { width: 100%; margin: 0 0 var(--s2); }
.cutoff select { width: auto; min-width: 13rem; max-width: 18rem; min-height: 40px; padding: 8px var(--s3); }
.cutoff button { min-height: 40px; padding: 8px var(--s4); font-size: .88rem; }

/* ---- The answer, inside the check panel ---- */
.answer { border: 1px solid var(--line-2); border-radius: var(--r-card);
  padding: var(--s5); margin: var(--s4) 0; background: rgba(255, 255, 255, .02); }
.answer.win { border-color: rgba(95, 227, 155, .35); }
.verdict { font-size: 1.15rem; font-weight: 500; margin: 0 0 var(--s2); line-height: 1.24; }
.answer.win .verdict mark { background: var(--win); color: var(--ball-ink);
  padding: 2px 8px; border-radius: var(--r-chip); }
.amount-won { font-weight: 600; font-stretch: 84%; letter-spacing: -.04em;
  font-size: clamp(1.8rem, 4.6vw, 2.6rem); line-height: 1; margin: var(--s3) 0;
  color: var(--gold); }
.amount-won.unknown { font-size: 1rem; font-weight: 400; color: var(--muted);
  letter-spacing: 0; font-stretch: 100%; }
.answer .balls { margin-top: var(--s4); }
.errors { color: var(--live-text); font-size: .92rem; margin-bottom: var(--s3); }
.errors ul { margin: 0; padding-left: var(--s5); }

/* ---- The tray on the home page ---- */
.balls.tray { justify-content: flex-start; gap: 10px; margin-bottom: var(--s4); }
.balls.tray .ball { translate: 0 calc(var(--y, 0) * 1px); }
.balls.mini { gap: 6px; margin: var(--s3) 0 0; }

/* ============================================================================
   THE INNER PAGES

   The home page is a lit studio and, until this section existed, every other
   page was a text document sitting on a black background. Same tokens, none of
   the light: an h1 hard against the top of the screen, a measure of prose down
   the left, and the right third of the viewport empty from the masthead to the
   footer.

   The fix is not nineteen redesigns. It is the three things the home page has
   and the inner pages did not: light at the top, the right column doing work,
   and sections that arrive rather than simply being there.
   ========================================================================= */

/* ---- The page head ---------------------------------------------------------
   A shallower relative of the home page's stage. The lamp is further back and
   further away, because this is the top of a reference page rather than the
   opening of the site, and a beam as strong as the home page's would make
   every page look like a landing page.
   --------------------------------------------------------------------------- */
.page-head {
  position: relative;
  /* Full bleed out of the wrapper and back in. Clipped at the wrapper's own
     edge the light stopped in a straight vertical line partway across the
     screen, which reads as the edge of a panel rather than as a lamp. */
  margin-inline: calc(50% - 50vw);
  margin-bottom: var(--s7);
  padding: var(--s6) max(var(--s5), calc(50vw - 33rem + var(--s5)));
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}
.page-head .beam { inset: -40% -14% auto; height: 150%; }
.page-head .beam::before {
  width: min(1100px, 120vw); top: -30%; height: 120%;
  background:
    radial-gradient(40% 52% at 50% 0%, rgba(56, 49, 158, .34), transparent 76%),
    radial-gradient(76% 22% at 50% 62%, rgba(30, 26, 112, .2), transparent 80%);
  filter: blur(34px);
}
.page-head .beam::after { opacity: .3; }

.page-head-in {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: var(--s6) var(--s7); align-items: center;
}
/* A head with nothing to put beside it keeps the measure rather than stretching
   a heading across the full width, which is the usual way a one-column page
   ends up unreadable. */
.page-head-in.solo { display: block; max-width: 46rem; }

.page-head h1 {
  margin: var(--s3) 0 0;
  font-size: clamp(2.2rem, 4.8vw, 3.5rem);
  max-width: 15ch;
}
.page-head .lede { margin: var(--s4) 0 0; font-size: 1.06rem; }
.page-head-aside { min-width: 0; }

@media (max-width: 860px) {
  .page-head-in { grid-template-columns: minmax(0, 1fr); }
  .page-head { padding-top: var(--s5); }
}

/* ---- The figure card -------------------------------------------------------
   What goes in the right column of a page head, and in the right column of a
   section that would otherwise leave one empty. One number, what it is, and
   where it came from.
   --------------------------------------------------------------------------- */
.figure-card {
  border: 1px solid var(--line-2); border-radius: var(--r-panel);
  background: var(--card); box-shadow: var(--e-subtle), var(--e-medium);
  padding: var(--s5);
}
.figure-card + .figure-card { margin-top: var(--s3); }
.figure-card .mono { display: block; margin: 0 0 var(--s2); }
.figure-card .figure {
  font-weight: 600; font-stretch: 84%; letter-spacing: -.045em;
  font-size: clamp(1.9rem, 4vw, 2.7rem); line-height: 1;
  margin: 0; color: var(--gold);
}
.figure-card .figure .scale {
  font-size: .42em; font-weight: 500; font-stretch: 100%; letter-spacing: -.01em;
  color: var(--text); margin-left: .35em;
}
.figure-card .figure.plain { color: var(--text); }
.figure-card p.sub { margin: var(--s3) 0 0; font-size: .86rem; color: var(--muted); }
.figure-card p.sub:first-of-type { margin-top: var(--s2); }
.figure-card .counter { margin-top: var(--s4); }
.figure-card .counter .flap { min-width: 48px; }
.figure-card .counter .flap .n { font-size: 1.5rem; }

/* ---- The lit tray ----------------------------------------------------------
   The winning numbers on a lottery's own page. This is the object somebody
   arrived from Google to look at, and it was a 46px row of balls with a caption
   under it, indistinguishable from the fifteen rows of history further down.
   --------------------------------------------------------------------------- */
.draw-tray {
  position: relative;
  border: 1px solid var(--line-2); border-radius: var(--r-panel);
  background: linear-gradient(180deg, var(--raised), var(--card));
  box-shadow: var(--e-subtle), var(--e-medium), var(--e-strong);
  padding: var(--s5) var(--s5) var(--s4);
  overflow: hidden;
}
/* The lamp over the tray, and the reason the balls underneath have anything to
   catch. Without it they are flat discs on a flat panel. */
.draw-tray::before {
  content: ""; position: absolute; inset: -60% -20% auto; height: 120%;
  background: radial-gradient(42% 58% at 50% 0%, rgba(255, 255, 255, .07), transparent 72%);
  pointer-events: none;
}
.draw-tray > * { position: relative; }
.draw-tray .balls { margin: 0; gap: 10px; }
.draw-tray .ball { width: 54px; height: 54px; font-size: 1.05rem; }
.draw-tray .drawn-on { margin: var(--s4) 0 0; }
.draw-tray .verdict-line { margin: var(--s3) 0 0; font-size: .96rem; line-height: 1.4; }
.draw-tray .verdict-line b { color: var(--gold); font-weight: 600; }
@media (max-width: 430px) {
  .draw-tray { padding: var(--s4); }
  .draw-tray .ball { width: 42px; height: 42px; font-size: .9rem; }
  .draw-tray .balls { gap: 7px; }
}

/* ---- The matrix shape ------------------------------------------------------
   Five white and one gold is a different game from five white and one red, and
   the lottery index said so only in a sentence. Empty balls read as the shape
   of a ticket, which is how somebody recognises their game in a list without
   reading a word of it.
   --------------------------------------------------------------------------- */
.matrix { display: flex; gap: 5px; align-items: center; margin: 0; padding: 0; list-style: none; }
/* Two class names deep on purpose. A bare `.matrix li` loses to the card rule
   below, which also targets an li at one class of specificity and comes later,
   and the balls came out as rounded squares the size of the card's padding. */
.matrix li, .lottery-index .matrix li {
  width: 17px; height: 17px; flex: none; padding: 0; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .28);
  background: rgba(255, 255, 255, .05);
  display: block; box-shadow: none;
}
.matrix li.special, .lottery-index .matrix li.special {
  border-color: rgba(255, 77, 46, .75); background: rgba(255, 77, 46, .16);
}
.matrix li.special[data-ball="gold"],
.lottery-index .matrix li.special[data-ball="gold"] {
  border-color: rgba(255, 194, 58, .8); background: rgba(255, 194, 58, .18);
}
.matrix .plus, .lottery-index .matrix .plus {
  width: auto; height: auto; border: 0; background: none; border-radius: 0;
  font-family: var(--mono); font-size: .68rem; color: var(--muted); margin: 0 2px;
}

/* ---- The lottery index, as cards rather than a stack of paragraphs --------- */
.lottery-index { display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fill, minmax(min(21rem, 100%), 1fr)); }
.lottery-index li {
  border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--card); padding: var(--s5);
  display: flex; flex-direction: column; gap: var(--s3);
  transition: border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.lottery-index li:hover { border-color: var(--accent-line); transform: translateY(-1px); }
.lottery-index .index-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s3); }
.lottery-index h2 { font-size: 1.32rem; margin: 0; }
.lottery-index h2 a { text-decoration: none; }
.lottery-index h2 a:hover { text-decoration: underline; text-decoration-color: var(--gold); }
.lottery-index .play { margin: 0; font-size: .92rem; color: var(--muted); }
.lottery-index .when { margin: 0; }
.lottery-index .pot { margin: 0; font-weight: 600; font-stretch: 86%; letter-spacing: -.03em;
  font-size: 1.5rem; line-height: 1; color: var(--gold); }
.lottery-index .pot .scale { font-size: .5em; font-weight: 500; font-stretch: 100%;
  letter-spacing: 0; color: var(--text); margin-left: .3em; }
.lottery-index .deep { margin: auto 0 0; padding-top: var(--s3);
  border-top: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: var(--s1) var(--s4); }
.lottery-index .deep a { font-size: .88rem; color: var(--muted); text-decoration: none; }
.lottery-index .deep a:hover { color: var(--text); text-decoration: underline; text-decoration-color: var(--gold); }

/* ---- State facts, as cards --------------------------------------------------
   Four figures somebody can act on, previously a definition list in a 60%
   column with the right third of the screen empty beside it.
   --------------------------------------------------------------------------- */
.rules { display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr)); margin: 0; }
.rule {
  display: block; border: 1px solid var(--line); border-radius: var(--r-card);
  background: var(--card); padding: var(--s5); margin: 0;
}
.rule dt {
  font-family: var(--mono); font-size: .68rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
  margin: 0 0 var(--s3); width: auto;
}
.rule dd { margin: 0; font-size: .98rem; line-height: 1.55; }
.rule dd strong { font-weight: 600; font-stretch: 88%; letter-spacing: -.02em;
  font-size: 1.32rem; color: var(--text); }
.rule .receipt { display: block; margin-top: var(--s3); font-size: .78rem; color: var(--muted); }
.rule .receipt a { color: var(--muted); }
.rule .receipt a:hover { color: var(--text); }

/* ---- A prose section with a rail beside it ---------------------------------
   The guides and the privacy page are one column of text and an empty right
   third. The rail is what belongs in that space on a reference page: where you
   are, and where to go next.
   --------------------------------------------------------------------------- */
.with-rail { display: grid; grid-template-columns: minmax(0, 1fr) 15rem; gap: var(--s6) var(--s7); align-items: start; }
.rail { position: sticky; top: 84px; border-left: 1px solid var(--line-2); padding-left: var(--s4); }
.rail p.mono { margin: 0 0 var(--s3); }
.rail ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.rail a { font-size: .9rem; color: var(--muted); text-decoration: none; }
.rail a:hover { color: var(--text); text-decoration: underline; text-decoration-color: var(--gold); }
@media (max-width: 860px) {
  .with-rail { grid-template-columns: minmax(0, 1fr); }
  .rail { position: static; border-left: 0; border-top: 1px solid var(--line-2);
    padding: var(--s4) 0 0; }
  /* Wraps rather than scrolls sideways. It was a horizontal scroller with no
     affordance, so on a phone the last few links were simply off the right of
     the screen with nothing to say they existed. A contents list is four to
     ten short links; wrapping shows all of them. */
  .rail ul { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); overflow: visible; }
  .rail li { flex: none; }
}

/* ---- The game navigation, as a real set of tabs ---------------------------- */
.game-nav {
  display: flex; gap: var(--s1); flex-wrap: wrap;
  border-bottom: 1px solid var(--line-2); padding: 0 0 var(--s2); margin: 0 0 var(--s7);
}
/* Straight under the page head the tabs belong to it, so the head's own bottom
   margin is the gap and a second one would read as a break in the page. */
.page-head + .game-nav { margin-top: calc(var(--s7) * -1 + var(--s5)); }
.game-nav a {
  padding: 8px 14px; border-radius: var(--r-btn);
  font-size: .92rem; font-weight: 500; color: var(--muted); text-decoration: none;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.game-nav a:hover { background: var(--raised); color: var(--text); }
.game-nav a[aria-current="page"] { background: var(--raised); color: var(--text); box-shadow: var(--e-subtle); }

/* ---- Tables, given the weight of the world they live in -------------------- */
.panel-table {
  border: 1px solid var(--line); border-radius: var(--r-panel);
  background: var(--card); overflow: hidden;
}
.panel-table table { margin: 0; }
.panel-table caption { padding: var(--s4) var(--s5) 0; text-align: left; color: var(--muted); font-size: .88rem; }
.panel-table thead th { padding-inline: var(--s5); }
.panel-table td, .panel-table tbody th { padding-inline: var(--s5); }
.panel-table tbody tr { transition: background var(--t-fast) var(--ease); }
.panel-table tbody tr:hover { background: rgba(255, 255, 255, .018); }
.panel-table + .note, .panel-table + .fine { margin-top: var(--s4); }
@media (max-width: 560px) {
  .panel-table { border-radius: var(--r-card); }
  .panel-table caption, .panel-table thead th,
  .panel-table td, .panel-table tbody th { padding-inline: var(--s4); }
  /* Squeezed into 390px a prize row sets "5 plus Mega Ball" over three lines
     and the table stops being scannable. The wrapper already scrolls, so the
     table is given a floor and slides inside it instead. */
  .panel-table .scroll table, .scroll .panel-table table,
  .panel-table table { min-width: 28rem; }
}

/* A section whose body is a table and whose right column would otherwise be
   empty gets the note moved into it. */
.table-with-note { display: grid; grid-template-columns: minmax(0, 1fr) 16rem; gap: var(--s5) var(--s6); align-items: start; }
@media (max-width: 900px) { .table-with-note { grid-template-columns: minmax(0, 1fr); } }

/* ---- The drawing pager -----------------------------------------------------
   Previous drawing, the archive, next drawing. Three links that let a reader
   and a crawler walk the series in either direction without going back to a
   list first. It sits apart from the pagination `.pager` because it is
   navigation between siblings rather than through a set.
   --------------------------------------------------------------------------- */
.draw-pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); flex-wrap: wrap;
  border-top: 1px solid var(--line-2); padding-top: var(--s4); margin-top: var(--s7);
}
.draw-pager a {
  font-size: .92rem; color: var(--muted); text-decoration: none;
  padding: 8px 14px; border-radius: var(--r-btn);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.draw-pager a:hover { background: var(--raised); color: var(--text); }
/* The archive link is the one that is always there, so it holds the middle
   whether or not it has neighbours beside it. */
.draw-pager a:only-child { margin-inline: auto; }

/* ============================================================================
   THE PHONE

   Written after looking at the live site on one. The home page was not merely
   cramped, it was broken: `.hero` kept its two columns all the way down, so at
   390px the check panel was 158px wide, 935px tall, and ran 107px off the right
   edge of the screen. The thing the whole product does was literally not on the
   page. `.grid2` did the same.

   None of it showed up in the audit, for a reason worth writing down: `body`
   carries `overflow-x: hidden`, so `scrollWidth` equals `innerWidth` no matter
   what is hanging off the side, and an overflow check built on that measures
   nothing. The check now walks elements instead. See tools/audit.

   Everything below is layout and size. The ground, the light, the balls, the
   flaps and the grain are untouched: this is the same room, seen through a
   narrower window.
   ========================================================================= */

@media (max-width: 860px) {
  /* ---- One column, which the hero now is at every width -------------------
     This block used to rebuild the hero as a column, because on a wide screen
     it was a two column grid. It is a centred column everywhere now, so all
     that is left to say here is how big things are.
     ---------------------------------------------------------------------- */

  /* Tonight's drawing, stacked. The countdown keeps its full width here
     because four flaps in a row is the one thing on this page that has to be
     read at a glance from across a room. */
  .next-up {
    grid-template-columns: minmax(0, 1fr); gap: var(--s5);
    margin-top: var(--s6); padding-top: var(--s5);
  }

  .grid2 { grid-template-columns: minmax(0, 1fr); margin-top: var(--s6); }
  .machine { margin-top: var(--s5); padding-top: var(--s5); }

  /* The bar rows lose the bar. Four columns in 350px leaves each one too
     narrow to read, and of the four the bar is the one carrying the least:
     the figures beside it say the same thing exactly. */
  .year-bars li { grid-template-columns: 4.6rem 1fr auto; gap: var(--s3); }
  .year-bars .bar-track { display: none; }
  .year-bars .year-figure { text-align: left; }

  /* ---- The hero, shorter ------------------------------------------------
     Every one of these was sized for a screen three times as wide. Together
     they were costing about a screen and a half of scrolling before anything
     could be done.
     ---------------------------------------------------------------------- */
  .stage { padding: var(--s5) 0 var(--s6); }
  .stage h1 { font-size: clamp(1.8rem, 7.4vw, 2.3rem); margin: var(--s4) 0 0; max-width: 100%; }
  .badge { padding: 5px 12px 5px 10px; font-size: .62rem; }
  .jackpot { margin-top: var(--s4); }
  .jackpot .amount .big { font-size: clamp(2.6rem, 13vw, 3.4rem); }

  /* The hero figure is the exception to the line above, which exists to stop
     a jackpot filling a phone screen. This one is meant to: it is the first
     thing on the page and the only number on it that is ours. Sized so the
     numeral and the word still share a line down to 320px. */
  .figure-unclaimed .amount .big { font-size: clamp(3.4rem, 28vw, 7rem); }
  .figure-unclaimed { margin-top: var(--s4); }
  .figure-unclaimed .jackpot-note { margin-top: var(--s5); }
  .hook h1 { margin-top: var(--s5); }
  .hero .panel { margin-top: var(--s4); }

  /* The annuity caveat is the longest paragraph above the fold and it is a
     caveat, not the message. It keeps every word and stops being the size of
     the sentence it qualifies. */
  .jackpot-note { font-size: .82rem; line-height: 1.5; }

  .counter { gap: var(--s2); }
  .counter .flap { min-width: 0; flex: 1; }
  .counter .unit { flex: 1; }

  /* ---- The check panel, full width and reachable ------------------------- */
  .hero .panel.lit { padding: var(--s5); }
  .ball-row { gap: var(--s3); }
  .ball-boxes { flex-wrap: wrap; }
}

@media (max-width: 760px) {
  /* ---- The bar, on one line ---------------------------------------------
     It was stacking the wordmark over the nav and spending 92px before the
     page began. One row, with the links scrolling sideways if they must.

     At 760px rather than 560, because 760 is where the bar starts stacking and
     anything narrower than that is a phone. Fixing it at 560 left a two hundred
     pixel band of devices still paying for two rows.
     ---------------------------------------------------------------------- */
  .masthead .wrap {
    flex-direction: row; align-items: center; height: 52px;
    gap: var(--s3); padding-block: 0;
  }
  .dateline nav {
    margin-left: auto; gap: 0; flex-wrap: nowrap;
    overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .dateline nav::-webkit-scrollbar { display: none; }
  .dateline nav a, .dateline .linkish { padding: 6px 9px; font-size: .8rem; white-space: nowrap; }
  .wordmark { font-size: .95rem; }

  /* ---- The strip scrolls, and shows that it does -------------------------
     It was simply cut off at the right edge with no sign there was more. A
     fade at the edge is the whole affordance: it says the row continues
     without adding a control nobody would press.
     ---------------------------------------------------------------------- */
  .strip .wrap {
    overflow-x: auto; flex-wrap: nowrap; gap: var(--s4);
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent);
    mask-image: linear-gradient(90deg, #000 88%, transparent);
  }
  .strip .wrap::-webkit-scrollbar { display: none; }
  .strip a { white-space: nowrap; }

}

@media (max-width: 560px) {
}

@media (max-width: 380px) {
  /* Two captions on one line, on the narrowest phone still in use. The
     tracking is what costs the room here: at .1em an eighteen character
     caption spends seventeen pixels on the spaces between its letters, and
     two of those were enough to make the captions touch. */
  .hero .panel .range-label { font-size: .55rem; letter-spacing: .04em; }

  /* Elsewhere the boxes are still a fixed size: the dedicated check page has a
     whole screen for them and no reason to squeeze. */
  .ball-input input { width: 46px; height: 46px; }
  .cutoff select { min-width: 0; width: 100%; max-width: none; }
  .cutoff button { width: 100%; }
  .button, button { min-height: 46px; }

  /* The page head's two columns become one, and the figure card that sat
     beside a heading now sits under it at full width. */
  .page-head-in { gap: var(--s5); }
  .figure-card { padding: var(--s4); }
  .draw-pager { gap: var(--s2); }
  .draw-pager a { padding: 8px 10px; font-size: .86rem; }
}


/* ---- Vertical spacing, at phone scale --------------------------------------
   The 4px grid tops out at 76 and 96px, which are the gaps between sections on
   a desktop. On a phone they are a third of a screen of nothing, repeated a
   dozen times, and they were most of the reason the home page ran to nearly
   seven screens. Same rhythm, two steps down.
   --------------------------------------------------------------------------- */
@media (max-width: 760px) {
  section { margin-bottom: var(--s6); }
  .section-head { padding-bottom: var(--s2); margin-bottom: var(--s4); }
  .stage { padding-bottom: var(--s5); }
  .machine { margin-top: var(--s5); padding-top: var(--s5); }
  .grid2 { gap: var(--s3); }
  .panel { padding: var(--s5); }
  .ticker { padding: var(--s3) 0; }
  .fact { margin: var(--s6) 0; padding: var(--s5); }
  footer.site { padding-top: var(--s6); }
  h2 { font-size: clamp(1.5rem, 6vw, 1.9rem); }
  .lede { font-size: 1rem; margin-bottom: var(--s5); }
  .hero .panel .alt { margin-top: var(--s3); font-size: .9rem; }
  .hint { font-size: .85rem; }

  /* Three cards under an introduction, with 56px of nothing between them and
     the sentence they answer to. On a desktop that gap is the pause before the
     answer; on a phone it is a fifteenth of the page. */
  .three { margin-top: var(--s5); }
  .faq .qa { padding: var(--s4) 0; }
}


/* ---- A short window --------------------------------------------------------
   The one thing this hero has to do is put the checker on the first screen,
   and the thing that decides whether it does is the height of the window, not
   the width of it. A 1280 by 800 laptop is wide enough for the full size
   figure and thirty pixels too short for it, which no width breakpoint can
   know.

   So the hero gives back the space it was given, in the order it can afford
   to: the padding above it first, then the gaps around the figure, then the
   figure itself. Nothing is removed and nothing changes size on the way down
   the page, because this is about one screen.
   --------------------------------------------------------------------------- */
@media (min-width:861px) and (max-height:840px){
  .stage{padding-top:var(--s5)}
  .figure-unclaimed{margin-top:var(--s5)}
  .figure-unclaimed .jackpot-note{margin-top:var(--s5)}
  .hero .panel{margin-top:var(--s3)}
  .hook h1{font-size:clamp(1.8rem,3vw,2.2rem)}
  .figure-unclaimed .amount .big{font-size:clamp(4rem,11vw,8rem)}
}

/* Shorter still, and now at any width: a small phone in portrait and a laptop
   window somebody has dragged down to half the screen are the same problem. */
@media (max-height:720px){
  .stage{padding-top:var(--s3)}
  .figure-unclaimed{margin-top:var(--s3)}
  .figure-unclaimed .jackpot-note{margin-top:var(--s3)}
  .hero .panel{margin-top:var(--s3)}
  .hook h1{font-size:clamp(1.5rem,4.4vw,1.9rem)}
  .figure-unclaimed .amount .big{font-size:clamp(2.6rem,19vw,5.4rem)}
  .jackpot-note{font-size:.84rem}
}


/* ---- The wallet ------------------------------------------------------------
   Three states, and they have to look like three states. A ticket read off a
   photo and never saved is doing nothing at all, and the old page said so in a
   heading reading "waiting for you to check", which somebody can read as
   waiting for the drawing. Words were not going to fix that on their own.
   --------------------------------------------------------------------------- */

/* Tonight. Only rendered when something of theirs is in a drawing today, so it
   is never an empty slot where good news goes. */
/* Drawn today.

   It was a flat brown panel with one sentence in it and a third of its width
   empty, which is a lot of page spent on eleven words. The words were also
   counting lines, which is not a thing anybody holds.

   Now it is a row per lottery: what is in the drawing on the left, how long
   until it happens on the right. The clock is the reason to look. The gold
   stays as a hairline and a glow along the top edge rather than as a fill,
   because a filled gold box on a near-black page is the loudest thing on the
   screen and this is good news, not an alarm. */
.tonight {
  position: relative;
  border: 1px solid rgba(255, 194, 58, .22);
  border-top-width: 2px;
  border-radius: var(--r-card);
  background: var(--card);
  padding: var(--s5) var(--s6);
  margin-bottom: var(--s6);
}

.tonight-label { margin: 0 0 var(--s4); display: flex; align-items: center; gap: var(--s2); }
/* On air. The same red dot the site uses for a live second, because a drawing
   happening tonight is the one genuinely live thing on this page. */
.tonight-label .pip {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--live); flex: 0 0 auto;
}
@media (prefers-reduced-motion: no-preference) {
  .tonight-label .pip { animation: tonight-pulse 2.4s ease-in-out infinite; }
}
/* Opacity only. A pulsing ring is a shadow modelling no light, and the house
   rule on shadows is that they come from the elevation scale or from something
   lit. A dot that dims and brightens is the same signal without the fiction. */
@keyframes tonight-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .5; }
}

.tonight-list { list-style: none; margin: 0; padding: 0; }
.tonight-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s5) var(--s6); flex-wrap: wrap;
  padding: var(--s4) 0;
}
.tonight-row + .tonight-row { border-top: 1px solid var(--line); }
.tonight-what { min-width: 0; }
.tonight-what h2 { margin: 0 0 2px; font-size: 1.12rem; letter-spacing: -.01em; }
.tonight-what p { margin: 0; color: var(--muted); font-size: .95rem; }
.tonight-when { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; }
.tonight-at { margin: 0; color: var(--muted); }

/* The counter at wallet size. The home page one is the hero and is allowed to
   be big; this one sits beside a sentence and must not outrank it. */
.counter.tight { gap: var(--s2); margin: 0; }
/* `width`, not `min-width`: the hero counter sets an explicit clamped width, so
   a minimum here would have been overruled by it and the wallet would have
   carried three hero-sized cards beside a sentence. */
.counter.tight .flap { width: 42px; flex: 0 0 auto; padding: 7px var(--s2); }
.counter.tight .n { font-size: 1.1rem; }
.counter.tight p { font-size: .56rem; margin-top: 4px; }
/* Past the drawing time. The script replaces the flaps with a sentence, so
   what is left has to read as text rather than as a counter with its cards
   removed. */
.counter.tight.done {
  display: block; color: var(--gold);
  font-family: var(--mono); font-size: .78rem;
  letter-spacing: .14em; text-transform: uppercase;
}
.tonight .sub { margin: var(--s4) 0 0; max-width: 62ch; }

@media (max-width: 560px) {
  .tonight { padding: var(--s4) var(--s5); }
  .tonight-row { align-items: flex-start; }
  .tonight-when { width: 100%; justify-content: space-between; }
}

/* A draft. Dashed, dimmer, and tagged, because the one thing it must not look
   like is a ticket that is being taken care of. */
.ticket-list li.draft {
  border-style: dashed;
  border-color: rgba(255, 194, 58, .4);
}
.ticket-list li.draft .balls .ball { opacity: .72; }
.tag-draft {
  display: inline-block; vertical-align: middle;
  margin-left: var(--s3); padding: 3px 8px;
  border-radius: var(--r-chip);
  background: rgba(255, 194, 58, .14);
  border: 1px solid rgba(255, 194, 58, .4);
  color: var(--gold); font-size: .6rem;
}

/* History, folded away. It grows for ever and nobody opens a wallet to read
   last year's losing tickets. */
.finished-fold > summary {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s4); cursor: pointer;
  padding: var(--s4) 0; border-bottom: 1px solid var(--line);
  font-family: var(--display); font-size: 1.02rem;
}
.finished-fold > summary::-webkit-details-marker { display: none; }
.finished-fold > summary::before {
  content: "\203A"; color: var(--gold); margin-right: var(--s2);
  transition: transform var(--t-fast) var(--ease); display: inline-block;
}
.finished-fold[open] > summary::before { transform: rotate(90deg); }
.finished-fold > summary:hover { color: var(--gold); }

/* The mark in the bar, on every page, saying a ticket is sitting unsaved. */
.unsaved-pip {
  display: inline-block; min-width: 1.15rem; padding: 1px 5px;
  margin-left: 4px; border-radius: var(--r-pill);
  background: var(--gold); color: var(--ball-ink);
  font-family: var(--mono); font-size: .62rem; font-weight: 600;
  text-align: center; line-height: 1.5;
}


/* ---- The save form, condensed ----------------------------------------------
   Four stacked label-over-control blocks below the numbers, three of which
   have a correct default and are changed by almost nobody. A form that long
   reads as more work than it is, and somebody who abandons it does not save
   the ticket at all, which is the only outcome here that costs money.
   --------------------------------------------------------------------------- */

/* A label beside its control rather than over it. Same rule the checker on the
   home page uses, which is why it is a modifier rather than a second idea. */
/* Label and control on one line, and on two when one line will not do.

   `white-space: nowrap` on the label with no wrapping on the row made the
   whole row as wide as "A name for this ticket" plus a usable input, which is
   376px, and a grid column is as wide as its widest item. So on a 320px phone
   one label was pushing the number boxes off the side of the screen from three
   rows away. Wrapping costs nothing at any width where it fits and is the
   original stacked layout at any width where it does not. */
.pick.inline {
  display: flex; align-items: center; gap: var(--s3);
  flex-wrap: wrap; min-width: 0;
}
.pick.inline > label { flex: 0 0 auto; margin: 0; white-space: nowrap; }
.pick.inline > select,
.pick.inline > input { flex: 1 1 12ch; width: auto; min-width: 0; margin: 0; }

.save-form .lines { margin: var(--s5) 0 0; }
.line-tools {
  display: flex; align-items: center; gap: var(--s4);
  flex-wrap: wrap; margin: var(--s4) 0 0;
}
.line-tools .hint { margin: 0; }
.add-line { padding: 8px var(--s4); }

/* Remove, as a control that is present rather than prominent. It sits on the
   line it removes, and it is not offered at all when there is one line left,
   because removing that one would leave nothing to fill in. */
.line { position: relative; }
.line-remove {
  position: absolute; top: var(--s2); right: 0;
  width: 26px; height: 26px; padding: 0; min-height: 0;
  border: 1px solid var(--line-2); border-radius: 50%;
  background: transparent; color: var(--muted);
  font-size: 1rem; line-height: 1; cursor: pointer;
}
.line-remove:hover { color: var(--live-text); border-color: var(--live); }

/* The two fields almost nobody changes. The summary names advance play in
   words, because that is the one a person with a ten drawing ticket must not
   miss: getting it wrong means we stop checking early and never say so. */
.more-options { margin: var(--s5) 0 0; }
.more-options > summary {
  cursor: pointer; padding: var(--s3) 0;
  font-family: var(--display); font-size: .94rem; color: var(--muted);
}
/* Both markers have to go. `::-webkit-details-marker` is the old one and is
   ignored by current Chromium, which draws the triangle through `::marker`
   instead, so hiding only the first left a triangle sitting next to the
   chevron below. `list-style: none` is what actually removes it. */
.more-options > summary { list-style: none; }
.more-options > summary::marker { content: ""; }
.more-options > summary::-webkit-details-marker { display: none; }
.more-options > summary::before {
  content: "\203A"; color: var(--gold); margin-right: var(--s2);
  display: inline-block; transition: transform var(--t-fast) var(--ease);
}
.more-options[open] > summary::before { transform: rotate(90deg); }
.more-options > summary:hover { color: var(--text); }
.more-options .pick { margin-top: var(--s3); }
.more-options .hint { margin: var(--s2) 0 var(--s4); }

/* Present to a screen reader, absent from the page. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ---------------------------------------------------------------- the walls

   Every free limit on this site now ends in the same block, because every one
   of them used to end in a full stop. "That is your free scans used" is a fact
   and not an answer, and a person who reads it has been told what they cannot
   do and nothing else.

   So the block is quiet on purpose. Gold is the money colour on this site and
   spending it here would make a limit look like an advertisement, which is the
   one reading that would earn the block its bad reputation. It sits on the
   raised surface with a lilac rule down its left edge: present, not shouting.
   The line about what is still free is the one set in white, because that is
   the sentence that matters and the offer underneath it is the smaller half. */
.plus-gate {
  margin: var(--s5) 0;
  padding: var(--s5);
  background: var(--card);
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--lilac);
  border-radius: var(--r-card);
}
.plus-gate > :first-child { margin-top: 0; }
.plus-gate h3 {
  margin: var(--s2) 0 var(--s3);
  font-size: 1.12rem; letter-spacing: -.01em;
}
.plus-gate p { max-width: var(--measure); }
.plus-gate .gate-free { color: var(--text); margin: 0 0 var(--s3); }
.plus-gate .gate-offer { color: var(--muted); margin: 0 0 var(--s4); }
.plus-gate .button { margin: 0; }

/* The name, as a chip rather than as a word in a sentence. It appears on the
   walls, in the wallet and on the pricing page, and a product name that is
   typographically the same as the prose around it gets read as prose. */
.plus-tag {
  display: inline-block;
  padding: 2px 7px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-chip);
  background: var(--raised);
  color: var(--lilac);
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
}

/* Arrived from a wall. The question they came with, answered at the top of the
   pricing page before the page makes any case of its own. */
.came-from {
  padding: var(--s5) var(--s6);
  background: var(--card);
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--lilac);
  border-radius: var(--r-card);
}
.came-from h2 { margin: 0 0 var(--s3); font-size: 1.24rem; }
.came-from p { max-width: var(--measure); margin: 0 0 var(--s3); }
.came-from p:last-child { margin-bottom: 0; color: var(--muted); }
.came-from .gate-free { color: var(--text); }

/* A row on the comparison table for something that does not exist yet. Dimmed
   and labelled, both, because either one alone can be read as a feature. The
   label is not decoration: apps/web/plus.py marks the row and a test fails if
   the page ever renders one of these as though it were included. */
.panel-table tr.not-built th,
.panel-table tr.not-built td { color: var(--muted); }
.soon {
  display: inline-block; margin-left: var(--s2);
  padding: 1px 6px;
  border: 1px solid var(--line-2); border-radius: var(--r-chip);
  color: var(--muted); font-size: .68rem;
  letter-spacing: .08em; text-transform: uppercase;
  vertical-align: middle;
}

/* The waitlist. The only thing on the pricing page anybody can actually do,
   since there is nothing to buy yet, so it is a real section rather than a
   line in a footer. */
.waitlist-form { max-width: var(--measure); }
.waitlist-form label {
  display: block; margin-bottom: var(--s2);
  font-family: var(--display); font-size: .9rem; color: var(--muted);
}
.waitlist-row { display: flex; gap: var(--s3); align-items: stretch; }
.waitlist-row input { flex: 1 1 auto; min-width: 0; }
.waitlist-row .button { flex: 0 0 auto; white-space: nowrap; }
.waitlist .joined { color: var(--win); max-width: var(--measure); }
.waitlist .fine { margin-top: var(--s3); }

@media (max-width: 560px) {
  .waitlist-row { flex-direction: column; }
  .waitlist-row .button { width: 100%; }
}

/* A fieldset does not shrink like anything else on the page.

   Its default `min-width: min-content` is in the UA stylesheet and it ignores
   the grid track it sits in, so on a 320px phone the line fieldset measured 376
   and took the number boxes off the side of the screen with it. The boxes were
   willing to wrap; they were never asked to, because their parent had already
   decided it was 376 wide.

   So the chain from the fieldset down to the boxes is told it may be narrower
   than its content, and the wrapping that was already there starts working. */
.lines { min-width: 0; }
.lines .line,
.lines .ball-row,
.lines .ball-group,
.lines .ball-boxes { min-width: 0; }

/* ---------------------------------------------------------------- the notices

   Two shapes did the same job in two different registers: a flash message in a
   filled panel, and a warning in a 2px red rectangle that looked like a browser
   error dialogue rather than part of this site. Both are now the same object,
   a coloured rule down the left edge of a quiet card, with the colour saying
   which kind it is. Nothing is filled, because a page whose background is
   near-black turns any filled panel into the brightest thing on it, and none of
   these messages are the most important thing on their page. */
.flash { list-style: none; margin: var(--s5) 0 0; padding: 0; }
.flash li {
  position: relative;
  display: flex; align-items: flex-start; gap: var(--s3);
  padding: var(--s3) var(--s4);
  margin-bottom: var(--s2);
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--accent-line);
  border-radius: var(--r-card);
  background: var(--card);
  font-size: .94rem;
  transition: opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.flash li > span { flex: 1 1 auto; min-width: 0; }
.flash-success { border-left-color: var(--win); }
.flash-error { border-left-color: var(--live); }
.flash-info { border-left-color: var(--lilac); }
/* Leaving. Kept short: this is an acknowledgement of a click, not an animation
   anybody should have to watch. */
.flash li.going { opacity: 0; transform: translateY(-4px); }

.flash-close {
  flex: 0 0 auto;
  width: 24px; height: 24px; padding: 0; min-height: 0;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--muted);
  font-size: 1.1rem; line-height: 1; cursor: pointer;
}
.flash-close:hover { color: var(--text); background: var(--raised); }

/* The same object at warning weight. It was a 2px red rectangle. */
.warn {
  padding: var(--s3) var(--s4); margin: 0 0 var(--s6);
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--live);
  border-radius: var(--r-card);
  background: var(--card);
  font-family: var(--display); font-size: .94rem;
  max-width: 62ch;
}
/* Not every warning is a failure. "Win emails are off" is a setting somebody
   chose, and telling them about it in the colour reserved for a bounced
   notification overstates it. */
.warn.quiet { border-left-color: var(--accent-line); color: var(--muted); }

/* The third ending: a drawing that has not happened.

   Not a win and not a loss, so neither of those two treatments. It gets the
   lilac rule that the plan walls use, because like them it is a state with
   something to do about it rather than a verdict. */
.answer.pending {
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--lilac);
  border-radius: var(--r-card);
  background: var(--card);
  padding: var(--s5) var(--s6);
  margin: 0 0 var(--s6);
}
.answer.pending .verdict { margin: 0 0 var(--s2); }
.answer.pending .balls { margin: var(--s4) 0; }
.answer.pending p { max-width: var(--measure); }
.pending-save, .pending-signin { margin: var(--s4) 0 0; }
.answer.pending .fine { margin-top: var(--s3); }

/* ------------------------------------------------------ the drawing machine

   Powerball and Mega Millions are drawn on gravity-pick machines: a clear drum
   with two paddles turning at the bottom and a door that lets one ball out at
   a time. The canvas draws that, holding the numbers that were actually drawn,
   and hands them to the tray beside it.

   The tray is the thing that has to be right. It is rendered by the server and
   is the whole of this block with no script running, so the layout puts it
   first in the source and lets the drum sit alongside. */
.machine-in {
  display: flex; align-items: center; gap: var(--s6);
  flex-wrap: wrap;
}
.machine-said { flex: 1 1 18rem; min-width: 0; }
.drum-stage { flex: 0 0 auto; width: min(320px, 100%); }
.drum { display: block; width: 100%; height: auto; cursor: grab; }
.drum:active { cursor: grabbing; }
.drum-tools {
  display: flex; align-items: center; gap: var(--s3);
  flex-wrap: wrap; margin: var(--s3) 0 0;
}
.drum-tools .hint { margin: 0; }

/* A slot the machine has not reached yet. The number is still in the markup
   and still in the accessibility tree: it is hidden from sight for a couple of
   seconds, not taken away, so nothing here can lose a result. */
.tray .ball.holding { visibility: hidden; }
.tray .ball.landing { animation: ball-lands var(--t-slow) var(--ease) both; }
@keyframes ball-lands {
  from { transform: translateY(-14px) scale(.7); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .tray .ball.holding { visibility: visible; }
  .tray .ball.landing { animation: none; }
}

@media (max-width: 760px) {
  .machine-in { gap: var(--s5); }
  .drum-stage { width: min(280px, 100%); margin: 0 auto; }
  /* The drum is centred on a phone, so the line under it is too. Left aligned
     against a centred circle reads as a mistake. */
  .drum-tools { justify-content: center; text-align: center; }
}

/* Two ways forward, side by side. The signed-out scan page offers an account
   and offers typing, and neither is framed as the failure case. */
.signin-pair {
  display: flex; gap: var(--s3); flex-wrap: wrap;
  margin: var(--s5) 0 var(--s3);
}
.signin-pair .button { margin: 0; }
