/* cocks.io / slot - the command reference page.
   ---------------------------------------------------------------------------
   Two visual languages on one page, deliberately:
     - the FRAME is cocks.io: gold logo, gold wordmark accent, the same `ck-`
       class names the bouncer skin and delta.cocks.io use;
     - the SURFACE is vibevideo: near-black with a purple cast, pink/purple/cyan
       accents, glassmorphism, heavy blur.

   Everything here is vanilla CSS. No build step, no preprocessor, no reset
   library - the stylesheet is served straight off disk at /slot/static/slot.css
   and it has to work when that file is the only thing that loaded.
*/

/* ------------------------------------------------------------------ tokens

   The text tokens are brighter than the vibevideo defaults on purpose.

   Every foreground on this page sits on a translucent surface over an ambient
   gradient with three blurred colour blobs, so the background is never the flat
   `--bg` - it is glass-over-blob, and the worst realistic case measures around
   #57395a, not #0d0d13. The old `--dim: #6a6a78` measured 1.85:1 there: well
   under both the 4.5:1 body threshold and the 3:1 large-text one.

   These values were chosen by running tools/contrast.py over every token, every
   surface and every blob, and taking the worst composite. See the comment block
   above the measuring script for the layer model.

   Measured worst case (jacket over the pink blob):
     text       16.5:1  (was  8.1:1)
     muted       7.0:1  (was  3.5:1)
     dim         5.3:1  (was  1.9:1)
     pink-soft   7.9:1  (was  3.7:1)  - needed a lighter pink, below
     green       9.9:1  (was  5.1:1)
     cyan       10.8:1  (was  5.4:1)
     brand       5.6:1  (was  3.4:1)  - needed a lighter orange, below

   `--brand` is the cocks.io orange and `--pink-soft` is the vibevideo pink;
   both were darkened a step for text use. The pure brand orange is still used
   for fills, borders and the gradient text, where the ratio does not apply
   because it is not text on the page background.
*/

:root {
  /* vibevideo surface */
  --bg: #0d0d13;
  --bg-2: #1b1b26;
  --bg-deep: #1a0512;
  --text: #f2f2f7;
  --muted: #c3c3d0;
  /* 5.3:1 on the worst surface. Still clearly the quietest text on the page -
     the hierarchy is carried by size and weight, not by dropping contrast. */
  --dim: #a2a2b2;

  /* vibevideo accents */
  --pink: #ec4899;
  --pink-soft: #f472b6;
  --purple: #a21caf;
  --cyan: #22d3ee;
  --green: #34d399;
  --amber: #f59e0b;

  /* Text-safe variants of the two brand colours.
     `--pink-soft` and `--brand` are tuned for *fills*: gradient text, borders,
     the wordmark. As foreground on a glass card over a blob they measured
     3.7:1 and 3.4:1. These two are the same hues stepped lighter, and they are
     what every piece of coloured TEXT on the page uses. Splitting them keeps
     the fills vivid without asking 12px text to be legible. */
  --pink-text: #f9a8d4;
  --brand-text: #ff9a5c;

  /* cocks.io frame */
  --brand: #ff6a1a;

  --line: rgba(255, 255, 255, 0.09);
  --line-soft: rgba(255, 255, 255, 0.055);
  /* Borders that carry meaning rather than decoration.

     `--line` and `--line-soft` are hairlines: 1.26:1 and 1.14:1 against the
     darkest card surface. That is the right weight for a separator between two
     rows of the same table, and the wrong weight for the edge of a control -
     WCAG 1.4.11 wants 3:1 for the boundary of an interactive component, because
     that boundary is the only thing telling you where the input ends.

     These are the same hue stepped up until they clear 3:1 against every
     surface a control actually sits on. Measured with tools/contrast.py's
     compositor: 0.34 measured 2.90:1 over the pink blob and was rejected;
     0.52 measures 4.88:1 in the worst case (page background under the pink
     blob) and never drops below 4.8:1 on any surface a control sits on. Used on
     inputs, selects and the command token, never on decorative separators,
     which keep `--line`. */
  --line-control: rgba(255, 255, 255, 0.52);
  --glass: rgba(27, 27, 38, 0.55);
  --glass-strong: rgba(27, 27, 38, 0.78);

  --sans: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
          Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas,
          "Liberation Mono", monospace;

  --r-sm: 10px;
  --r: 16px;
  --r-lg: 22px;
  --wrap: 1120px;

  /* The frosted-edge trick: a 1px light line along the top of every glass
     surface. Cheaper and sharper than a full gradient border. */
  --edge: inset 0 1px 0 rgba(255, 255, 255, 0.09);
  --shadow: 0 18px 48px -24px rgba(0, 0, 0, 0.9);
}

* { box-sizing: border-box; }

html {
  background: var(--bg-deep);
  /* Firefox and older engines without scroll-driven smooth scroll just ignore
     this; the sticky header still works because scroll-margin is plain CSS. */
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
}

body {
  margin: 0;
  min-height: 100%;
  color: var(--text);
  font: 16px/1.65 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  background: var(--bg);
  overflow-x: hidden;
}

h1, h2, h3 {
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0;
}

a { color: var(--pink-text); text-decoration: none; }
a:hover { color: var(--pink); }

code {
  font-family: var(--mono);
  font-size: 0.9em;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-nav {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 200;
  padding: 10px 16px;
  border-radius: var(--r-sm);
  background: var(--pink);
  color: #0d0d13;
  font-weight: 600;
  transition: top 0.15s ease;
}
.skip-nav:focus { top: 12px; color: #0d0d13; }

:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
  border-radius: 4px;
}

#wrap {
  position: relative;
  z-index: 1;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 24px;
}

/* --------------------------------------------------------------- ambience */

/* Three blurred radial blobs on a near-black purple base. They drift with
   `transform` only - animating `filter` or `background-position` on elements
   this large repaints the whole viewport every frame. The blur is a static
   filter, applied once. */
.vv-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(120% 80% at 50% 0%, #150a1e 0%, var(--bg-deep) 55%, #0a0a10 100%);
}

.vv-blob {
  position: absolute;
  display: block;
  border-radius: 50%;
  opacity: 0.5;
  filter: blur(90px);
  will-change: transform;
}

.vv-blob-1 {
  width: 46vmax; height: 46vmax;
  top: -14vmax; left: -10vmax;
  background: radial-gradient(circle at 50% 50%, rgba(236, 72, 153, 0.55), rgba(162, 28, 175, 0) 68%);
  animation: vv-drift-a 34s ease-in-out infinite alternate;
}
.vv-blob-2 {
  width: 40vmax; height: 40vmax;
  top: 24vh; right: -12vmax;
  background: radial-gradient(circle at 50% 50%, rgba(34, 211, 238, 0.34), rgba(34, 211, 238, 0) 66%);
  animation: vv-drift-b 42s ease-in-out infinite alternate;
}
.vv-blob-3 {
  width: 52vmax; height: 52vmax;
  bottom: -22vmax; left: 18vw;
  background: radial-gradient(circle at 50% 50%, rgba(162, 28, 175, 0.5), rgba(244, 114, 182, 0) 70%);
  animation: vv-drift-c 50s ease-in-out infinite alternate;
}

@keyframes vv-drift-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(8vw, 6vh, 0) scale(1.12); }
}
@keyframes vv-drift-b {
  from { transform: translate3d(0, 0, 0) scale(1.06); }
  to   { transform: translate3d(-9vw, 9vh, 0) scale(0.94); }
}
@keyframes vv-drift-c {
  from { transform: translate3d(0, 0, 0) scale(0.96); }
  to   { transform: translate3d(-7vw, -8vh, 0) scale(1.14); }
}

/* Grain. Large smooth gradients band badly on 8-bit displays, and the banding
   is the first thing that makes a page like this look cheap. An SVG turbulence
   tile at low opacity hides it without touching the palette. */
.vv-grain {
  position: absolute;
  inset: -50%;
  opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}

/* ------------------------------------------------------------------ glass */

.glass {
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow), var(--edge);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
}

/* Engines without backdrop-filter (older Firefox, some embedded webviews) get
   an opaque-enough surface instead of a transparent card over the blobs. Same
   look, none of the see-through. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass { background: var(--glass-strong); }
  .vv-blob { opacity: 0.34; }
  html { scroll-behavior: auto; }
}

/* ----------------------------------------------------------------- banner */

.ck-banner {
  position: sticky;
  top: 14px;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin: 20px 0 0;
  padding: 12px 18px;
  border-radius: 999px;
}
.ck-logo {
  display: inline-flex;
  flex: 0 0 auto;
  border-radius: 10px;
  transition: transform 0.18s ease;
}
.ck-logo:hover { transform: translateY(-1px); }
.ck-wm { font-size: 19px; font-weight: 700; white-space: nowrap; }
.ck-wm a { color: var(--text); }
/* The one place gold wins: the wordmark and the brand mark are how people
   recognise the site, so they stay cocks.io orange. */
.ck-wm em { font-style: normal; color: var(--brand-text); }
.ck-tagline {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  white-space: nowrap;
}

.ck-topnav {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  font-size: 14px;
  flex-wrap: wrap;
}
.ck-topnav a { color: var(--muted); }
.ck-topnav a:hover { color: var(--text); }
.ck-topnav a.on {
  color: #0d0d13;
  background: linear-gradient(120deg, var(--pink-soft), var(--pink));
  padding: 3px 11px;
  border-radius: 999px;
  font-weight: 600;
}
.ck-topnav-sep { color: var(--dim); }

.ck-langs {
  display: flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
}
.ck-langs a { color: var(--dim); padding: 3px 9px; border-radius: 999px; }
.ck-langs a:hover { color: var(--text); }
.ck-langs a.on {
  color: #0d0d13;
  background: var(--brand);
  font-weight: 600;
}

/* ------------------------------------------------------------------- hero */

.hero { padding: 64px 0 40px; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 18px;
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.eyebrow-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 4px rgba(52, 211, 153, 0.16);
  animation: vv-pulse 2.6s ease-in-out infinite;
}
@keyframes vv-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

.hero-h1 {
  font-size: clamp(38px, 8vw, 82px);
  font-weight: 700;
  letter-spacing: -0.045em;
  margin: 0 0 16px;
}
.hero-h1 em {
  font-style: normal;
  background: linear-gradient(100deg, var(--brand), var(--pink));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero-h1 .slash {
  color: var(--dim);
  font-weight: 400;
  margin: 0 0.06em;
}

.hero-tagline {
  font-size: clamp(17px, 2.4vw, 22px);
  color: var(--text);
  margin: 0 0 14px;
  max-width: 46ch;
}
.hero-intro {
  color: var(--muted);
  max-width: 62ch;
  margin: 0;
  font-size: 16.5px;
}
.hero-cta { display: flex; flex-wrap: wrap; gap: 12px; margin: 26px 0 0; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 20px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  font-weight: 500;
  font-size: 14.5px;
  transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.btn:hover {
  transform: translateY(-1px);
  border-color: rgba(244, 114, 182, 0.5);
  background: rgba(244, 114, 182, 0.1);
  color: var(--text);
}
.btn-primary {
  border-color: transparent;
  background: linear-gradient(120deg, var(--pink), var(--purple));
  color: #fff;
}
.btn-primary:hover {
  background: linear-gradient(120deg, var(--pink-soft), var(--pink));
  color: #fff;
}

/* --------------------------------------------------------------- sections */

.card {
  padding: 26px 28px;
  margin: 0 0 22px;
}

.sec-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 18px;
}
.sec-head.big {
  font-size: clamp(20px, 3.4vw, 30px);
  letter-spacing: -0.02em;
  text-transform: none;
  color: var(--text);
  margin: 0 0 8px;
}
/* The cocks.io ordinal style - 01 / 02 / 03 - but in the subpage's accent. */
.sec-ord {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--pink);
  opacity: 0.85;
}
.sec-head.big .sec-ord { font-size: 14px; }

.note {
  color: var(--muted);
  font-size: 14.5px;
  margin: 16px 0 0;
  max-width: 72ch;
}
.note code, .lede code {
  padding: 1px 6px;
  border-radius: 6px;
  background: rgba(236, 72, 153, 0.13);
  border: 1px solid rgba(236, 72, 153, 0.24);
  color: var(--pink-text);
}
.lede {
  color: var(--muted);
  max-width: 66ch;
  margin: 0 0 24px;
}
.lede code {
  font-size: 0.86em;
}

.tag {
  display: inline-block;
  padding: 1px 9px;
  border-radius: 999px;
  border: 1px solid rgba(52, 211, 153, 0.35);
  background: rgba(52, 211, 153, 0.1);
  color: var(--green);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.dash { color: var(--dim); }
.dot-sep { color: var(--dim); margin: 0 8px; }

/* ---------------------------------------------------------- connect / spec */

.spec {
  display: grid;
  grid-template-columns: minmax(120px, 180px) 1fr;
  gap: 10px 20px;
  margin: 0;
  font-size: 15px;
}
.spec dt {
  color: var(--dim);
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding-top: 2px;
}
.spec dd { margin: 0; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.spec code {
  padding: 3px 10px;
  border-radius: 8px;
  background: rgba(34, 211, 238, 0.09);
  border: 1px solid rgba(34, 211, 238, 0.22);
  color: var(--cyan);
  font-size: 13.5px;
}

/* -------------------------------------------------------------- pot list */

/* A list, not a table. Four columns of pot data in a 320px viewport is a
   horizontal scrollbar; this stacks the same information as two rows per pot
   and drops to a single column without any of it disappearing. */
.pot-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.pot-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "name now" "side side";
  align-items: baseline;
  gap: 2px 12px;
  padding: 10px 14px;
  border-radius: var(--r);
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--line-soft);
}
.pot-name {
  grid-area: name;
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.pot-now {
  grid-area: now;
  color: var(--pink-text);
  font-family: var(--mono);
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.pot-side {
  grid-area: side;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--dim);
}
.pot-prev, .pot-winner { overflow-wrap: anywhere; }
.pot-k {
  color: var(--dim);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-right: 4px;
}

/* ------------------------------------------------------------------ tables */

.table-scroll { overflow-x: auto; margin: 0 -6px; padding: 0 6px; }

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14.5px;
}

thead th {
  text-align: left;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  padding: 0 14px 10px 0;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
tbody tr { transition: background 0.15s ease; }
tbody tr:hover { background: rgba(255, 255, 255, 0.032); }
tbody td, tbody th {
  padding: 10px 14px 10px 0;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
  text-align: left;
  font-weight: 400;
}
tbody tr:last-child td, tbody tr:last-child th { border-bottom: 0; }
.num { text-align: right; padding-right: 20px; font-variant-numeric: tabular-nums; }
thead th.num { text-align: right; }

.pot-name {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
}
.pot-now {
  color: var(--pink-text);
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 600;
}
.pot-prev { color: var(--muted); font-family: var(--mono); font-size: 13px; }
.pot-winner { color: var(--muted); font-family: var(--mono); font-size: 13px; }

/* -------------------------------------------------------------- stat grid

   Why the tiles are not all the same width: a Swiss-format sum like
   `1'234'567$` is ten monospace glyphs. At the 25px this grid used to use, that
   is ~150px of text in a 132px tile - it overflowed its own box, and with a
   German label ("Zurückgezahlt") underneath it had nowhere to go. The money
   cells now span two tracks, exactly as the RTP cell already did for its
   sub-line, and the number is sized against its own tile with a container
   query rather than against the viewport.

   Measured in tools/measure_stat.py: a 132px tile holds 8 glyphs at 25px, so
   the old clamp overflowed from the fifth figure upwards. A 264px money tile at
   the same 25px holds 17 glyphs - `1'234'567'890$` and then some.

   Nothing here truncates. There is no `text-overflow: ellipsis` on a stat
   cell: a number that cannot be shown in full means the layout is wrong, and
   the `overflow-wrap` below is the last-resort wrap that keeps it inside the
   box instead of letting it escape. */

.stat-grid {
  display: grid;
  /* 140px, not 132: the smallest tile now holds a count and a label, and the
     money tiles are two tracks wide. */
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
}
.stat {
  padding: 14px 15px;
  min-width: 0;
  /* The number sizes against its own tile, not the viewport: eight tiles
     across a 1120px page are each ~160px, and one tile spanning two is ~330px.
     Sizing from the viewport put the same 25px into a 160px box and a 330px
     box alike, which is exactly how the value overflowed. */
  container-type: inline-size;
  border-radius: var(--r);
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--line-soft);
  transition: border-color 0.18s ease, transform 0.18s ease;
}
.stat:hover {
  border-color: rgba(236, 72, 153, 0.35);
  transform: translateY(-2px);
}
/* The four money sums. Two tracks each, so a six-figure total has room to be
   readable rather than clipped. */
.stat-money { grid-column: span 2; }
.stat-n {
  display: block;
  font-family: var(--mono);
  /* 11cqi: a 140px tile gets 15px, a 330px money tile gets 25px (capped).
     Ten glyphs at 15px is 90px inside a 110px content box - it fits, and it is
     still the largest text in the tile. */
  font-size: clamp(14px, 11cqi, 26px);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  line-height: 1.1;
  /* The safety net, not the strategy: at an implausible magnitude the value
     wraps inside the tile instead of escaping it. Nothing is ellipsised. */
  overflow-wrap: anywhere;
  hyphens: none;
}
/* The count tiles (players, rounds, seen recently) are one track wide and hold
   a short integer, so they can afford a larger size than 11cqi - and they are
   the numbers a reader scans for first. Six digits at 16cqi of a 129px tile is
   20px type needing ~74px, which fits with room to spare. */
.stat:not(.stat-money):not(.stat-wide) .stat-n {
  font-size: clamp(14px, 16cqi, 30px);
}
.stat-l {
  display: block;
  margin-top: 5px;
  font-size: 10.5px;
  letter-spacing: 0.13em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--dim);
  /* German labels are longer than English ones ("Zurückgezahlt",
     "Gespielte Runden"). They wrap to a second line, which is fine; what is
     not fine is them pushing the card wider than the viewport. */
  overflow-wrap: anywhere;
}
.stat-formula { text-transform: none; letter-spacing: 0.02em; }
/* The RTP cell carries a second, qualifying figure. It spans the row so the
   label next to a percentage is never read as belonging to the wrong number. */
.stat-wide { grid-column: span 2; }
.stat-sub {
  display: block;
  margin-top: 3px;
  font-family: var(--mono);
  font-size: 10px;
  color: var(--dim);
}
.stat-sub[hidden] { display: none; }

/* ------------------------------------------------------------- jackpot hero */

.hero-jackpot {
  padding: 26px 26px 22px;
  margin: 0 0 18px;
  /* The headline number sizes against this card, not the viewport. */
  container-type: inline-size;
  /* A gradient wash under the glass, so the hero reads as its own object.

     These two alphas are lower than the first pass used (0.22 / 0.14). Stacked
     over the glass *and* over an ambient blob, the old values composited to
     #57395a - a mid purple - and every accent colour fell under 4.5:1 on it.
     At 0.13 / 0.08 the worst composite stays dark enough to read on while the
     wash is still clearly visible. Measured in tools/contrast.py. */
  background:
    radial-gradient(120% 130% at 8% -10%, rgba(236, 72, 153, 0.13), rgba(27, 27, 38, 0.62) 58%),
    radial-gradient(90% 120% at 100% 0%, rgba(34, 211, 238, 0.08), rgba(27, 27, 38, 0) 62%),
    var(--glass);
}

.jack-kicker {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--green);
}
.live-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 12px rgba(52, 211, 153, 0.9);
  animation: vv-pulse 2.2s ease-in-out infinite;
}
.jack-kicker-sub {
  color: var(--dim);
  letter-spacing: 0.14em;
  padding-left: 10px;
  border-left: 1px solid var(--line);
}

.jack-num {
  margin: 12px 0 8px;
  font-family: var(--mono);
  /* clamp() alone overflows on a phone: 165'000$ at 42px is wider than 335px.
     A container query keeps it inside its own card on any width. */
  font-size: clamp(38px, 22cqw, 96px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(96deg, var(--pink-soft) 0%, var(--pink) 45%, var(--cyan) 130%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  overflow-wrap: anywhere;
}
.jack-num.stale { opacity: 0.55; }

.jack-meta {
  margin: 0 0 26px;
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--muted);
}
.jack-pot-name { color: var(--text); }
.jack-status { color: var(--amber); margin-left: 8px; }
.jack-body {
  margin: 0;
  max-width: 72ch;
  color: var(--muted);
  font-size: 15px;
}
.hero-jackpot .sec-head {
  padding-top: 24px;
  border-top: 1px solid var(--line-soft);
}

/* -------------------------------------------------- leaderboard / player */

/* The two live controls share one control style. Both are native <select> and
   <input> so they get a real mobile picker and real keyboard behaviour for
   free - no custom widget to reimplement that. */
.lb-controls, .pc-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin: 0 0 16px;
}
.lb-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.lb-field label {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
}
.lb-controls .lb-field, .pc-controls .lb-field { flex: 1 1 160px; }
.lb-controls select, .pc-controls input {
  /* 44px min: a tap target you can hit with a thumb without aiming. */
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--line-control);
  background: rgba(10, 10, 16, 0.6);
  color: var(--text);
  font-family: var(--mono);
  font-size: 13px;
  /* iOS zooms the page on focus for inputs under 16px. */
}
.lb-controls select:focus, .pc-controls input:focus {
  border-color: rgba(34, 211, 238, 0.6);
}
.pc-controls input::placeholder { color: var(--dim); }
.btn-sm { min-height: 44px; padding: 8px 18px; font-size: 13.5px; }

/* A table in a 320px viewport cannot hold five columns of numbers without
   forcing the whole document sideways. Measured: at 320px the board was 390px
   wide - 85px of horizontal scroll on every page that has one.

   The columns are `min-width: 0` so they are allowed to shrink, and the
   smallest two collapse entirely below 480px. Rank and best win are the ones
   that go: they are the two a phone reader is least likely to compare across
   rows. `overflow-x: auto` stays on the wrapper as the last-resort escape -
   it is what makes the table scroll *inside* its card instead of dragging the
   document with it. */
.lb-table {
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
  table-layout: fixed;
  width: 100%;
}
.lb-table th, .lb-table td {
  min-width: 0;
  /* No ellipsis on a number. The old rule clipped every cell, so a six-figure
     balance could render as `124'7…` in a narrow column - a truncated money
     value is a wrong money value. Numbers and nicks wrap inside the cell and
     the wrapper scrolls; nothing is hidden. */
  overflow-wrap: anywhere;
}
/* The one cell where clipping is acceptable is the nick, and even there it
   wraps instead - an ellipsis on a nick hides which player a row is. */
.lb-nick { overflow-wrap: anywhere; }
/* Five numeric columns do not fit a 360px phone. The wrapper scrolls sideways
   rather than letting the table push the whole document wide - which would
   break the sticky banner and every other section's alignment. */
.lb-wrap { overflow-x: auto; }
.lb-wrap .lb-table { min-width: 420px; }
.lb-rank { color: var(--dim); font-family: var(--mono); font-size: 12px; }
/* The nick is a button so it can load that player's card. It has to look like
   a link and behave like a control: hover, focus, and a real hit area. */
.lb-pick {
  appearance: none;
  background: none;
  border: 0;
  padding: 6px 8px;
  margin: -6px -8px;
  min-height: 32px;
  color: var(--pink-text);
  font: inherit;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  border-radius: 6px;
  overflow-wrap: anywhere;
  transition: background 0.15s ease, color 0.15s ease;
}
.lb-pick:hover { background: rgba(236, 72, 153, 0.14); color: var(--text); }
.lb-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin: 12px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--dim);
}
/* Five columns at 320px is 64px each, which is not enough for "124'750$".
   The wrapper scrolls internally; the card itself never grows. */
.lb-wrap { max-width: 100%; overflow-x: auto; }
.lb-flag::before {
  content: "";
  display: inline-block;
  width: 6px; height: 6px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--green);
  vertical-align: 1px;
}

.pc-top { margin: 0 0 4px; }
.pc-nick {
  margin: 0 0 12px;
  font-size: 21px;
  font-weight: 700;
  color: var(--text);
  overflow-wrap: anywhere;
}
.pc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: 8px;
  margin: 0;
}
.pc-stat {
  padding: 9px 12px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--line-soft);
  min-width: 0;
}
.pc-v {
  display: block;
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 600;
  color: var(--pink-text);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.pc-k {
  display: block;
  margin-top: 2px;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.pc-sub {
  margin: 18px 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.pc-table { font-size: 13px; }

/* ------------------------------------------------------- players / cards

   `/slot/players` and `/slot/players/<nick>`. Same palette, same card and
   table primitives as the rest of the page - no new visual language, just the
   existing pieces pointed at two new routes. */

.hero-slim { padding: 44px 0 26px; }
.hero-h1-slim { font-size: clamp(30px, 5.4vw, 54px); }

/* The status line sits above the table, out of the way of it, and carries the
   same states as the one on /slot. */
.players-live { margin: 0 0 18px; }

.players-controls { margin: 0 0 18px; }
.players-table { min-width: 640px; }
.players-table td, .players-table th { font-size: 13.5px; }

/* A <dl> tile shows the value first and the label under it, matching the
   `.pc-stat` tiles the inline card on /slot renders. `order` rather than
   reversed markup, because dt-before-dd is the readable source order. */
.pc-grid > .pc-stat { display: flex; flex-direction: column; }
.pc-grid dt.pc-k { order: 2; margin-top: 3px; }
.pc-grid dd.pc-v { order: 1; margin: 0; }

.pager {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 14px 0 0;
}

.deaths-table { min-width: 520px; }
.deaths-grid { margin: 0 0 14px; }
.death-line { color: var(--muted); font-size: 13px; max-width: 46ch; }
.deaths-pending {
  padding: 14px 16px;
  border: 1px dashed var(--line);
  border-radius: var(--r);
}
/* The stale state the poller applies when the API stops answering: the numbers
   stay exactly as they were, they are just marked as no longer refreshing. */
.stale { opacity: 0.55; }

/* ---------------------------------------------------------- live status */

/* The countdown. Deliberately quiet: it is information about the mechanism,
   not the headline. The state word (updated / retrying / offline) is the part
   that changes colour, because that is the part a reader has to notice. */
.live-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0 0 20px;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid var(--line-soft);
  background: rgba(10, 10, 16, 0.4);
  font-family: var(--mono);
  font-size: 11px;
}
.live-state { color: var(--green); font-weight: 600; letter-spacing: 0.06em; }
.live-count { color: var(--dim); margin-left: auto; }
.live-bar[data-state="retry"] .live-state { color: var(--amber); }
.live-bar[data-state="stale"] .live-state,
.live-bar[data-state="offline"] .live-state { color: var(--amber); }

/* -------------------------------------------------------- command section */

.commands { margin: 40px 0 18px; }

.jump {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 18px;
  margin: 0 0 22px;
  border-radius: var(--r);
}
.jump-nav { display: flex; flex-wrap: wrap; gap: 8px; }
.jump-nav a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 5px 13px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.03);
  color: var(--muted);
  font-size: 13px;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.jump-nav a:hover {
  color: var(--text);
  border-color: rgba(244, 114, 182, 0.5);
  background: rgba(244, 114, 182, 0.1);
}
.jump-ord {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--pink);
  opacity: 0.8;
}

.jump-filter { flex: 1 1 220px; max-width: 320px; }
.jump-filter input {
  width: 100%;
  min-height: 44px;
  padding: 9px 15px;
  border-radius: 999px;
  border: 1px solid var(--line-control);
  background: rgba(10, 10, 16, 0.55);
  color: var(--text);
  font-family: var(--mono);
  font-size: 16px;
  /* iOS Safari zooms the viewport on focus for anything under 16px, which
     leaves the reader scrolled sideways in a zoomed page. */
}
.jump-filter input::placeholder { color: var(--dim); }
.jump-filter input:focus { border-color: rgba(34, 211, 238, 0.55); }

.filter-empty {
  margin: 18px 0 0;
  padding: 18px;
  border-radius: var(--r);
  border: 1px dashed var(--line);
  color: var(--muted);
  text-align: center;
}

/* ------------------------------------------------------------ command rows */

/* The reason this section changed shape: 76 commands as eight stacked tables
   made a page roughly 4000px tall, and the reference - the actual content -
   was below the fold on a laptop.

   CSS multi-column instead of grid on purpose. A grid gives every cell the same
   row height, so one long group next to one short group leaves a visible hole.
   Multi-column fills top-to-bottom in balanced columns and has no gaps. The
   groups are `break-inside: avoid` so a command never gets split across a
   column boundary.

   Two columns at desktop, one below 640px. */
.cmd-columns {
  columns: 2;
  column-gap: 18px;
}

.group {
  padding: 16px 18px;
  margin: 0 0 18px;
  border-radius: var(--r-lg);
  break-inside: avoid;
  /* Without this a `hidden` group still occupies a column slot in some engines. */
  display: inline-block;
  width: 100%;
}
.group[hidden] { display: none; }

.group-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 16px;
  margin: 0 0 3px;
}
.group-ord {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  color: var(--cyan);
}
.blurb { color: var(--muted); font-size: 13px; margin: 0 0 12px; }

.cmd-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.cmd-row {
  padding: 7px 0;
  border-top: 1px solid var(--line-soft);
}
.cmd-row:first-child { border-top: 0; }
.cmd-row[hidden] { display: none; }
.cmd-cell {
  margin: 0;
  /* `nowrap` on the token and its arguments only. The row itself may wrap, and
     the description below it always does. */
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.cmd-args {
  color: var(--dim);
  font-family: var(--mono);
  font-size: 11.5px;
  white-space: nowrap;
  overflow-wrap: anywhere;
}
.cmd-row:hover .cmd-args { color: var(--muted); }
.alias {
  margin: 3px 0 0;
  display: flex;
  align-items: baseline;
  gap: 5px;
  flex-wrap: wrap;
}
.alias-l {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.what {
  margin: 2px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--muted);
}

/* The command token is the centrepiece of the page: it has to read as a real
   terminal token, not as bold text. Tinted fill, hairline border, pink
   glow on hover, and a press state.

   The token is a <button> (so it is keyboard reachable and Enter/Space copy it),
   which means the UA's button defaults have to be taken back off: the font is
   inherited rather than the UA's system button font, the background and border
   are the token's own, and `cursor: pointer` is explicit rather than inherited.
   `text-align: left` stops the UA centring the label inside the box. */
.cmd-copy {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  /* Default text cursor, NOT pointer. The copy affordance only appears once
     JavaScript has proven it can honour it - a pointer cursor on a button that
     does nothing (JS off, or the clipboard blocked with no selection possible)
     is a promise the element cannot keep. `.js` is set by the page script on
     <html>, so `cursor: pointer`, the hover lift and the tick apply only when
     the click handler is actually bound. Without JS the token stays plainly
     selectable text and the <noscript> note explains that. */
  cursor: text;
  /* Stops iOS Safari from showing a grey tap highlight over the token. */
  -webkit-tap-highlight-color: transparent;
}
.js .cmd-copy { cursor: pointer; }
.cmd {
  display: inline-block;
  padding: 3px 10px 3px 9px;
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(236, 72, 153, 0.2), rgba(162, 28, 175, 0.16));
  /* The token's edge is decorative, not the control's boundary, and it is
     deliberately below 3:1: measured with tools/contrast.py's compositor this
     reads 2.02:1 worst case. WCAG 1.4.11's 3:1 applies to the boundary that
     tells you where an interactive component ends; here the affordance is
     carried by the filled tint (white on it measures 11.01:1), the hover and
     pressed states, and the 8.0:1 cyan focus ring - not by the hairline. A
     3:1 edge was tried at a higher alpha and made the reference look like a
     table of outlined chips, which is a worse read than the token has now. */
  border: 1px solid rgba(236, 72, 153, 0.55);
  color: #fff;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
/* The hover/press feedback now hangs off the button, so it also fires when the
   pointer is over the tick that sits next to the token. Gated on `.js` for the
   same reason as the cursor. */
.js .cmd-copy:hover .cmd {
  transform: translateY(-1px);
  border-color: rgba(244, 114, 182, 0.75);
  box-shadow: 0 6px 18px -8px rgba(236, 72, 153, 0.9);
}
.js .cmd-copy:active .cmd { transform: translateY(0); }

/* Focus. The global :focus-visible rule in the shell paints a cyan ring on
   `button`, so the token gets one for free - but the token's own transform on
   hover would otherwise shift the ring's offset while focused, so the focused
   state drops the hover lift. */
.cmd-copy:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 10px; }
.cmd-copy:focus-visible .cmd { transform: none; }

/* The confirmation tick. Hidden by default, drawn by `.is-copied`; the box is
   reserved (width, not display) so the token does not jump sideways when it
   appears. Colour is never the only signal - the live region speaks the
   command, and the tick has a shape. */
.cmd-copy-tick {
  display: inline-block;
  width: 0;
  overflow: hidden;
  color: var(--green);
  font-size: 12px;
  line-height: 1;
  transition: width 0.14s ease;
  flex: none;
}
.cmd-copy.is-copied .cmd-copy-tick { width: 1em; }
.cmd-copy.is-copied .cmd-copy-tick::before { content: "\2713"; }
.cmd-copy.is-copied .cmd { border-color: rgba(52, 211, 153, 0.85); }

/* Blocked: the clipboard write failed and the command is selected instead.
   Deliberately amber, and paired with the tick glyph's absence plus the live
   region text - the state is legible without colour. */
.cmd-copy.is-blocked .cmd { border-color: rgba(245, 158, 11, 0.9); }

.cmd-noscript {
  margin: 16px 0 0;
  padding: 12px 16px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.03);
  color: var(--muted);
  font-size: 13px;
}

/* Arguments travel with the command: `.slots` and `<bet>` read as one
   invocable line, the way you would type them in the channel. The `.cmd-args`
   styling lives with the row rules above. */

.alias-tok {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line-soft);
  color: var(--muted);
  font-size: 11px;
}
.alias-tok:hover { color: var(--cyan); border-color: rgba(34, 211, 238, 0.4); }

.what code {
  padding: 0 5px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line-soft);
  color: var(--pink-text);
  font-size: 11.5px;
}

.badge {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid rgba(245, 158, 11, 0.45);
  background: rgba(245, 158, 11, 0.12);
  color: var(--amber);
  font-family: var(--mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  vertical-align: 2px;
}

/* ------------------------------------------------------------------ footer */

#foot {
  margin: 56px 0 0;
  padding: 26px 28px 30px;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  color: var(--muted);
  font-size: 13.5px;
}
.ck-footnav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
}
.ck-footnav a { color: var(--muted); }
.ck-footnav a:hover { color: var(--pink-text); }
.ck-footnav-sep { color: var(--dim); }
/* The separator is emitted after every link; drop the one that trails the last. */
.ck-footnav-sep:last-child { display: none; }

.ck-fine { margin: 0 0 14px; color: var(--dim); font-size: 12.5px; }
.ck-ninja { color: var(--cyan); font-family: var(--mono); font-size: 0.95em; }

.ck-donate-row { margin: 0; }
.ck-donate {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 13px 7px 10px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1;
}
.ck-donate-x {
  color: var(--brand-text);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
}
.ck-donate-addr {
  appearance: none;
  background: none;
  border: 0;
  /* 44px tall: the whole XMR chip is the button, and it sits in a footer a
     phone user reaches with a thumb. */
  min-height: 44px;
  padding: 0 2px;
  color: var(--text);
  font: inherit;
  cursor: pointer;
  transition: color 0.15s ease;
}
.ck-donate-addr:hover { color: var(--pink-text); }

/* ------------------------------------------------------------- xmr dialog */

.ck-xmr-modal {
  position: fixed;
  inset: 0;
  z-index: 300;
  box-sizing: border-box;
  width: min(420px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100vh - 48px);
  max-height: calc(100dvh - 48px);
  margin: auto;
  padding: 24px 24px 20px;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: rgba(20, 18, 30, 0.94);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  backdrop-filter: blur(26px) saturate(150%);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 20px;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.95), var(--edge);
  text-align: left;
}
.ck-xmr-modal:not([open]) { display: none; }
.ck-xmr-modal::backdrop {
  background: rgba(8, 6, 14, 0.72);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ck-xmr-modal { background: #14121e; }
}

.ck-xmr-x {
  position: absolute;
  top: 12px; right: 12px;
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  padding: 0;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text);
  cursor: pointer;
}
.ck-xmr-x:hover { background: rgba(255, 255, 255, 0.1); }
.ck-xmr-x svg { display: block; width: 13px; height: 13px; }

.ck-xmr-kicker {
  margin: 0 56px 4px 0;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--brand-text);
}
.ck-xmr-title {
  margin: 0 56px 12px 0;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.25;
}
.ck-xmr-body {
  margin: 0 0 16px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--muted);
}
.ck-xmr-body strong { color: var(--text); font-weight: 600; }
.ck-xmr-addr {
  margin: 0;
  padding: 11px 12px;
  border-radius: 10px;
  background: rgba(10, 10, 16, 0.6);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--text);
  word-break: break-all;
  user-select: all;
  -webkit-user-select: all;
}
.ck-xmr-copy {
  display: block;
  width: 100%;
  min-height: 44px;
  margin: 10px 0 0;
  padding: 0 14px;
  border-radius: 10px;
  border: 1px solid rgba(236, 72, 153, 0.4);
  background: linear-gradient(120deg, rgba(236, 72, 153, 0.9), rgba(162, 28, 175, 0.9));
  color: #fff;
  font-family: var(--sans);
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: filter 0.15s ease;
}
.ck-xmr-copy:hover { filter: brightness(1.12); }
.ck-xmr-copy.ck-xmr-done {
  background: rgba(52, 211, 153, 0.14);
  border-color: rgba(52, 211, 153, 0.45);
  color: var(--green);
}
.ck-xmr-state {
  min-height: 16px;
  margin: 8px 0 0;
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 1.4;
  color: var(--dim);
}
.ck-xmr-state.ck-xmr-done { color: var(--green); }
.ck-xmr-sig {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--dim);
  text-align: center;
}

/* --------------------------------------------------------------- narrow */

@media (max-width: 900px) {
  #wrap { padding: 0 16px; }
  /* The banner wraps to three rows here, so the sticky offset has to grow with
     it or every #anchor jump lands underneath it. */
  .ck-banner { border-radius: 20px; top: 10px; gap: 10px; padding: 12px 14px; }
  .ck-tagline { display: none; }
  .ck-topnav { margin-left: 0; width: 100%; order: 3; }
  .ck-langs { margin-left: auto; }
  .hero { padding: 40px 0 28px; }
  .card, .group, .hero-jackpot { padding: 20px 16px; }
  .spec { grid-template-columns: 1fr; gap: 2px 0; }
  .spec dd { margin: 0 0 12px; }
  .jump { border-radius: var(--r); }
  .jump-filter { max-width: none; }
  #foot { padding: 22px 16px 26px; }
  /* The alias column is the least useful one on a phone; the command name and
     the description are not. */
  .alias-col { display: none; }
}

@media (max-width: 900px) {
  html { scroll-padding-top: 160px; }
}

/* ------------------------------------------------------------ narrow table */

/* Below this width the command columns collapse to one. The rows are already
   stacked markup (`.cmd-list` / `.cmd-row`), so this is mostly about stopping
   the two-column layout from squeezing 76 commands into a 340px column. */
/* 44px tap targets. Every one of these was measured under 44px tall at 320px
   in a real browser - the nav links came out at 22-29px, the lang switch at
   23px and the leaderboard nick buttons at 34px. The nav grows vertically
   instead, because a 44px-wide pill row of five links is 220px of a 305px
   screen and would wrap mid-word. */
@media (max-width: 640px) {
  .ck-topnav a { min-height: 44px; display: inline-flex; align-items: center; }
  .ck-topnav a.on { padding: 3px 13px; }
  .ck-langs a { min-height: 44px; display: inline-flex; align-items: center; }
  .ck-logo { padding: 7px; margin: -7px; }
  /* The wordmark link beside it. Same fix: it is a 19px line of text inside a
     pill-shaped header, so its hit area is 25px tall unless it is padded out. */
  .ck-wm a { display: inline-flex; align-items: center; min-height: 44px; }
  .ck-footnav a { min-height: 44px; display: inline-flex; align-items: center; }
  .ck-footnav-sep { align-self: center; }
  .lb-pick { min-height: 44px; }

  .cmd-columns { columns: 1; }
  .cmd-row { padding: 8px 0; }
  .cmd { font-size: 13.5px; }
  .what { font-size: 13px; }
  .alias-tok { font-size: 11.5px; }

  .stat-grid { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 10px; }
  .stat { padding: 12px 13px; }
  /* A 2-column span on a 1- or 2-column grid leaves a gap; the money tiles
     drop back to one track and the container query keeps the number inside. */
  .stat-wide { grid-column: span 1; }
  .stat-money { grid-column: span 1; }

  /* The controls go full width so the 44px tap targets span the card. */
  .lb-controls .lb-field, .pc-controls .lb-field { flex: 1 1 100%; }
  .lb-controls select, .pc-controls input { width: 100%; }
  .pc-controls .btn { width: 100%; justify-content: center; }
  .pc-grid { grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); }
  .live-bar { border-radius: 12px; }
  .live-count { margin-left: 0; }
}

/* The jackpot hero is the first thing on screen, so it has to stay legible
   without eating a whole phone screen. `22cqw` is measured against the card,
   not the viewport - see the .jack-num comment. */
@supports not (container-type: inline-size) {
  .jack-num { font-size: clamp(38px, 11vw, 96px); }
}

/* Nothing may exceed the viewport width. `body` already clips overflow-x, but
   that hides the evidence of a wide element instead of fixing it, so the
   genuinely-nowrap things get `min-width: 0` and wrapping instead. */
@media (max-width: 400px) {
  #wrap { padding: 0 10px; }
  .card, .group, .hero-jackpot { padding: 16px 13px; }
  .cmd-cell { min-width: 0; }
  /* The button wraps the token, so it needs the same escape hatch: a flex item
     defaults to min-width:auto, which refuses to shrink below its content and
     would push the row past the viewport even though the token inside it is
     already allowed to wrap. */
  .cmd-copy { min-width: 0; max-width: 100%; }
  .cmd { max-width: 100%; overflow-wrap: anywhere; white-space: normal; }
  .pc-nick { font-size: 18px; }
  .hero-h1 { font-size: clamp(30px, 10vw, 44px); }
  .pc-v { font-size: 13.5px; }
}

@media (max-width: 480px) {
  .ck-xmr-modal {
    /* Fill the width: a 100vw-wide dialog on a phone is expected, and the
       16px gutter is what keeps the rounded corners visible. */
    width: calc(100vw - 16px);
    padding: 20px 18px 16px;
    max-height: calc(100dvh - 24px);
  }
  /* The address is 95 characters; at 11.5px it needs the full panel width to
     wrap to about six lines rather than breaking mid-glyph. */
  .ck-xmr-addr { font-size: 10.5px; padding: 9px 10px; }
  .ck-xmr-kicker { letter-spacing: 0.2em; }
  .ck-xmr-sig { font-size: 9.5px; }
}

@media (max-height: 620px) {
  .ck-xmr-body { font-size: 12.5px; line-height: 1.5; }
}

/* ------------------------------------------------------- reduced motion */

/* The drifting blobs and the pulsing dots are the only motion on the page.
   Both are decoration; both go away entirely, not just faster. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* The three drifting blobs are the page's only ambient motion and they cover
     the whole viewport at 90px blur, so they are the part that actually costs
     a user with vestibular sensitivity something. They stop outright - not
     slowed, not paused on a frame. */
  .vv-blob,
  .eyebrow-dot,
  .live-dot {
    animation: none !important;
  }
  .vv-blob { opacity: 0.4; }
  /* The countdown is a `setInterval` in JS, not a CSS animation, so the media
     query cannot stop it. It is left running: it is a number changing once a
     second in a live region, not motion the eye has to follow. */
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}
/* Monero QR in the donate modal. Copied verbatim from the cocks.io start page
   (skin/pub/main.css equivalent, LowerBanner.tmpl) so the QR looks identical
   on the bouncer, on slot and on delta rather than merely similar. */
.ck-xmr-qr { width: 140px !important; max-width: 100% !important; margin: 14px auto 13px !important; border-radius: 9px !important; overflow: hidden !important; line-height: 0 !important; }
.ck-xmr-qr svg { display: block !important; width: 100% !important; height: auto !important; }

@media (max-width: 480px) {
	.ck-xmr-qr { width: 124px !important; margin: 12px auto 11px !important; }
}