:root {
  --color-primary: #f8b00d;
  --color-primary-hover: #e5a000;
  --color-primary-text: #0c0c0b;
  --color-accent: #5bc0f8;
  --color-bg: #1c0323;
  --color-surface: #1c0323;
  --color-surface-alt: #320a3c;
  --color-text: #ffffff;
  --color-text-muted: #d8c8dc;
  --color-border: #612270;
  --color-header-bg: #1c0323;
  --color-button-outline: #612270;
  --color-testimonial-card-bg: #60216f;
  --color-footer-divider: #612270;
  --color-table-border: #612270;
  --font-heading: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --container: 1200px;
  --radius-sm: 4px;
  --radius-md: 12px;
  --header-h: 72px;
}

*, *::before, *::after { box-sizing: border-box; }

/* SG-071: .site-header is position: sticky; top: 0, so an in-page anchor (the Contents menu,
   or any external deep link) would land its target flush against the viewport top and hide it
   completely under the header. scroll-padding-top on the scrolling element reserves the header
   band for EVERY scroll into an anchor — native hash navigation included, so no JS is needed.
   --header-h is declared on :root (= this same element), and the 768px media query re-declares
   it as 64px there, so the reserved band follows the header on mobile by itself. */
html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 12px);
}

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--color-bg);
  color: var(--color-text);
  line-height: 1.65;
  font-size: 16px;
}

img { max-width: 100%; display: block; }

a { color: inherit; text-decoration: none; }

.container {
  width: min(var(--container), 100% - 32px);
  margin-inline: auto;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 9999;
  background: var(--color-primary);
  color: var(--color-primary-text);
  padding: 8px 16px;
}
.skip-link:focus { left: 16px; }

.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;
}

.section-tone-a { background: var(--color-surface); }
.section-tone-b { background: var(--color-surface-alt); }

/* SG-123: the internal page's reading column is a content section like any other, so it draws its
   vertical rhythm from THIS rule rather than from a private padding of its own — the two can no
   longer drift apart (that drift is what the client saw as "the internal page looks different").
   The column cannot simply BE the `.section`: `.legal-page` is one, and it has to keep `padding: 0`
   so its SG-124 hero stays flush under the header and full-bleed, so the padding lands one level in,
   on the container that holds the breadcrumbs, the Contents and the body.
   The `:not(.legal-page)` is load-bearing, not decoration. `.legal-page { padding: 0 }` alone did NOT
   hold: it has the same specificity as this rule, so the copy of it inside @media (max-width: 768px)
   — which comes later in the file — was winning, and the internal page's hero carried a 40px band
   above and below it on every phone. Excluding the article here makes the reset independent of
   source order, in this cascade and in every media block. */
.section:not(.legal-page),
.legal-page > .container { padding: 56px 0; }

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  line-height: 1.2;
  margin: 0 0 20px;
  color: var(--color-text);
}

h1 {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 5vw, 3.375rem);
  font-weight: 800;
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

h2 {
  font-size: 26px;
  font-weight: 500;
}

h3 {
  font-size: 20px;
  font-weight: 500;
}

h4 {
  font-size: 18px;
  font-weight: 700;
}

.section-text {
  color: var(--color-text);
  margin: 0 0 20px;
}

/* SG-123: `.legal-page-body` (the internal page's authored HTML, data-bind-html="legal-content")
   is the same kind of field as `.section-text` — arbitrary author markup — but it was never named
   in any of these rules, so its prose and its tables fell back to UA defaults while the identical
   HTML on the home page was styled. Every rule below is JOINED, never copied: one place still owns
   each decision, and the internal page can no longer drift away from the home page again. Note the
   field's own `.section-text { margin: 0 0 20px }` is deliberately NOT shared — the body is the last
   thing in its column and the column's own bottom padding already spaces it. */
.section-text p,
.legal-page-body p { margin: 0 0 16px; }

/* SG-008: universal html fields may carry lists directly; style them like the
   dedicated .bullet-list / .steps-list elements they replaced. */
.section-text ul,
.section-text ol,
.legal-page-body ul,
.legal-page-body ol {
  padding-left: 1.25rem;
  margin: 0 0 16px;
}

.section-text li,
.legal-page-body li { margin-bottom: 10px; }

/* SG-033: style raw <table> pasted into any .section-text html field, so wide
   tables never break the mobile layout (universal for arbitrary content). */
/* SG-049: .hero-desc renders author HTML too, so it gets the same table
   treatment — otherwise a pasted <table> overflows the hero on mobile. */
/* SG-067: the table must fill the content column. SG-033 made the table itself
   the scroll container, which meant taking it out of table layout; its rows then
   built an ANONYMOUS inner table that shrink-to-fits its content, so a two-column
   table drew at ~30% of the section and left the rest empty (and no width on the
   outer block could reach that anonymous box). It is a real table box again, at
   full width. The mobile guarantee moved one level out — see the two rules
   below — and is not lost. */
/* SG-123: `.legal-page-body` renders author HTML too — the client pasted a table into the bonuses
   page and got a bare, unstyled one. Joining it here (and into every rule below) gives it the whole
   SG-033/SG-049/SG-067 package at once: real table box, full column width, mobile scroll. */
.section-text table,
.hero-desc table,
.legal-page-body table {
  display: table;
  width: 100%;
  /* Redundant next to width: 100% in the normal case, kept on purpose as
     insurance against author HTML that hard-codes a width inline
     (<table style="width:900px">) — inline styles outrank this rule's width,
     and then max-width is the only thing left holding the table in the column. */
  max-width: 100%;
  border-collapse: collapse;
  margin: 0 0 16px;
  font-size: 15px;
}

/* SG-067: the scroll container is now the html field, and only when it actually
   holds a table — putting overflow on every field would turn each one into a
   block formatting context and change margin collapsing for plain prose. A table
   too wide to fit (many columns) therefore scrolls inside its own column instead
   of pushing the page sideways, exactly as under SG-033. */
.section-text:has(table),
.hero-desc:has(table),
.legal-page-body:has(table) {
  overflow-x: auto;
}

/* SG-067: that overflow makes the field a block formatting context, so the last
   child's 16px bottom margin no longer collapses into the field's own 20px — a
   table-bearing .section-text would grow 20px → 36px below. Zeroing the last
   child restores the old gap (every child here has margin-top: 0, so nothing
   above moves). Scoped by the same :has(table) as the rule that causes it, so
   the compensation can never apply without the BFC or vice versa — including in
   browsers that do not support :has at all. .hero-desc already does this
   unconditionally (see `.hero-desc > :last-child` below), and SG-123 gave
   .legal-page-body the same unconditional treatment for a different reason
   (its own bottom margin never collapsed with anything: the column's padding
   sits below it), so neither needs the conditional form. */
.section-text:has(table) > :last-child {
  margin-bottom: 0;
}

.section-text table th,
.section-text table td,
.hero-desc table th,
.hero-desc table td,
.legal-page-body table th,
.legal-page-body table td {
  padding: 12px 16px;
  text-align: left;
  vertical-align: top;
  /* SG-067: first line of defence on narrow screens. `anywhere` (unlike
     `break-word`) lowers each cell's MIN-CONTENT width, so an ordinary 2-4 column
     table wraps its text down to the viewport instead of overflowing, and long
     unbreakable tokens (urls, hashes) break rather than widen a column. */
  overflow-wrap: anywhere;
  border: 1px solid color-mix(in srgb, var(--color-table-border) 45%, transparent);
}

.section-text table th,
.hero-desc table th,
.legal-page-body table th {
  background: rgba(0, 0, 0, 0.15);
  font-weight: 600;
}

.section-text table thead th,
.hero-desc table thead th,
.legal-page-body table thead th {
  background: rgba(0, 0, 0, 0.25);
}

.section-text table caption,
.hero-desc table caption,
.legal-page-body table caption {
  caption-side: top;
  text-align: left;
  color: var(--color-text-muted);
  font-size: 14px;
  margin-bottom: 8px;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-header-bg);
  min-height: var(--header-h);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--header-h);
  gap: 16px;
  padding: 12px 0;
}

.header-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}

.header-nav:empty { display: none; }

.header-nav-item {
  display: inline-block;
  padding: 8px 10px;
  border-radius: 8px;
  color: var(--color-text);
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
}

.header-nav-item:hover {
  background: rgba(255, 255, 255, 0.06);
  text-decoration: none;
}

.header-nav-item.active { color: var(--color-primary); }

/* SG-208: doubled for the reason the media block below is — see SG-207's note there. [[SG-207]]
   repaired the hide rule, whose bare `.header-lang-switcher` (0-1-0) had been racing
   `.lang-switcher` (0-1-0, ~980 lines down) and losing on document order; this line is that rule's
   twin, 24 lines above it, and was left bare. It gets away with it today only because the two
   declare nothing in common — `flex-shrink` here against `display`/`justify-content` there — and a
   browser resolves the cascade per property, so neither has ever had to lose. Measured, not read:
   tests/footer-flag-link-cascade.test.js's sweep listed exactly this pair as a tie. The intended winner
   is not in doubt (a rule qualifying ONE surface's copy of the widget must outrank the widget's
   generic rule), so it is stated as weight — `.header-lang-switcher.lang-switcher` is 0-2-0 —
   rather than left to which line happens to sit lower. */
.header-lang-switcher.lang-switcher { flex-shrink: 0; }

@media (max-width: 900px) {
  /* SG-207: the second selector is doubled to WIN, not to read nicely.
   *
   * The element the runtime puts in the header menu is `<nav class="lang-switcher
   * header-lang-switcher">` (public/script.js createLangSwitcherNav — `.header-lang-switcher` is the
   * only thing it adds, and shared/site-menu.js adds it for the sake of this very rule). Written as
   * a bare `.header-lang-switcher` this hide weighed 0-1-0, exactly what `.lang-switcher
   * { display: flex }` ~900 lines below weighs, and an equal-weight tie goes to whichever rule sits
   * LATER in the file. So the hide lost at every width and resolved to `flex`: a rule that read as
   * working and did nothing. `.header-lang-switcher.lang-switcher` is 0-2-0 and outweighs it
   * instead of racing it — deliberately not fixed by moving this block below `.lang-switcher`, which
   * would win on the same document order that just failed and would file the header's rules 900
   * lines away from the header.
   *
   * It cost nothing to leave broken and still had to be fixed: `.header-nav` on the line above hides
   * the switcher's PARENT at these widths and is not overridden later, and `display: none` takes the
   * subtree with it, so nothing was ever wrongly on screen. What was wrong is that three places —
   * shared/site-menu.js's `langClass`, and two cases in tests/header-nav.test.js — say this class is
   * what makes the header switcher desktop-only, and until now it was not. The alternative outcome
   * (delete the rule, note that the parent is the only mechanism) would have meant demoting all
   * three. Verified in Chrome on the customer's export with `.header-nav` forced visible, so this
   * rule is the only thing left holding the switcher back: gone at 360…900px, still there at
   * 901…1440px. Pinned by tests/header-switcher-desktop-only.test.js, which also pins the doubled
   * selector's one premise — that both classes really are on the element. */
  .header-nav,
  .header-lang-switcher.lang-switcher { display: none; }
}

.burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 0;
  background: transparent;
  color: var(--color-text);
  cursor: pointer;
  margin-left: auto;
}

.burger svg { width: 24px; height: 24px; }

.mobile-nav-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease;
  z-index: 200;
}

.mobile-nav-overlay.visible {
  opacity: 1;
  visibility: visible;
}

.mobile-nav {
  position: fixed;
  top: 0;
  right: 0;
  width: min(320px, 88vw);
  height: 100%;
  background: var(--color-header-bg);
  transform: translateX(100%);
  transition: transform 0.25s ease;
  z-index: 201;
  box-shadow: -8px 0 24px rgba(0, 0, 0, 0.25);
}

.mobile-nav.open { transform: translateX(0); }

.mobile-nav-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 40px;
  height: 40px;
  border: 0;
  background: transparent;
  color: var(--color-text);
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
}

.mobile-nav-inner {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 64px 20px 24px;
}

.mobile-nav-item {
  display: block;
  padding: 12px 14px;
  border-radius: 8px;
  color: var(--color-text);
  text-decoration: none;
}

.mobile-nav-item:hover { background: rgba(255, 255, 255, 0.06); }

.mobile-nav-item.active { color: var(--color-primary); }

/* SG-206: the language switcher is a menu ENTRY of this drawer, so it gets the entry's box.
 *
 * WHY IT NEEDED SAYING AT ALL. Every other entry in the drawer is printed by the static half and
 * carries `.mobile-nav-item`; the switcher is the one element with no static half ([[SG-182]],
 * boundary accepted in [[SG-186]]) — the runtime appends a bare `<nav class="lang-switcher">` into
 * this same column (renderMenuSlot, `burger` surface, langClass ""). So it inherited nothing of the
 * entry box and fell back to the generic `.lang-switcher` rules. Those DO state a horizontal
 * alignment unconditionally — `justify-content: flex-start` — but that is the flex default and
 * moved nothing; the only declaration that ever displaced the flag was the FOOTER's
 * `@media (max-width: 640px) { justify-content: center }`, which reached this element too because
 * the two share the class. Hence a flag that moved with the width while the labels above it
 * did not. (Spelled out because the first draft of this comment called the footer rule the only
 * horizontal statement at all, which is wrong as an inventory — SG-206 review.)
 *
 * The declarations below are not new numbers: `12px 14px` is `.mobile-nav-item`'s own padding,
 * repeated here because the two elements have no shared class to hang it on. What that buys,
 * measured in Chrome on the customer's preset with the drawer open (`.mobile-nav-inner` gap 4px,
 * entry box 50.4px tall):
 *   - horizontally, flag-left − item-text-left goes from +115.5px (≤640) / −8.5px (>640) to 0.0px
 *     at every width the burger shows. The −8.5px is why `justify-content: flex-start` alone was
 *     not the fix: the 21px flag sits centred in a 32px tap target (`.lang-switcher-item a`), so
 *     flush-left aligns the TARGET, not the flag. Aligning the anchor's content left edge instead
 *     puts the visible flag on the labels' vertical.
 *   - vertically, the switcher's box now advances the column by the same 54.4px stride as one
 *     entry, and the optical gap from "Mobile Version" to the flag goes from 41.2px to 53.2px
 *     against the 54.4px that separates two labels — the 1.2px residue is the flag being 24px tall
 *     against a 26.4px line box, and is not worth a second magic number.
 *
 * The desktop switcher is untouched: it is `.header-lang-switcher` in `.header-nav`, and this
 * container exists only inside the drawer, which only opens at ≤900px. */
.mobile-nav-inner .lang-switcher {
  justify-content: flex-start;
  /* `.mobile-nav-item`'s padding verbatim — that is the whole point of the rule. */
  padding: 12px 14px;
  /* …except on the left, where it is that same 14px minus the 1px transparent border
     `.lang-switcher-item a` carries for its active state (SG-038). With the border counted in the
     flag landed 1px right of the labels; spelled as a subtraction rather than as "13px" so the two
     facts stay legible when either of them moves. */
  padding-left: calc(14px - 1px);
}

.mobile-nav-inner .lang-switcher-item a {
  justify-content: flex-start;
}

/* SG-161: a marked entry is the page you are on and its click is prevented (shared/nav-current.js
   markNavCurrent), so it must not offer a pointer that promises a navigation. `aria-disabled` is
   the attribute that carries the fact; the selector reads it rather than the class, so anything
   marked that way is covered and nothing merely styled `.active` (the language switcher's own
   convention, which stays clickable) is caught by it.
   SG-208: the footer selector is `> li > a` for the same reason its three neighbours down at
   `.footer-links-list > li > a` are — the list holds the switcher widget as well as its entries,
   and only the entries are ever marked. */
.header-nav-item[aria-disabled="true"],
.mobile-nav-item[aria-disabled="true"],
.footer-links-list > li > a[aria-disabled="true"] {
  cursor: default;
}

body.menu-open { overflow: hidden; }

@media (max-width: 900px) {
  .burger { display: inline-flex; }
  /* SG-074 review: renderMobileNav marks the burger [hidden] when the header menu it
     mirrors is empty. Without this rule the `display: inline-flex` above would beat the
     UA stylesheet's [hidden] and keep showing a button that opens a blank drawer. */
  .burger[hidden] { display: none; }
}

.brand {
  display: flex;
  align-items: center;
  gap: 0;
  color: var(--color-text);
  text-decoration: none;
  flex-shrink: 0;
}

.brand-logo {
  height: 30px;
  width: auto;
}

.brand-logo:not([src]), .brand-logo[src=""] { display: none; }

.brand:has(.brand-logo[src]:not([src=""])) .brand-name { display: none; }

.brand-name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.25rem;
  text-transform: uppercase;
}

.brand-name:empty { display: none; }

.header-actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
}

/* SG-058: only guard the buttons against the centred nav on desktop. Below
   900px the nav is hidden, so keeping flex-shrink:0 there would combine with
   the 768px flex-wrap:nowrap and let long button labels overflow the viewport. */
@media (min-width: 901px) {
  .header-actions { flex-shrink: 0; }
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.2s, background 0.2s, box-shadow 0.2s;
  line-height: 1;
}

.btn-lg {
  font-family: var(--font-display);
  font-size: 19px;
  padding: 14px 34px;
  border-radius: var(--radius-sm);
}

.btn-primary {
  background: var(--color-primary);
  color: var(--color-primary-text);
  border-color: var(--color-primary);
}

.btn-primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
  text-decoration: none;
}

.btn-outline {
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px double var(--color-button-outline);
}

.btn-outline:hover {
  border-color: var(--color-primary);
  text-decoration: none;
}

.btn-animate-pulse { animation: btnPulse 1.5s ease-in-out infinite; }
.btn-animate-blink { animation: btnBlink 1s step-start infinite; }
.btn-animate-glow { animation: btnGlow 1.5s ease-in-out infinite; }
.btn-animate-shake { animation: btnShake 0.6s ease-in-out infinite; }

@keyframes btnPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.04); }
}
@keyframes btnBlink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
@keyframes btnGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(248, 176, 13, 0.55); }
  50% { box-shadow: 0 0 24px 4px rgba(248, 176, 13, 0.35); }
}
@keyframes btnShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-3px); }
  75% { transform: translateX(3px); }
}

.hero-block {
  position: relative;
  overflow: hidden;
  background: #fff359;
  padding: 24px 0 0;
}

.hero-bg-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center right;
  pointer-events: none;
  z-index: 0;
}

/* SG-159: `[hidden]` has to actually hide it. The `img { display: block }` reset at the top of this
   file OUTRANKS the UA sheet's `[hidden] { display: none }` — author origin beats UA origin whatever
   the specificity — so a hero whose background image is not set kept a src-less <img> in the layout,
   absolutely positioned over the whole hero box. Chrome paints a src-less <img> as its broken-image
   placeholder: a 1px light frame, which is the hairline that appeared around every internal page's
   hero. It was there all along and invisible on the old yellow `#fff359`; SG-158's dark surface is
   what revealed it. The frame is drawn by a CHILD at z-index 0, which is why nothing on `.hero-block`
   itself — outline, box-shadow, a flat vs gradient background — could cover it.
   Same shape as `.burger[hidden]` above, for the same reason. Both heroes share the class, so this
   fixes the home page's empty state too; the runtime and the export both toggle exactly this
   attribute (script.js renderHero / renderPageHero), so an authored background is untouched. */
.hero-bg-image[hidden] { display: none; }

/* SG-072: readability scrim over the hero background image. It sits on its own
   level between .hero-bg-image (z-index 0) and .hero-layout (z-index 2) rather
   than relying on ::after being painted last: a future positioned child of
   .hero-block that must NOT be dimmed can then be given z-index 2, which tree
   order alone would not allow.
   The colour is a DARK grey, not a mid grey: a mid-grey film at 30% lightens the
   dark parts of a photo, which drops the contrast of the white hero text exactly
   where the text was already hardest to read. A dark grey only ever darkens.
   Gated on an actually-visible background image: with no hero.backgroundImage the
   runtime leaves the <img> [hidden] (script.js renderHero; the export injects a
   src and drops the attribute only when there is one), and the hero falls back to
   a flat brand colour that must not be dimmed. */
.hero-block:has(.hero-bg-image:not([hidden]))::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(26, 26, 26, 0.3);
  pointer-events: none;
}

.hero-bg {
  display: none;
}

/* SG-050: hero content spans the full container width and is centered; the
   mascot/decor now lives inside the full-bleed background image instead of a
   dedicated right-hand column. */
.hero-layout {
  position: relative;
  /* SG-072: 2, not 1 — the readability scrim occupies level 1. Nothing else on the
     page sits between 1 and 100, so raising this does not reorder it against anything. */
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr;
  justify-items: center;
  align-items: center;
  text-align: center;
  min-height: 520px;
  padding: 24px 0 40px;
}

.hero-content {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  padding: 70px 40px;
  text-align: center;
}

.hero-desc {
  margin: 0 0 20px;
  color: var(--color-text);
  font-size: 16px;
}

/* SG-049: hero.description is an HTML field rendered into a <div>, so it may
   carry block-level markup. Keep the old single-paragraph rhythm and drop the
   trailing margin so the CTA spacing stays identical to the plain-text case. */
.hero-desc p { margin: 0 0 16px; }

.hero-desc ul,
.hero-desc ol {
  padding-left: 1.25rem;
  margin: 0 0 16px;
}

.hero-desc li { margin-bottom: 10px; }

/* SG-123: `.legal-page-body` joins this rule instead of taking the `:has(table)` variant that
   `.section-text` needs. Its own bottom margin is 0 and its column's 56px bottom padding sits
   below it, so the last child's 16px margin never collapses away — it is simply added, table or
   no table. Zeroing it unconditionally is what makes an internal page end with the same gap
   whatever its last element happens to be. */
.hero-desc > :last-child,
.legal-page-body > :last-child { margin-bottom: 0; }

.hero-cta-wrap { margin-bottom: 16px; }

/* SG-050: the separate mascot column is retired (markup kept for binding
   compatibility). Hidden at every breakpoint. */
.hero-visual {
  display: none;
}

/* SG-122: breadcrumbs, in the place (and the visual language) of the removed
   `.legal-page-back` link — same top margin, same primary-coloured link, same hover. */
.breadcrumbs {
  margin: 0 0 24px;
}
.breadcrumbs-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.9375rem;
}
.breadcrumbs-item {
  display: flex;
  align-items: center;
  gap: 6px;
}
/* The separator is decoration, never a text node: both render halves print the crumb's
   name and nothing else, so their rendered text compares equal character for character. */
.breadcrumbs-item + .breadcrumbs-item::before {
  content: "/";
  opacity: 0.5;
}
.breadcrumbs-item a {
  color: var(--color-primary);
  text-decoration: none;
  font-weight: 600;
}
.breadcrumbs-item a:hover {
  text-decoration: underline;
}
.breadcrumbs-current {
  opacity: 0.75;
}
.legal-page-body h1:first-child {
  margin-top: 0;
}

/* SG-124: the reading column moved off the <article> and onto the .container inside it, so the
   internal page's hero (a sibling of that container) can span the full viewport the way the home
   page's does. `.seo-static-main` keeps the original standalone rule: it is the SSG fragment shell,
   it has no hero and no inner container to move the box onto.
   SG-123: that column's own `max-width: 900px` is gone. It was a second, narrower cap stacked on
   top of the `.container` the column already is, and with `--container` at 1200px it is what made an
   internal page read as a thin strip next to the home page ("huge margins on the sides" — the
   client, on the bonuses page). Removed, the column is `width: min(var(--container), 100% - 32px)`
   and nothing else: character for character the box every home-page section gets. Vertical padding
   likewise — see the `.section` rule above, which this column now shares.
   On the side gutter, for the record, because SG-124's review flagged it: the internal page's side
   gutter is the site-wide `.container` one, 16px and 12px under 768px. The 24px it had before was
   `padding: 40px 24px` on the <article>, INSIDE the container's own gutter — a 40px total inset that
   only internal pages had. SG-124 dropped it when it moved the box; that is the right answer and it
   is deliberately not restored here, because 24px is precisely the extra side margin the client
   asked to remove, and putting it back would un-match the home page this task exists to match.
   `.legal-page` itself keeps `padding: 0` (it carries the `section` class): the hero must sit flush
   under the header and bleed to both edges, so no padding may live on the article. That reset is
   now belt-and-braces — the `.section` rule excludes `.legal-page` outright, because on its own this
   declaration lost to the mobile copy of `.section` and put a 40px band around the hero on phones. */
.legal-page {
  padding: 0;
  color: var(--color-text);
  line-height: 1.6;
}

.seo-static-main {
  max-width: 900px;
  margin: 0 auto;
  padding: 40px 24px;
  color: var(--color-text);
  line-height: 1.6;
}

/* The hero of an internal page. `.hero-block` supplies the scrim and the stacking context; the
   background is overridden right below. This rule only guarantees the block disappears when it is
   [hidden] — `.hero-block` sets no `display`, so the UA rule would already do it, but a future
   display on that class must not resurrect an empty band on every page that authored no hero. */
.page-hero[hidden] { display: none; }

/* The internal page's hero sits on "Color 2" when it has no background image of its own — the same
   surface the Table section takes on the home page (`contentBlocks` defaults to tone "b",
   shared/section-order.js DEFAULT_SECTION_TONES, painted by `.section-tone-b` above). It inherits
   `.hero-block`, whose flat `#fff359` is the HOME hero's brand yellow, and that yellow read as an
   unstyled band behind every internal page's title (client, 2026-07-31).

   The token, not the literal: `--color-surface-alt` is what `.section-tone-b` paints with, so a
   brand that re-themes its surfaces moves this hero with the rest of them instead of keeping one
   hard-coded colour. Same class specificity as `.hero-block` (0,1,0) — this wins on source order,
   which is why it must stay BELOW that rule.

   Only the flat fallback is affected. `hero.backgroundImage` renders as a separate <img> painted
   over this background (`.hero-bg-image`, z-index 0), so a page that authored one looks exactly as
   it did, scrim included. */
.page-hero { background: var(--color-surface-alt); }

/* SG-124: the internal page's Contents. No tone class and no background on purpose — the client
   asked for the background to cover the hero ONLY, so this block and the body below it sit on the
   page's own surface. The list itself reuses .toc-list / .toc-item / .toc-link from the home page. */
.page-toc {
  margin: 0 0 32px;
}

.page-toc[hidden] { display: none; }

.page-toc-title {
  margin: 0 0 16px;
}

.legal-page h1,
.legal-page h2,
.legal-page h3 {
  color: var(--color-text);
}

.seo-static-header {
  padding: 16px 24px;
  background: var(--color-header-bg, #1c0335);
}

.seo-static-header a {
  color: var(--color-primary);
  text-decoration: none;
  font-weight: 700;
}

.seo-static-back {
  max-width: 900px;
  margin: 0 auto 40px;
  padding: 0 24px;
}

.seo-static-back a {
  color: var(--color-primary);
}

/* SG-068: .bullet-list is gone — its last generator was renderContentBlocks, removed with the
   block list. Lists inside a universal html field are styled by the .section-text rules. */

.games-featured {
  padding-top: 48px;
  padding-bottom: 20px;
}

.games-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 5px 3px;
  min-height: 325px;
  align-items: center;
}

.flip-box {
  perspective: 1000px;
  aspect-ratio: 275 / 413;
  display: block;
  color: inherit;
  text-decoration: none;
}

.flip-box-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform 0.5s ease;
  transform-style: preserve-3d;
}

.flip-box:hover .flip-box-inner { transform: rotateY(180deg); }

.flip-box-front,
.flip-box-back {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border-radius: 10px;
  overflow: hidden;
}

.flip-box-front {
  background: #320a3c;
  border: none;
}

.flip-box-front img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.flip-box-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  text-align: center;
  font-size: 13px;
  color: var(--color-text-muted);
}

.flip-box-back {
  transform: rotateY(180deg);
  background-color: #00194c;
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 16px;
  text-align: center;
}

/* SG-175: the slot name is a caption (div.flip-box-title), no longer an h3. The declarations are
   carried over unchanged so the card looks exactly as before — `margin: 0` and the explicit size /
   weight are now belt-and-braces rather than heading resets, but removing them would change the
   rendering, since a div would otherwise fall back to the inherited body font. */
.flip-box-back .flip-box-title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
}

.flip-box-back .btn {
  font-size: 12px;
  padding: 10px 18px;
}

/* SG-068: the .content-block article list is gone — the Table section renders one
   h2 + .section-text pair, styled by the shared .section / .section-text rules. */

.testimonials-grid {
  max-width: 1117px;
  margin: 24px auto 0;
}

.testimonials-track {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  align-items: stretch;
}

.testimonial-card {
  background: var(--color-testimonial-card-bg);
  border: none;
  border-left: 3px solid var(--color-primary);
  border-radius: 10px;
  padding: 30px 20px 24px;
  min-height: 100%;
}

.testimonial-author {
  font-weight: 700;
  margin-bottom: 8px;
}

.testimonial-stars {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 12px;
}

.star-icon {
  display: inline-flex;
  width: 18px;
  height: 18px;
}

.star-icon svg {
  width: 100%;
  height: 100%;
  fill: var(--color-primary);
}

.star-icon.star-empty svg {
  fill: rgba(248, 176, 13, 0.25);
}

.star-icon.star-half svg {
  fill: var(--color-primary);
  clip-path: inset(0 50% 0 0);
}

.testimonial-text {
  color: var(--color-text);
  font-style: italic;
  margin: 0;
}

.bonus-welcome {
  margin: 24px 0 32px;
}

.bonus-welcome-body ul,
.bonus-welcome-body ol {
  padding-left: 1.25rem;
}

.bonus-section {
  margin-bottom: 32px;
}

.bonus-section:last-child { margin-bottom: 0; }

.site-toast {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 1000;
  max-width: min(360px, calc(100vw - 48px));
  padding: 14px 18px;
  border-radius: 12px;
  background: var(--color-surface-alt, #320a3c);
  color: var(--color-text, #fff);
  border: 1px solid var(--color-border, #612270);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
  font-size: 0.95rem;
  line-height: 1.4;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.25s ease, transform 0.25s ease;
  pointer-events: none;
}

.site-toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.steps-list {
  padding-left: 1.25rem;
  margin: 0;
}

.steps-list li { margin-bottom: 10px; }

.faq-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-top: 12px;
}

.faq-item {
  padding: 15px;
  background: transparent;
}

/* SG-172: the question is now `h3.faq-question-heading > button.faq-question`. The h3 is a pure
   wrapper that exists to keep the heading level in the accessibility tree, so it must contribute
   none of its own box: an h3 brings a 1em block margin and a larger, bolder font, neither of which
   the old single element had (`.faq-question` reset them on itself). */
.faq-question-heading {
  margin: 0;
  font: inherit;
}

.faq-question {
  width: 100%;
  text-align: left;
  padding: 0;
  margin: 0;
  background: transparent;
  border: none;
  color: var(--color-primary);
  font: inherit;
  font-size: 18px;
  font-weight: 500;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}

.faq-item.open .faq-question {
  color: var(--color-accent);
}

.faq-toggle-icon {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.faq-toggle-icon svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

.faq-icon-open { display: none; }
.faq-item.open .faq-icon-closed { display: none; }
.faq-item.open .faq-icon-open { display: block; }

.faq-answer {
  display: none;
  padding: 12px 0 0;
  color: var(--color-text-muted);
}

.faq-item.open .faq-answer { display: block; }

.sportsbook-features ul {
  padding-left: 1.25rem;
  margin: 0;
}

.sportsbook-features li { margin-bottom: 10px; }

.site-footer {
  padding: 48px 0 32px;
  border-top: 1px solid color-mix(in srgb, var(--color-footer-divider) 45%, transparent);
}

.footer-inner {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.footer-top {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.footer-col {
  min-width: 0;
}

.footer-brand-col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}

.footer-brand .brand-logo {
  height: 30px;
}

.footer-links-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  /* SG-058 made the list a row (it used to be a column) and spread it with
     space-between to fill the width. SG-074 keeps the row but replaces the spread
     with flex-end: the customer reads the wide gaps as the links falling apart, so
     they now sit as one compact group pushed to the right edge of the .footer-top
     `auto minmax(0, 1fr)` grid's second column, opposite the brand. Deliberate
     revision of SG-058's choice, not a regression. */
  justify-content: flex-end;
  gap: 10px 24px;
}

/* SG-208: `> li > a` is the list's own ENTRIES, and that is all these three rules were ever about.
 *
 * The footer's menu entries are `<li><a href>…</a></li>` — shared/site-menu.js's footer surface,
 * `wrap: "li"` with `itemClass: ""`, so the anchors carry no class and the list has to reach them by
 * tag. Written as a descendant `.footer-links-list a`, that reach did not stop at the entries: the
 * language switcher is a WIDGET the runtime drops into a `<li class="footer-lang-item">` of the same
 * list, and its flag link sits four levels below (`li.footer-lang-item > nav.lang-switcher >
 * ul.lang-switcher-list > li.lang-switcher-item > a`). So this rule and `.lang-switcher-item a` —
 * both 0-1-1, 81 lines apart in this file and thirteen rules apart in the cascade — both landed on
 * that link, and which of them won was decided by which sits lower in the file, not by intent.
 *
 * Nothing was wrong on screen: the two declare disjoint properties (`color`/`text-decoration` here,
 * the 32×24 tap target there) and a browser resolves the cascade per PROPERTY, so the flag took its
 * box from the switcher and its colour from here and neither ever had to lose. It is a fault about
 * what happens next — the day either grows a property the other already has, the winner flips to
 * whatever the file order happens to be. Third in a row for this widget after [[SG-206]] (a footer
 * rule was the burger drawer's flag alignment, and the customer saw the flag jump 124px across a
 * breakpoint) and [[SG-207]] (the header's hide rule had lost the same race since it was written),
 * which is why a latent one was worth closing.
 *
 * The line drawn here is not "the footer may not style the widget" — it may, and does: the 640px
 * block below centres the switcher's `<nav>` with the rest of the column, because WHERE a widget
 * sits inside a surface is the surface's business. What the footer has no business doing is dressing
 * the widget's insides, and it was not trying to; the anchor was simply in reach.
 *
 * What the scoping costs, resolved against the booted document rather than eyeballed
 * (tests/footer-flag-link-cascade.test.js): at rest, nothing — the flag link falls back to
 * `a { color: inherit; text-decoration: none }`, every ancestor from `body` down leaves `color`
 * unset, so `inherit` is `body`'s own `var(--color-text)`, the same value it had. On hover, one
 * deliberate change: the flag no longer turns `var(--color-primary)` and now hovers exactly like the
 * header's and the drawer's do (`opacity: 1`, SG-038's affordance for this widget) — visible only
 * when the operator turns flags off and the link renders the locale label as text. */
.footer-links-list > li > a {
  color: var(--color-text);
  text-decoration: none;
}

.footer-links-list > li > a:hover {
  color: var(--color-primary);
}

/* SG-161: the footer's copy of a menu entry gets the same "you are here" treatment as the header's
   and the drawer's — the entry pointing at the page being read is marked and does not navigate.
   The footer anchors carry no base class of their own, so `.active` is matched on its own here.
   SG-208 scoped it with its two neighbours: the marking is written by renderMenuEntryHtml onto
   entry anchors only, and the switcher's own `.active` sits on its `<li>`, so this never reached
   the flag link — but leaving one of the three rules able to would be leaving the next reader to
   work out which. */
.footer-links-list > li > a.active { color: var(--color-primary); }

.footer-divider {
  height: 1px;
  background: color-mix(in srgb, var(--color-footer-divider) 45%, transparent);
}

.footer-bottom {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  align-items: center;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 24px;
  justify-content: center;
}

.footer-links a {
  color: var(--color-text);
  text-decoration: underline;
}

.footer-copy,
.footer-email {
  color: var(--color-text-muted);
  font-size: 14px;
  margin: 0;
}

.footer-email {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  text-decoration: none;
}

.footer-email:hover {
  color: var(--color-primary);
}

.footer-email-icon {
  width: 16px;
  height: 16px;
  fill: currentColor;
  flex-shrink: 0;
}

.lang-switcher {
  display: flex;
  justify-content: flex-start;
}

.lang-switcher-list {
  display: flex;
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.lang-switcher-item a {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  width: 32px;
  height: 24px;
  padding: 0;
  border-radius: 3px;
  overflow: hidden;
  border: 1px solid transparent;
  opacity: 0.72;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  transition: opacity 0.2s, border-color 0.2s;
}

.lang-switcher-item a:hover {
  opacity: 1;
  text-decoration: none;
}

.lang-switcher-item.active a {
  opacity: 1;
  border-color: var(--color-primary);
}

.lang-switcher-item img {
  width: 21px;
  height: 15px;
  object-fit: cover;
  display: block;
}

[data-section].hidden,
.hidden { display: none !important; }

@media (max-width: 1100px) {
  .games-grid { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 900px) {
  /* SG-050: layout is single-column and centered at every width now; mobile
     only relaxes the vertical rhythm and the horizontal padding. */
  .hero-layout {
    min-height: auto;
  }

  .hero-content {
    padding: 20px 0;
    max-width: none;
  }

  .games-grid { grid-template-columns: repeat(3, 1fr); }

}

@media (max-width: 768px) {
  :root { --header-h: 64px; }

  .container { width: min(var(--container), 100% - 24px); }

  /* SG-123: keeps the internal page's reading column on the section rhythm here too — and keeps
     the article itself out of it, see the unconditional rule for why the exclusion is repeated. */
  .section:not(.legal-page),
  .legal-page > .container { padding: 40px 0; }

  .games-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }

  .header-inner {
    padding: 8px 0;
    gap: 10px;
  }

  .brand-logo { height: 26px; }

  .header-actions {
    gap: 8px;
    flex-wrap: nowrap;
  }

  .header-actions .btn {
    padding: 10px 12px;
    font-size: 11px;
  }

  .btn { padding: 12px 14px; font-size: 12px; }
}

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

  .footer-top,
  .footer-bottom {
    grid-template-columns: 1fr;
    text-align: center;
  }

  .footer-brand-col,
  .footer-email {
    justify-content: center;
    align-items: center;
  }

  .footer-links-list {
    justify-content: center;
  }

  /* SG-206: scoped to the FOOTER list, where the centering belongs. It used to read
     `.lang-switcher` bare, and the switcher the burger drawer renders is the same element with
     the same class — so this footer rule was the drawer's alignment too, and it flipped at 640px
     while nothing else in the drawer did. Measured on the customer's preset (CoolzinoCasino,
     one visible flag) with the drawer open, flag-left minus item-text-left:
       360/390/430/540px → +115.5px (centered in the 280px column)
       660/720/768/880px → −8.5px  (flush left, inside the items' 14px padding)
     i.e. the flag jumped 124px sideways across the breakpoint while "Boni" & co. never moved.
     That is the "пляшет" in the ticket. The drawer's own alignment is stated unconditionally
     next to .mobile-nav-item instead — see there. */
  .footer-links-list .lang-switcher {
    justify-content: center;
  }
}

@media (max-width: 480px) {
  .games-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
}

/* SG-071: "Contents" — the anchor menu of the page's own headings.
   One FLAT <ol>: the numbering has to run 1..N straight through the bonuses sub-entries
   (a nested <ol> would restart at 1), so the second level is drawn by the indent on
   .toc-item-sub rather than by real nesting. */
.toc-list {
  margin: 0;
  padding-left: 22px;
  max-width: 760px;
  list-style: decimal;
  color: var(--color-text-muted);
}

.toc-item {
  margin: 0 0 10px;
  padding-left: 4px;
}

.toc-item:last-child { margin-bottom: 0; }

.toc-item-sub { margin-left: 26px; }

.toc-link {
  color: var(--color-text);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.toc-link:hover,
.toc-link:focus-visible { color: var(--color-primary); }

@media (max-width: 640px) {
  .toc-item-sub { margin-left: 14px; }
}
