/* Smart Money Sweeps — the site stylesheet.

   Ported at M5 from the locked M4 design (proto/merged/style.css, the North Sea
   system the owner selected on 2026-08-10). The component rules below are the
   reviewed ones, unchanged: this file is the design decision, not a new one.

   THREE RULES BIND EVERY EDIT HERE.

   1. NO LITERAL COLOUR. Not a hex, not an rgb(), not an hsl(). Every colour is
      a var(--token) from assets/css/tokens.css, which is GENERATED from the
      locked registry in proto/merged/palettes.mjs and must never be hand-edited.
      tokens.css is linked BEFORE this file on every page; a rule here that
      names a colour is a rule the palette can no longer move.
   2. The same goes for radius, spacing, type family and measure: --r-*, --s-*,
      --display/--ui/--body, --gutter and --measure all come from the same file.
   3. Nothing may reference a third party. Fonts are self-hosted beside this
      file and their OFL licences ship with them; scripts/build.mjs refuses to
      publish a page or stylesheet that points at another host.

   What changed on the way over from the prototype, and nothing else did:
     - the font URLs are ../fonts/, because this file sits in assets/css/ while
       the woff2 files sit in assets/fonts/;
     - the injected palette block is gone, replaced by the tokens.css link;
     - the style-guide chrome (.sg-*, .sw*) is gone - it belongs to
       styleguide.html, which still ships with its own stylesheet. */

/* ---------- fonts ----------
   Three families, each with one job, all OFL and self-hosted beside their
   licences. Fraunces is the warmth the merge needed and the one thing here that
   is neither candidate's body face; Archivo is editorial's, kept because the
   wordmark is built on it; Public Sans is editorial's reading face. */

@font-face {
  font-family: 'Fraunces';
  src: url('../fonts/fraunces-latin-600-normal.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-latin-500-normal.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-latin-600-normal.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-latin-700-normal.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Public Sans';
  src: url('../fonts/public-sans-latin-400-normal.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Public Sans';
  src: url('../fonts/public-sans-latin-600-normal.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}

/* ---------- tokens ----------
   Not here. Every page links assets/css/tokens.css first, and that file - which
   is generated from the locked palette registry - declares the whole colour,
   type, spacing and geometry contract on :root. This file only ever spends it. */

/* ---------- base ---------- */

*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--s-5);
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 400 var(--t-base)/var(--lh-body) var(--body);
  font-variant-numeric: tabular-nums;
}

h1, h2 { margin: 0; font-family: var(--display); font-weight: 600; line-height: var(--lh-tight); letter-spacing: var(--tr-display); }
h3 { margin: 0; font-family: var(--ui); font-weight: 700; line-height: var(--lh-tight); letter-spacing: var(--tr-display); }
p { margin: 0; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }
a { color: var(--brand-ink); }
#index, #method, #facts { scroll-margin-top: var(--s-5); }

.ic { flex: none; vertical-align: middle; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 10;
  background: var(--brand); color: var(--on-solid); padding: 0.6rem 1rem;
  border-radius: 0 0 var(--r-2) 0;
  font: 600 var(--t-sm) var(--ui); text-decoration: none;
}
.skip-link:focus { left: 0; }

:focus-visible { outline: var(--focus-ring) solid var(--focus); outline-offset: var(--focus-offset); border-radius: var(--r-1); }
.promise :focus-visible,
.foot :focus-visible { outline-color: var(--focus-on-dark); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.promise-in, .head-in, .hero-in, .foot-in, .index, .method-in, .op {
  max-width: var(--measure);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---------- promise strip ----------
   Friendly's honesty bar, in editorial's position and register: the three
   claims that make the page worth reading, printed before anything is sold. */

.promise { background: var(--brand-deep); color: var(--promise-text); }
.promise-in {
  display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-6);
  padding-block: 0.5rem;
}
.promise-in > span {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font: 500 var(--t-xs)/var(--lh-body) var(--ui); letter-spacing: var(--tr-slight);
}
.promise .ic { color: var(--promise-icon); }

/* ---------- masthead ---------- */

.head { background: var(--paper); border-bottom: 1px solid var(--rule); }
.head-in { display: flex; align-items: center; gap: 1.5rem; padding-block: 0.85rem; }
.brand { display: flex; align-items: center; gap: 0.65rem; text-decoration: none; color: var(--ink); }
.mark { flex: none; color: var(--brand); }
.brand-n { display: block; font: 700 var(--t-lg)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-display); }
.brand-s {
  display: block; margin-top: 0.3rem;
  font: 600 var(--t-2xs)/var(--lh-tight) var(--ui);
  letter-spacing: var(--tr-widest); text-transform: uppercase; color: var(--brand-ink);
}

/* Nav pills — the friendly candidate's active-nav treatment, brought over in
   the revision round. An underline under a 12px uppercase label is nearly
   invisible and does not survive a colour change; a filled pill is legible at a
   glance, gives the hover state somewhere to live, and is the one place the
   accent appears in the masthead. */
.nav { margin-left: auto; }
.nav ul { display: flex; gap: 0.3rem; }
.nav a {
  display: block;
  font: 600 var(--t-sm)/var(--lh-tight) var(--ui);
  text-transform: uppercase; letter-spacing: var(--tr-label);
  color: var(--ink-2); text-decoration: none;
  padding: 0.5rem 0.75rem; border-radius: var(--r-pill);
  border: 1px solid transparent;
  transition: color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}
.nav a:hover, .nav a.is-hover { background: var(--accent-wash); border-color: var(--accent-line); color: var(--accent-ink); }
.nav a.is-current, .nav a[aria-current='page'] {
  background: var(--brand-tint); border-color: var(--brand-line); color: var(--brand-ink);
}
.head-cta {
  font: 600 var(--t-sm)/var(--lh-tight) var(--ui);
  border: 1px solid var(--control-line); border-radius: var(--r-pill);
  padding: 0.55rem 0.85rem; text-decoration: none; color: var(--ink);
  transition: color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}
.head-cta:hover { border-color: var(--brand); color: var(--brand-ink); }

/* ---------- hero ----------
   Scaled down from both parents: one deck paragraph, and a panel that now
   explains the score instead of counting the set. */

.hero { background: var(--paper); border-bottom: 1px solid var(--rule); }
.hero-in {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(310px, 4fr);
  gap: var(--s-5) var(--s-7);
  padding-block: var(--s-6) var(--s-6);
  align-items: center;
}
.eyebrow {
  display: flex; align-items: center; gap: 0.55rem;
  font: 600 var(--t-2xs)/var(--lh-tight) var(--ui);
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--brand-ink);
  margin-bottom: 0.85rem;
}
.eyebrow::before { content: ''; width: 22px; height: 3px; border-radius: 2px; background: var(--brand-accent); }
.hero h1 { font-size: var(--t-hero); max-width: var(--read-title); text-wrap: balance; }
.lead {
  margin-top: 0.9rem;
  font-size: var(--t-lg); line-height: var(--lh-body);
  color: var(--ink-2); max-width: var(--read-lede);
}
.hero-btns { margin-top: 1.4rem; display: flex; flex-wrap: wrap; gap: 0.6rem; }

/* ---------- the scoring explainer ----------
   Replaced the "Where things stand" quick-stats panel in the revision round.
   Naming the four axes here is what makes the four rows on every card below
   legible at a glance instead of on second reading.

   M6 STEP 1, "OPTION A" (owner, 2026-08-10): this panel used to run a worked
   example, tagged "Example", with four invented marks and the arithmetic
   spelled out under the sum. All of that is gone - no fabricated score, only
   the formula. .panel-tag, .scoring-v and .scoring-maths existed to carry
   that worked example and are gone with it. */

.scoring {
  background: var(--ground); border: 1px solid var(--rule);
  border-radius: var(--r-4); padding: 1rem 1.1rem 1.05rem;
}
.panel-h {
  display: flex; align-items: center; gap: 0.5rem;
  font: 600 var(--t-2xs)/var(--lh-tight) var(--ui);
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
  padding-bottom: 0.75rem; border-bottom: 1px solid var(--rule);
}
/* M6.2: THE FLOW RUNS DOWN THE PANEL, NOT ACROSS IT.
   Beside the output badge the four tiles were 114px wide at 1440 and 77px at
   1024, which is narrower than the word "Redemptions" - the title overflowed
   its own tile at EVERY width, and at 1024 the descriptors went with it. The
   arrow-into-result reading is the owner's; the axis of it is not, and the
   panel already turned this way below 560px. Turning it at every width buys
   the tiles the full panel measure (184px at 1440, 142px at 1024) and the four
   inputs still converge on one result. */
.scoring-flow {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 0.6rem; justify-items: stretch; padding-top: 0.8rem;
}
/* auto-rows over auto-fit: both rows take the height of the tallest tile, so
   the four never step 86 / 118 the way content-sized rows did. */
.scoring-axes {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 1fr; gap: 0.5rem;
}
.scoring-axes li {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.45rem;
  align-items: start; min-height: 4.5rem;
  padding: 0.55rem; background: var(--paper); border: 1px solid var(--rule);
  border-radius: var(--r-2);
}
.scoring-ic { color: var(--brand); margin-top: 2px; }
.scoring-n { display: block; font: 700 var(--t-sm)/var(--lh-snug) var(--ui); letter-spacing: var(--tr-tight); color: var(--ink); }
.scoring-g { display: block; margin-top: 0.1rem; font: 400 var(--t-xs)/var(--lh-snug) var(--body); color: var(--ink-3); }
.scoring-join { color: var(--brand); font: 600 var(--t-xl)/var(--lh-tight) var(--ui); justify-self: center; transform: rotate(90deg); }
.scoring-output {
  display: grid; place-items: center; align-content: center;
  padding: 0.8rem 0.55rem; text-align: center;
  background: var(--brand-tint); border: 1px solid var(--brand-line); border-radius: var(--r-3);
}
.scoring-output-star { color: var(--brand); }
.scoring-output strong { margin-top: 0.35rem; font: 700 var(--t-sm)/var(--lh-snug) var(--ui); color: var(--ink); }
.scoring-output span { margin-top: 0.2rem; font: 400 var(--t-2xs)/var(--lh-snug) var(--body); color: var(--ink-3); }
/* The overall row is a result, not a second formula. The public explainer
   deliberately shows four weighted inputs converging without printing math. */
.scoring-sum {
  margin-top: 0.7rem; padding-top: 0.7rem; border-top: 1px solid var(--rule-2);
}
.scoring-sum-l { font: 700 var(--t-sm)/var(--lh-snug) var(--ui); color: var(--ink); }
.scoring-sum-l span { display: block; margin-top: 0.15rem; font: 400 var(--t-2xs)/var(--lh-snug) var(--body); color: var(--ink-3); }
.scoring-rule {
  display: flex; gap: 0.45rem; margin-top: 0.7rem; padding-top: 0.7rem;
  border-top: 1px solid var(--rule);
  font: 400 var(--t-xs)/var(--lh-body) var(--body); color: var(--ink-2);
}
.scoring-rule .ic { margin-top: 2px; color: var(--brand-accent); }

/* ---------- section heads ---------- */

.sec-head { padding-bottom: 1rem; border-bottom: 2px solid var(--ink); margin-bottom: 1.6rem; }
.sec-kicker {
  font: 600 var(--t-2xs)/var(--lh-tight) var(--ui);
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--brand-ink);
  margin-bottom: 0.5rem;
}
.sec-h { font-size: var(--t-head); max-width: var(--read-title); }
.sec-sub { margin-top: 0.6rem; font-size: var(--t-base); line-height: var(--lh-body); color: var(--ink-2); max-width: var(--read-wide); }
.index { padding-block: var(--s-6) 0; }

/* ---------- filters ----------
   Nested inside the section head, under the title they act on. */

.filters {
  margin-top: 1.15rem;
  background: var(--ground-2); border: 1px solid var(--rule);
  border-radius: var(--r-3); padding: 0.9rem 1rem 0.85rem;
}
.filters-grid {
  display: grid;
  grid-template-columns: minmax(200px, 1.5fr) repeat(3, minmax(150px, 1fr)) auto;
  gap: 0.7rem 0.9rem; align-items: end;
}
.fld label {
  display: block; margin-bottom: 0.35rem;
  font: 600 var(--t-2xs)/var(--lh-snug) var(--ui);
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--ink-3);
}
.in { position: relative; display: block; }
.in-ic {
  position: absolute; left: 0.6rem; top: 50%; margin-top: -8px;
  color: var(--ink-3); pointer-events: none;
}
.in input, .in select {
  width: 100%;
  font: 400 var(--t-md)/var(--lh-tight) var(--body);
  color: var(--ink); background: var(--paper);
  border: 1px solid var(--control-line); border-radius: var(--r-2);
  padding: 0.58rem 0.65rem 0.58rem 2.1rem;
}
.in input::placeholder { color: var(--ink-3); }
.in select { appearance: none; padding-right: 2rem; }
/* A thin chevron, drawn from two borders so it carries the same 1.6px weight as
   the icon set without being a second image. */
.sel::after {
  content: ''; position: absolute; right: 0.85rem; top: 50%;
  width: 7px; height: 7px; margin-top: -5px;
  border-right: 1.6px solid var(--ink-3); border-bottom: 1.6px solid var(--ink-3);
  transform: rotate(45deg); pointer-events: none;
}
.filters-note {
  display: flex; gap: 0.4rem; margin-top: 0.8rem;
  font: 400 var(--t-xs)/var(--lh-body) var(--body); color: var(--ink-3);
}
.filters-note .ic { margin-top: 2px; }
.filter-actions { display: flex; flex-wrap: wrap; gap: var(--s-2); }

/* ---------- the referral disclosure ----------
   ONE line, above the grid, before any Sign up button can be reached. It is
   deliberately not quiet: the point of moving it off the individual cards was
   to make it conspicuous, not to tuck it away in a smaller place. */

.disclose {
  display: flex; gap: 0.55rem; align-items: flex-start;
  margin-bottom: 1.15rem;
  background: var(--accent-wash);
  border: 1px solid var(--accent-line); border-left: 3px solid var(--brand-accent);
  border-radius: var(--r-3); padding: 0.7rem 0.9rem;
  font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--accent-ink);
}
.disclose .ic { margin-top: 2px; }
.disclose strong { font-weight: 600; }

/* ---------- the dash legend ----------
   Said once, above the grid, because every card now prints every row and an
   unverified value is a dash. Quiet on purpose: the disclosure above it is the
   thing a reader must not miss, and two loud bars in a row would mean neither
   of them is. */

.legend {
  display: flex; gap: 0.5rem; align-items: flex-start;
  margin-bottom: 1.15rem; padding-left: 0.1rem;
  font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-2);
}
.legend .ic { margin-top: 2px; color: var(--ink-3); }
.legend strong { font-weight: 600; color: var(--ink); }

/* ---------- cards ----------
   Lean by the owner's pick, with the axis breakdown and the verdict restored in
   the revision round: those two are what make a score legible rather than
   asserted. Playthrough, excluded states, promo-ban behaviour and days-to-floor
   all still belong to the detail page. */

.cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.15rem; }
.card {
  display: flex; flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-3);
  padding: 1.05rem 1.05rem 0.95rem;
}
/* An author rule that sets `display` (the flex above) otherwise wins the
   cascade over the user-agent `[hidden]{display:none}` rule, so a card the
   M5-step-2 script hides with the `hidden` attribute would silently keep
   rendering without this override. */
.card[hidden] { display: none; }

/* The zero-results state assets/js/landing.js shows when a filter combination
   matches nothing. Styled quietly, like .legend: it is information, not a
   warning, and it sits where the grid was without the page jumping. */
.cards-empty {
  display: flex; gap: 0.55rem; align-items: flex-start;
  margin-top: 0.4rem; padding: 1.4rem 1.1rem;
  background: var(--ground-2); border: 1px dashed var(--rule); border-radius: var(--r-3);
  font: 400 var(--t-md)/var(--lh-body) var(--body); color: var(--ink-2);
}
.cards-empty .ic { margin-top: 2px; color: var(--ink-3); }
.cards-empty[hidden] { display: none; }
.card-head {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.75rem;
  align-items: center; padding-bottom: 0.85rem; border-bottom: 1px solid var(--rule);
}
.tile {
  width: 46px; height: 46px; flex: none;
  display: grid; place-items: center;
  background: var(--brand); color: var(--on-solid);
  border-radius: var(--r-2);
  font: 700 var(--t-base)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-slight);
}
/* A real operator icon sits on white, inset, so a square app icon and a
   transparent logotype both look deliberate in the same tile. */
.tile.has-img { background: var(--paper); border: 1px solid var(--rule); padding: 4px; }
.tile img { width: 100%; height: 100%; object-fit: contain; border-radius: 7px; }
.card-name { font-size: var(--t-xl); }
/* M6: the card title links to the operator's page, and looks exactly like the
   heading it replaced until you point at it. A title sitting beside a "Details"
   button while not itself being clickable is a small daily annoyance; a title
   recoloured to link-teal would be a change to a design the owner signed off
   on. Inheriting the ink and underlining on hover/focus buys the behaviour
   without moving a pixel at rest. */
.card-name a { color: inherit; text-decoration: none; }
.card-name a:hover, .card-name a:focus-visible { text-decoration: underline; text-underline-offset: 2px; }
.card-parent {
  margin-top: 0.28rem;
  font: 600 var(--t-2xs)/var(--lh-snug) var(--ui);
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--ink-3);
}
.rank { font: 700 var(--t-xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-label); color: var(--ink-3); }

/* The score band is given a fixed height so the axis breakdown — and every row
   under it — starts at the same y on all six cards. A rated card shows one line
   of stars; a provisional one shows a badge and two lines of reason, and
   without this the grid stepped by about 40px from card to card. */
.score {
  display: flex; align-items: center; gap: 0.55rem;
  padding: 0.65rem 0 0.55rem; min-height: 4.75rem;
}
.stars-bg { fill: var(--rule); }
.stars-fg { fill: var(--brand); }
.score-n { font: 700 var(--t-xl)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-display); }
.score-of { font: 600 var(--t-md)/var(--lh-tight) var(--ui); color: var(--ink-3); }

.score.is-provisional { display: block; padding-bottom: 0.7rem; }
/* Neutral, not accented: the accent belongs to the thing we want acted on, and
   "we have not finished checking" is not an offer. */
.prov-badge {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font: 700 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-wide); text-transform: uppercase;
  color: var(--ink-2); background: var(--ground-2);
  border: 1px solid var(--rule-2); border-radius: var(--r-pill);
  padding: 0.35rem 0.6rem;
}
.prov-note { margin-top: 0.5rem; font: 400 var(--t-xs)/var(--lh-body) var(--body); color: var(--ink-2); }

/* ---------- the four axes ----------
   The friendly candidate's treatment. A hatched bar for an unscored axis is the
   load-bearing detail: an empty bar and a 0.0 bar are the same picture, and
   "nobody has looked yet" must never render as "we looked and it was nothing". */

/* The heading is what keeps "Daily Bonus the score" from being read as "Daily
   Bonus the coins", now that the owner has given both the same name. It is
   small and quiet, but it is not optional. */
.axes-block { padding-bottom: 0.85rem; border-bottom: 1px solid var(--rule); margin-bottom: 0.9rem; }
.axes-h {
  display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem;
  margin-bottom: 0.55rem;
  font: 700 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-wide); text-transform: uppercase;
  color: var(--ink-2);
}
.axes-h-of {
  font: 400 var(--t-2xs)/var(--lh-tight) var(--body); letter-spacing: 0; text-transform: none; color: var(--ink-3);
}
.axes {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem 0.9rem;
}
.axis {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline; column-gap: 0.4rem;
  font: 600 var(--t-2xs)/var(--lh-tight) var(--ui);
}
.axis-l { color: var(--ink-2); letter-spacing: var(--tr-slight); }
.axis-v { text-align: right; color: var(--ink); }
/* The "/5" is the second half of the same defence: a score carries a
   denominator, a coin amount carries units. Neither can be mistaken for the
   other in a skim. */
.axis-of { font: 600 var(--t-2xs)/var(--lh-tight) var(--ui); color: var(--ink-3); }
.axis.is-unscored .axis-v { font-size: var(--t-2xs); font-weight: 700; letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--ink-3); }
.axis-bar {
  grid-column: 1 / -1; margin-top: 0.22rem;
  height: 6px; border-radius: var(--r-pill);
  background: var(--ground-2); border: 1px solid var(--rule);
  overflow: hidden;
}
.axis-fill { display: block; height: 100%; background: var(--brand); }
.axis-hatch {
  display: block; height: 100%;
  background: repeating-linear-gradient(-45deg, var(--rule-2) 0 2px, transparent 2px 5px);
}

/* the sign-up bonus — the one element on a lean card allowed to shout */
.signup {
  background: var(--accent-wash); border: 1px solid var(--accent-line);
  border-left: 3px solid var(--brand-accent);
  border-radius: var(--r-3);
  padding: 0.6rem 0.75rem 0.65rem; min-height: 5.45rem;
}
.signup-l {
  display: flex; align-items: center; gap: 0.35rem;
  font: 700 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-wide); text-transform: uppercase;
  color: var(--accent-ink);
}
/* ONE line, two halves. The free coins are the loud half, in full ink; the pack
   sits a shade back and carries a price, because it costs money and must never
   read as part of the free offer. The block this replaced said the same thing
   across three lines and a hairline rule. */
.signup-v {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; min-height: 2.8em;
  margin-top: 0.35rem; font: 700 var(--t-base)/var(--lh-snug) var(--ui); letter-spacing: var(--tr-display); color: var(--ink);
}
.su-pack { color: var(--ink-2); }
.su-plus { color: var(--accent-ink); padding: 0 0.28rem; }

.facts { margin-top: 0.9rem; border-top: 1px solid var(--rule); }
.fact {
  display: flex; align-items: baseline; justify-content: space-between; gap: 0.9rem;
  padding: 0.5rem 0; border-bottom: 1px solid var(--rule);
}
.fact:last-child { border-bottom: 0; }
/* THE LABEL IS NOT A FLEX CONTAINER, and that is the whole fix for the
   misalignment the owner spotted on the Daily Bonus row. A flex box takes its
   baseline from its FIRST flex item, which here was the 15px icon — so the
   label's "baseline" was the bottom edge of a picture, and the row's two halves
   sat two or three pixels apart on every card. As plain inline content the
   label's baseline is its text's baseline, which is what `align-items:baseline`
   on .fact was asking for all along; the icon rides on vertical-align. */
.fact dt {
  flex: 0 0 auto; white-space: nowrap;
  font: 600 var(--t-2xs)/var(--lh-snug) var(--ui); letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--ink-2);
}
.fact dt .ic { color: var(--ink-3); margin-right: 0.4rem; vertical-align: -0.22em; }
.fact dd { flex: 1 1 auto; font: 600 var(--t-sm)/var(--lh-snug) var(--ui); text-align: right; }
/* An unverified value is a dash, and a dash does not need italics to say it is
   not a number — it is already not a number. Just the quiet ink. */
.fact.is-unknown dd { color: var(--ink-3); }

/* ---------- redemptions ----------
   Two labelled values instead of one run-on line. Each half carries its own
   not-verified state; neither is a sentence.

   SECOND REVISION ROUND — DELIBERATELY QUIET. This block had a filled panel, a
   bordered box per value and figures at 1rem/700: the loudest thing on the
   card, spent on a number most readers consult once. It was outshouting the
   verdict, which is the only sentence on the card a person wrote. So: no fill,
   no boxes, one hairline above it, a 9.5px label, and values at fact-row size.
   Nothing was removed — only the volume. */

.redeem {
  margin-top: 0.8rem; padding-top: 0.65rem;
  border-top: 1px solid var(--rule);
}
.redeem-l {
  display: flex; align-items: center; gap: 0.35rem;
  font: 600 var(--t-2xs)/var(--lh-snug) var(--ui); letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.redeem-l .ic { color: var(--ink-3); }
.redeem-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem 0.9rem; margin-top: 0.35rem; }
.redeem-k { display: block; font: 400 var(--t-2xs)/var(--lh-snug) var(--body); color: var(--ink-3); }
.redeem-v { display: block; margin-top: 0.1rem; font: 600 var(--t-sm)/var(--lh-snug) var(--ui); color: var(--ink); }
.redeem-cell.is-unknown .redeem-v { color: var(--ink-3); }

/* ---------- our take ----------
   The card's highlighted editorial moment, and the emphasis Redemptions gave
   up. Teal rather than terracotta: the accent belongs to the thing we want
   acted on, and this is us talking, not an offer. */

.take {
  margin-top: 0.85rem;
  background: var(--brand-tint);
  border: 1px solid var(--brand-line); border-left: 3px solid var(--brand);
  border-radius: var(--r-3);
  padding: 0.6rem 0.75rem 0.65rem;
}
.take-l {
  display: flex; align-items: center; gap: 0.35rem; margin-bottom: 0.25rem;
  font: 700 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--brand-ink);
}
.take-l .ic { color: var(--brand-ink); }
.card .take-v {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden; min-height: 4.65em;
  font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink);
}
.op-take .take-v { display: block; min-height: 0; overflow: visible; }

/* the only red in the system — detail pages, never the landing card */
.warn {
  display: flex; gap: 0.45rem; margin-top: 0.85rem;
  background: var(--warn-wash); border: 1px solid var(--warn-line);
  border-radius: var(--r-2); padding: 0.5rem 0.6rem;
  font: 400 var(--t-xs)/var(--lh-body) var(--body); color: var(--warn);
}
.warn .ic { margin-top: 2px; }
.warn strong { font-weight: 600; }

.stamp {
  display: flex; align-items: center; gap: 0.35rem; margin-top: 0.8rem;
  font: 400 var(--t-xs)/var(--lh-snug) var(--body); color: var(--ink-3);
}
.stamp .ic { color: var(--good); }

.card-foot { margin-top: auto; padding-top: 0.85rem; }
.actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem;
  font: 600 var(--t-md)/var(--lh-tight) var(--ui);
  padding: 0.6rem 0.95rem;
  border: 1px solid var(--brand); border-radius: var(--r-2);
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: transform var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), box-shadow var(--motion-fast) var(--motion-ease);
}
.btn:not([aria-disabled='true']):hover { transform: translateY(-1px); }
.btn:not([aria-disabled='true']):active { transform: translateY(1px); }
.btn-solid, .btn-solid:link, .btn-solid:visited { color: var(--on-solid); background: var(--brand); }
.btn-solid:hover, .btn-solid.is-hover { background: var(--brand-deep); border-color: var(--brand-deep); }
.btn-line, .btn-line:link, .btn-line:visited { color: var(--brand-ink); background: var(--paper); }
.btn-line:hover, .btn-line.is-hover { background: var(--brand-tint); }
.btn-quiet, .btn-quiet:link, .btn-quiet:visited {
  color: var(--ink-2); background: transparent; border-color: var(--control-line);
}
.btn-quiet:hover, .btn-quiet.is-hover { color: var(--ink); border-color: var(--ink-3); background: var(--ground-2); }
.btn-lg { font-size: var(--t-base); padding: 0.75rem 1.15rem; }
.btn[aria-disabled='true'], .btn.is-disabled {
  color: var(--ink-3); background: var(--ground-2); border-color: var(--rule);
  cursor: not-allowed;
}
.btn-ic { margin-left: 0.1rem; }
.actions .btn { width: 100%; min-width: 0; }

/* ---------- method ---------- */

.method { padding-block: var(--s-7) var(--s-7); }
.method-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.6rem 2.2rem; }
.method-n {
  display: flex; align-items: center; gap: 0.45rem; margin-bottom: 0.55rem;
  font: 700 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-wide); color: var(--brand-ink);
}
.method-n .ic { color: var(--brand-accent); }
.method-col h3 { font-size: var(--t-base); margin-bottom: 0.45rem; }
.method-col p { font: 400 var(--t-md)/var(--lh-loose) var(--body); color: var(--ink-2); }

/* ---------- footer ---------- */

.foot { background: var(--brand-deep); color: var(--footer-text); }
.foot-in { padding-block: var(--s-4); }
.foot-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.2rem; flex-wrap: wrap; padding-bottom: 0.75rem; border-bottom: 1px solid var(--dark-surface-rule);
}
.foot-brand { display: flex; align-items: center; gap: 0.6rem; color: var(--on-solid); font: 700 var(--t-base)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-display); }
.foot-brand .mark { color: var(--on-solid); }
.foot-nav ul { display: flex; gap: 1.4rem; }
.foot-nav a {
  color: var(--footer-text); text-decoration: none;
  font: 600 var(--t-xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-label); text-transform: uppercase;
}
.foot-nav a:hover { color: var(--on-solid); }
.foot-copy { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-5); padding-top: 0.75rem; }
.foot-promises { display: grid; gap: var(--s-3); }
.foot-disc { font: 400 var(--t-xs)/var(--lh-body) var(--body); max-width: var(--read-legal); }
.foot-disc strong {
  display: block; color: var(--on-solid);
  font: 700 var(--t-2xs)/var(--lh-body) var(--ui); letter-spacing: var(--tr-wide); text-transform: uppercase;
}
.foot-legal { font: 400 var(--t-xs)/var(--lh-body) var(--body); color: var(--footer-legal); max-width: var(--read-legal); }

::view-transition-group(*) { animation-duration: var(--motion-medium); animation-timing-function: var(--motion-ease); }

/* ---------- operator detail pages (M6) ----------
   /casinos/<slug>/ — everything the lean card deliberately left out.

   NO NEW VOCABULARY WAS INVENTED HERE. The page is assembled from the
   components the owner already reviewed: the hairline .fact rows, the teal
   .take panel, the hatched .axis bars, .sec-head, the pill nav, the buttons,
   and the one .warn that is the only red in the system (it finally has the
   detail page the comment above it always promised). What is below is the
   rules those components need in a two-column decision layout plus the
   breadcrumb, state chips, pros/cons lists and free-bonus timeline.

   Same three rules as the rest of this file: no colour literal, no raw
   radius/space/family, nothing third-party. */

/* THE REFERENCE RECORD READS NARROWER THAN THE HERO (M6.2, owner).
   Everything below the hero is fact rows, panels and score bars, and at the
   full 1280px measure they stretched across dead space: a two-word label on
   the left, a two-word value on the right, and 900px of nothing between them.
   The hero and the At a Glance rail keep the wide measure - they are a
   summary, and a summary is allowed to fill the page.

   Left-aligned rather than centred, deliberately: the hero above it starts at
   the same x, and a centred column would read as a different page. */
.op { padding-block: var(--s-6); --op-measure: 880px; }
.op-sec, .op-stamp { max-width: var(--op-measure); }
.op-sec + .op-sec { margin-top: var(--s-6); }
/* Reference headings, not editorial ones: the kicker is gone (render/detail.mjs)
   and the heading scales to the narrower measure. Same Fraunces, same weight -
   this is a size decision, not a type change. */
.op .sec-h { font-size: var(--t-subhead); max-width: var(--read-head); }
.op .sec-head { padding-bottom: 0.7rem; margin-bottom: 1.1rem; }

/* Panels are cards without the flex column: one hairline box, one uppercase
   label, rows under it. Same paper, border, radius and padding as .card so a
   detail page and the grid it came from are recognisably the same object. */
.panel {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-3);
  padding: 1.05rem 1.05rem 1rem;
}
.panel-hint {
  margin-left: auto;
  font: 400 var(--t-2xs)/var(--lh-snug) var(--body); letter-spacing: 0; text-transform: none; color: var(--ink-3);
}
/* The panel's own label already carries a bottom hairline, so the first .facts
   list inside it must not draw a second one directly underneath. */
.panel .facts { margin-top: 0.35rem; border-top: 0; }

/* STRETCH, NOT START. Panels sharing a row are one row of the record, and a
   pair of boxes whose bottom edges disagree by 60px reads as a rendering fault
   rather than as two panels with different amounts in them. Their content stays
   top-aligned - .panel is an ordinary block, so only the box grows. */
.op-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.15rem; align-items: stretch; }
.op-grid--one { grid-template-columns: minmax(0, 1fr); }

/* A quiet full-width line under a panel's rows: a method, a caveat, a source
   note. Never a value — values are .fact rows, and anything that reads like a
   number belongs in one. */
.op-note {
  display: flex; gap: 0.45rem; align-items: flex-start;
  margin-top: 0.7rem; padding-top: 0.7rem; border-top: 1px solid var(--rule);
  font: 400 var(--t-xs)/var(--lh-body) var(--body); color: var(--ink-2);
}
.op-note .ic { margin-top: 2px; color: var(--ink-3); flex: none; }
.op-note + .op-note { border-top: 0; margin-top: 0.4rem; padding-top: 0; }

/* ---------- the detail hero ---------- */

.crumb {
  display: flex; align-items: center; gap: 0.45rem; margin-bottom: 1rem;
  font: 600 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--ink-3);
}
.crumb a { color: var(--brand-ink); text-decoration: none; }
.crumb a:hover { text-decoration: underline; }

/* The landing's hero centres its two columns because they are close in height.
   Here the left column is three times the rail, so centring floats the score
   breakdown into the middle of nowhere. */
.op-hero .hero-in { align-items: start; }
.op-id { display: flex; align-items: center; gap: 0.9rem; }
.op-id .tile { width: 54px; height: 54px; font-size: var(--t-base); }
.op-hero h1 { font-size: var(--t-hero); max-width: var(--read-display); }
.op-parent {
  margin-top: 0.35rem;
  font: 600 var(--t-2xs)/var(--lh-snug) var(--ui);
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--ink-3);
}
/* The card's score band is height-locked so six cards line up. One page, one
   operator, nothing to line up with. */
.op-hero .score { min-height: 0; margin-top: 1rem; padding-bottom: 0; }
.op-take { margin-top: 1.1rem; }
.op-take .take-v { font-size: var(--t-base); }
.op-hero .disclose { margin-top: 1.1rem; }
.op-hero .hero-btns { margin-top: 1rem; }

/* The detail-page rail answers the four first questions before a reader has to
   enter the reference record below. It remains ordinary document flow, so at
   tablet and mobile it follows the hero summary rather than becoming a sticky
   or overlapping control. */
.op-summary-rail { display: grid; gap: var(--s-4); }
.op-glance .facts { margin-top: var(--s-2); }
.op-timeline-track {
  display: flex; align-items: center; height: var(--s-2); margin-top: var(--s-4);
  overflow: hidden; border: 1px solid var(--rule); border-radius: var(--r-pill); background: var(--ground-2);
}
.op-timeline-track span { width: 100%; height: 100%; background: var(--brand); }
.op-timeline-track.is-unknown { border-style: dashed; }
.op-timeline-track.is-unknown span { width: 36%; background: repeating-linear-gradient(-45deg, var(--rule-2) 0 2px, transparent 2px 5px); }
.op-timeline-n {
  margin-top: var(--s-3); font: 600 var(--t-4xl)/var(--lh-tight) var(--display);
  letter-spacing: var(--tr-display); color: var(--brand);
}
.op-timeline-n span {
  margin-left: var(--s-2); font: 700 var(--t-2xs)/var(--lh-tight) var(--ui);
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
}
.op-timeline-n.is-unknown { color: var(--ink-3); }
.op-timeline-t { margin-top: var(--s-2); font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-2); }
.op-timeline-caveat { margin-top: var(--s-3); font: 600 var(--t-2xs)/var(--lh-body) var(--ui); color: var(--ink-3); }
.op-calc { margin-top: var(--s-3); padding-top: var(--s-3); border-top: 1px solid var(--rule); }
.op-calc summary { cursor: pointer; font: 600 var(--t-xs)/var(--lh-snug) var(--ui); color: var(--brand-ink); }
.op-calc summary,
.op-detail summary {
  transition: color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}
.op-calc summary:hover,
.op-detail summary:hover { color: var(--accent-ink); }
.op-calc p { margin-top: var(--s-2); font: 400 var(--t-xs)/var(--lh-body) var(--body); color: var(--ink-2); }

/* Pros and cons — recorded, owner-authored, and the reason this page exists.
   Cons are NOT red: red is reserved for a genuine warning, and a drawback is
   not a hazard. */
.op-pcs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem 1.6rem; margin-top: 1.1rem; }
.op-pc-h {
  font: 700 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
  margin-bottom: 0.5rem;
}
.op-pc li {
  display: flex; gap: 0.45rem; align-items: flex-start;
  font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-2);
}
.op-pc li + li { margin-top: 0.35rem; }
.op-pc li .ic { margin-top: 3px; flex: none; }
.op-pc--pro li .ic { color: var(--good); }
.op-pc--con li .ic { color: var(--ink-3); }

/* The score-breakdown rail: the scoring panel's frame, one axis per row rather
   than the card's two-up grid, with room for the note under each bar. */
.op-axis-list { grid-template-columns: minmax(0, 1fr); gap: 0.85rem; padding-top: 0.85rem; }
.op-axis-list .axis { font-size: var(--t-xs); }
.axis-subtitle {
  grid-column: 1 / -1; margin-top: var(--s-1);
  font: 400 var(--t-xs)/var(--lh-body) var(--body); color: var(--ink-2);
}
.axis-note {
  grid-column: 1 / -1; margin-top: 0.3rem;
  font: 400 var(--t-xs)/var(--lh-body) var(--body); color: var(--ink-3);
}

/* ---------- offers ---------- */

.op-packs { margin-top: 0.8rem; padding-top: 0.7rem; border-top: 1px solid var(--rule); }
.op-packs-h {
  font: 700 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3);
  margin-bottom: 0.45rem;
}
.op-packs li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 0.9rem;
  padding: 0.35rem 0; border-bottom: 1px solid var(--rule);
}
.op-packs li:last-child { border-bottom: 0; }
.op-pack-v { font: 700 var(--t-sm)/var(--lh-snug) var(--ui); color: var(--ink); }
.op-pack-p { font: 600 var(--t-sm)/var(--lh-snug) var(--ui); color: var(--ink-2); }
.op-packs-none { font: 600 var(--t-sm)/var(--lh-snug) var(--ui); color: var(--ink-3); }

/* ---------- cashing out and progressive detail ---------- */

/* Two across and the third full width, because three across the narrower
   measure gives each panel 280px - and a .fact row's label does not wrap, so
   "First Redemption (ID Checks)" would leave its value about 40px to live in.
   Getting Paid is the panel with the rows in it and it gets the room. */
.op-grid--three { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.op-grid--three > :nth-child(3) { grid-column: 1 / -1; }
.op-details { display: grid; gap: var(--s-3); }
.op-detail {
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-3);
  overflow: hidden;
}
.op-detail summary {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3);
  padding: var(--s-4); cursor: pointer; font: 700 var(--t-sm)/var(--lh-snug) var(--ui); color: var(--ink);
  list-style: none;
}
.op-detail summary::-webkit-details-marker { display: none; }
.op-detail summary::after {
  content: '+'; flex: none; color: var(--brand); font: 500 var(--t-lg)/var(--lh-tight) var(--ui);
  transition: transform var(--motion-fast) var(--motion-ease);
}
.op-detail[open] summary::after { transform: rotate(45deg); }
.op-detail summary span:last-child { font: 400 var(--t-xs)/var(--lh-snug) var(--body); color: var(--ink-3); text-align: right; }
.op-detail[open] summary { border-bottom: 1px solid var(--rule); }
.op-detail-body { padding: var(--s-4); }
.op-detail-intro { margin-bottom: var(--s-4); font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-2); max-width: var(--read-wide); }

/* ---------- state availability ---------- */

.op-states-n {
  margin-top: 0.6rem;
  font: 700 var(--t-lg)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-display); color: var(--ink);
}
.op-states-n.is-unknown { color: var(--ink-3); }
/* The Allowed panel's one line (M6.2). Prose, not a figure: it is a sentence
   attributed to the operator's terms, and setting it at .op-states-n's 1.1rem
   bold would make it shout over the enumeration it points at. */
.op-states-summary { margin-top: 0.6rem; font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-2); }
/* Chips rather than a comma list: seventeen states in a sentence is a wall, and
   the reader is scanning for exactly one of them. They carry full state names
   from M6.2 - the code is what the database stores, not what a reader looking
   for Michigan wants to have to decode. */
.op-states { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.7rem; }
.op-states li {
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--rule); border-radius: var(--r-pill);
  background: var(--ground);
  font: 700 var(--t-2xs)/var(--lh-snug) var(--ui); letter-spacing: var(--tr-label); color: var(--ink-2);
}

/* ---------- responsive ---------- */

@media (max-width: 1120px) {
  .cards, .amoe-grid, .guide-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* The four controls hold one row and the button takes its own. Five items in
     four columns left "Sort By" orphaned beside the button, which is the shape
     that made the first label wrap and the search placeholder truncate. */
  .filters-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .fld--go { grid-column: 1 / -1; }
}

@media (max-width: 960px) {
  .hero-in { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .scoring { max-width: 560px; }
  /* Three fit down to here; below it, one. Two columns put a lone third column
     under a pair, and an orphaned card reads as a mistake rather than a list. */
  .method-grid { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
  .method-col p { max-width: var(--read-body); }
  .op-grid, .op-grid--three, .op-grid--three > :nth-child(3) { grid-template-columns: minmax(0, 1fr); grid-column: auto; }
}

/* 2x2, so "Looking for one in particular?" keeps one line and the search input
   keeps its whole placeholder. 1040px is where a quarter-width column stops
   holding that label on one line - measured, not guessed. */
@media (max-width: 1040px) {
  .filters-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
  .head-in { flex-wrap: wrap; gap: 0.9rem; }
  .brand { margin-right: auto; }
  .nav { margin-left: 0; order: 3; width: 100%; border-top: 1px solid var(--rule); padding-top: 0.7rem; }
  .nav ul { flex-wrap: wrap; margin-inline-start: -0.75rem; }
  /* One card per row: nothing sits beside anything, so the fixed score band
     that keeps six cards in step is pure empty space here. */
  .score { min-height: 0; }
  .cards, .amoe-grid, .guide-grid { grid-template-columns: minmax(0, 1fr); }
  .filters-grid { grid-template-columns: minmax(0, 1fr); }
  .promise-in { gap: 0.35rem 1.2rem; }
  .promise-in > span { font-size: var(--t-2xs); }
  .op-pcs { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 560px) {
  .head-cta { display: none; }
  .hero-btns .btn { flex: 1 1 auto; }
  .foot-copy { grid-template-columns: minmax(0, 1fr); gap: var(--s-3); }
}

@media (max-width: 420px) {
  .fact { flex-direction: column; align-items: flex-start; gap: 0.15rem; }
  .fact dd { text-align: left; }
  /* The tile and the operator name stop competing for one line. */
  .op-id { flex-direction: column; align-items: flex-start; gap: 0.7rem; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation: none !important; transition: none !important; }
}

/* ---------- games catalogue ---------- */
.games-hero, .games-index { max-width: var(--measure); margin-inline: auto; padding-inline: var(--gutter); }
.games-hero { padding-block: var(--s-6) var(--s-5); background: var(--paper); }
.games-hero h1 { font-size: var(--t-hero); max-width: var(--read-title); }
.games-index { padding-block: var(--s-5) var(--s-7); }
.games-method, .games-empty { display: flex; gap: 0.65rem; align-items: flex-start; margin-bottom: 1.2rem; padding: 0.85rem 0.95rem; background: var(--brand-tint); border: 1px solid var(--brand-line); border-radius: var(--r-3); color: var(--ink-2); font: 400 var(--t-sm)/var(--lh-body) var(--body); }
.games-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
.game-card, .notable-games { padding: 1rem; background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-3); }
.game-card-top { display: flex; justify-content: space-between; gap: 0.7rem; padding-bottom: 0.75rem; border-bottom: 1px solid var(--rule); }
.game-kicker, .game-facts dt { font: 600 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--ink-3); }
.game-rtp { text-align: right; color: var(--brand-ink); }.game-rtp span { display: block; font: 600 var(--t-2xs)/var(--lh-tight) var(--ui); text-transform: uppercase; }.game-rtp strong { font: 700 var(--t-lg)/var(--lh-tight) var(--ui); }.game-rtp.is-unknown { color: var(--ink-3); }
.game-card h3 { margin-top: 0.9rem; font-size: var(--t-xl); }.game-facts { margin-top: 0.85rem; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.7rem; }.game-facts dd { margin-top: 0.15rem; color: var(--ink-2); font: 400 var(--t-sm)/var(--lh-snug) var(--body); }
.notable-games-list { display: grid; gap: 0.45rem; }.notable-games-list li { display: grid; grid-template-columns: minmax(0, 1fr) repeat(4, auto); gap: 0.7rem; padding-block: 0.4rem; border-bottom: 1px solid var(--rule); }.notable-games-list li:last-child { border: 0; }.notable-games-list span, .notable-games-empty { color: var(--ink-3); font-size: var(--t-sm); }
@media (max-width: 960px) { .games-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) {
  .games-grid { grid-template-columns: minmax(0, 1fr); }
  .notable-games-list li { grid-template-columns: minmax(0, 1fr); gap: 0.2rem; }
  .game-card, .notable-games, .game-facts > div { min-width: 0; overflow-wrap: anywhere; }
}

/* ---------- AMOE reference + print checklist ---------- */

.amoe-hero, .amoe-index, .amoe-checklist-main {
  max-width: var(--measure); margin-inline: auto; padding-inline: var(--gutter);
}
.amoe-hero { padding-block: var(--s-6) var(--s-5); background: var(--paper); }
.amoe-hero h1 { max-width: var(--read-title); font-size: var(--t-hero); }
.amoe-hero .lead { max-width: var(--read-body); }
.amoe-brief {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-3);
  margin-top: var(--s-5);
}
.amoe-brief > div {
  padding: var(--s-4); background: var(--ground); border: 1px solid var(--rule);
  border-radius: var(--r-3);
}
.amoe-brief strong {
  display: block; margin-bottom: var(--s-2); font: 700 var(--t-2xs)/var(--lh-tight) var(--ui);
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--brand-ink);
}
.amoe-brief p { font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-2); }

.amoe-index { padding-block: var(--s-5) var(--s-7); }
.amoe-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.15rem; }
.amoe-card {
  display: grid; grid-template-rows: auto 1fr auto; min-width: 0; padding: var(--s-4);
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-3);
}
.amoe-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-3); }
.amoe-card h3 { margin: 0; font-size: var(--t-xl); }
.amoe-card p { margin-top: var(--s-3); font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-2); }
.amoe-state {
  flex: none; padding: 0.32rem 0.58rem; border: 1px solid var(--rule);
  border-radius: var(--r-pill); font: 700 var(--t-2xs)/var(--lh-tight) var(--ui);
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--ink-3);
}
.amoe-state.is-ready { border-color: var(--brand-line); background: var(--brand-tint); color: var(--brand-ink); }
.amoe-card .btn { justify-self: start; margin-top: var(--s-4); }
.amoe-card-note { display: flex; align-items: flex-start; gap: var(--s-2); }
.amoe-card-note .ic { flex: none; margin-top: 0.2rem; color: var(--ink-3); }

.amoe-checklist-main { max-width: 940px; padding-block: var(--s-5) var(--s-7); }
.amoe-checklist-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-4); align-items: end; }
.amoe-checklist-head h1 { max-width: var(--read-display); font-size: var(--t-hero); }
.amoe-checklist-head .lead { max-width: var(--read-lede); }
.amoe-print-bar { display: flex; justify-content: flex-end; }
.amoe-sheet {
  margin-top: var(--s-5); padding: clamp(1rem, 3vw, 2rem); background: var(--paper);
  border: 1px solid var(--rule); border-top: 4px solid var(--brand); border-radius: var(--r-3);
}
.amoe-sheet-kicker {
  display: flex; align-items: center; gap: var(--s-2); font: 700 var(--t-2xs)/var(--lh-tight) var(--ui);
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--brand-ink);
}
.amoe-sheet-kicker .ic { color: var(--brand); }
.amoe-facts {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: var(--s-4); border-top: 1px solid var(--rule); border-left: 1px solid var(--rule);
}
.amoe-facts > div { min-width: 0; padding: var(--s-3); border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.amoe-facts dt {
  font: 700 var(--t-2xs)/var(--lh-tight) var(--ui); letter-spacing: var(--tr-wide);
  text-transform: uppercase; color: var(--ink-3);
}
.amoe-facts dd { margin-top: var(--s-2); font: 600 var(--t-md)/var(--lh-snug) var(--ui); color: var(--ink); overflow-wrap: anywhere; }
.amoe-section { margin-top: var(--s-5); }
.amoe-section h2 { font-size: var(--t-xl); }
.amoe-section-intro { margin-top: var(--s-2); max-width: var(--read-body); font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-2); }
.amoe-address {
  margin-top: var(--s-3); padding: var(--s-4); white-space: pre-line;
  border: 1px solid var(--rule); border-radius: var(--r-2);
  font: 600 var(--t-md)/var(--lh-body) var(--ui); color: var(--ink); background: var(--ground);
}
.amoe-instructions { margin-top: var(--s-3); }
.amoe-instructions ol, .amoe-instructions ul { display: grid; gap: var(--s-3); padding: 0; list-style: none; }
.amoe-instructions ol { counter-reset: amoe-step; }
.amoe-instructions li {
  position: relative; min-height: 2rem; padding: 0.45rem 0 0.45rem 2.6rem;
  border-bottom: 1px solid var(--rule); font: 400 var(--t-md)/var(--lh-body) var(--body); color: var(--ink-2);
}
.amoe-instructions li::before {
  content: ''; position: absolute; inset: 0.42rem auto auto 0;
  display: grid; place-items: center; width: 1.75rem; height: 1.75rem;
  border: 1px solid var(--brand-line); border-radius: var(--r-1);
  font: 700 var(--t-2xs)/var(--lh-tight) var(--ui); color: var(--brand-ink); background: var(--brand-tint);
}
.amoe-instructions ol li { counter-increment: amoe-step; }
.amoe-instructions ol li::before { content: counter(amoe-step); }
.amoe-instructions li p { margin: 0; }
.amoe-note, .amoe-sources {
  margin-top: var(--s-4); padding: var(--s-3); border-radius: var(--r-2);
  font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-2);
}
.amoe-note { background: var(--brand-tint); border: 1px solid var(--brand-line); }
.amoe-sources { border: 1px solid var(--rule); }
.amoe-sources strong { display: block; margin-bottom: var(--s-2); color: var(--ink); }
.amoe-sources ul { display: grid; gap: var(--s-1); }
.amoe-sources a { color: var(--brand-ink); overflow-wrap: anywhere; }

/* ---------- guides + help (M12) ----------
   /help is the guide index; /guides/<slug>/ is one owner-editable draft
   Markdown document. Both are editorial prose, never scored facts, so they are
   drafts: noindexed by the build and carrying a draft banner on the page.

   Same three rules as the rest of this file: no colour literal, no raw
   radius/space/family, nothing third-party. The Markdown renderer refuses raw
   HTML and remote images, so .guide-body is headings, paragraphs, lists and
   links only. */

.guide-main, .help-main {
  max-width: var(--measure);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: var(--s-6);
}
.guide-head { margin-bottom: var(--s-4); }
.help-head { margin-bottom: var(--s-5); }
.help-head .lead { margin-top: 0.6rem; max-width: var(--read-lede); }

/* The draft banner — a quiet "work in progress" note, not a warning. It reuses
   the teal brand-tint family (like .take) but sits full-width above the prose,
   so a reader meets the "not final advice" line before the content does. */
.draft-banner {
  display: flex; gap: 0.5rem; align-items: flex-start;
  margin: 1rem 0 1.4rem;
  background: var(--brand-tint);
  border: 1px solid var(--brand-line); border-left: 3px solid var(--brand);
  border-radius: var(--r-3); padding: 0.7rem 0.9rem;
  font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--brand-ink);
}
.draft-banner .ic { margin-top: 2px; color: var(--brand); flex: none; }

/* The rendered Markdown body. Prose only: the renderer refuses raw HTML and
   remote images, so this is headings, paragraphs, lists and links, set on the
   same type scale as the rest of the site. */
.guide-body { margin-top: var(--s-2); }
.guide-body > :first-child { margin-top: 0; }
.guide-body h2 { font-size: var(--t-xl); margin-top: var(--s-5); max-width: var(--read-head); }
.guide-body h3 { font-size: var(--t-lg); margin-top: var(--s-4); }
.guide-body p { margin-top: var(--s-3); font: 400 var(--t-base)/var(--lh-loose) var(--body); color: var(--ink-2); max-width: var(--read-body); }
.guide-body ul, .guide-body ol { margin-top: var(--s-3); padding-left: 1.25rem; display: grid; gap: 0.4rem; }
.guide-body ul { list-style: disc; }
.guide-body ol { list-style: decimal; }
.guide-body li { list-style: inherit; font: 400 var(--t-base)/var(--lh-loose) var(--body); color: var(--ink-2); }
.guide-body a { color: var(--brand-ink); text-decoration: underline; text-underline-offset: 2px; }
.guide-body a:hover, .guide-body a:focus-visible { color: var(--brand); }
.guide-body strong { color: var(--ink); font-weight: 600; }
.guide-body code { font-family: var(--ui); background: var(--ground-2); padding: 0.1rem 0.3rem; border-radius: var(--r-1); font-size: 0.9em; }

/* The /help grid of guide cards. */
.help-grid { margin-top: var(--s-2); }
.guide-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.15rem; }
.guide-card {
  display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-3);
  padding: 1.05rem 1.05rem 0.95rem;
}
.guide-card-link { text-decoration: none; color: inherit; display: block; }
.guide-card-link:hover .guide-card-top h2,
.guide-card-link:focus-visible .guide-card-top h2 { text-decoration: underline; text-underline-offset: 2px; }
.guide-card-top { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
.guide-card-top h2 { font-size: var(--t-xl); }
.guide-card-top .ic { color: var(--brand); flex: none; }
.guide-card-note { margin-top: 0.6rem; font: 400 var(--t-sm)/var(--lh-body) var(--body); color: var(--ink-3); }

@media (max-width: 700px) {
  .amoe-brief, .amoe-facts { grid-template-columns: minmax(0, 1fr); }
  .amoe-checklist-head { grid-template-columns: minmax(0, 1fr); }
  .amoe-print-bar { justify-content: flex-start; }
}

@media print {
  @page { size: auto; margin: 0.55in; }
  .promise, .head, .foot, .skip-link, .amoe-print-bar, .crumb, .draft-banner { display: none !important; }
  body { background: var(--paper); }
  .amoe-checklist-main { max-width: none; padding: 0; }
  .amoe-checklist-head { display: block; }
  .amoe-checklist-head .eyebrow { color: var(--ink); }
  .amoe-checklist-head h1 { max-width: none; font-size: 24pt; }
  .amoe-checklist-head .lead { font-size: 10.5pt; }
  .amoe-sheet { margin-top: 18pt; padding: 0; border: 0; border-top: 3pt solid var(--ink); border-radius: 0; }
  .amoe-facts, .amoe-section, .amoe-note, .amoe-sources { break-inside: avoid; }
  .amoe-facts > div { padding: 8pt; }
  .amoe-instructions li { break-inside: avoid; padding-left: 25pt; }
  .amoe-instructions li::before { content: ''; width: 13pt; height: 13pt; border-color: var(--ink); background: transparent; }
  a { color: inherit; text-decoration: none; }
  .amoe-sources a::after { content: ' (' attr(href) ')'; font-size: 8pt; }
}


/* A state closed by statute rather than by the operator. Marked in words, not
   by colour alone, like every other state distinction on this site. */
.op-state-law {
  font-family: var(--ui); font-size: var(--t-2xs);
  text-transform: uppercase; letter-spacing: var(--tr-label);
  color: var(--ink-3);
}
