/* Skip link */

.skip-link {
  position: absolute;
  top: -3rem;
  left: var(--space-3);
  z-index: 100;
  padding: var(--space-2) var(--space-3);
  background: var(--color-ink);
  color: var(--color-white);
  border-radius: var(--radius-sm);
  transition: top var(--transition-fast);
}

.skip-link:focus {
  top: var(--space-2);
}

/* Header — see PROJECT.md for the full navigation-redesign writeup:
   the 1200px breakpoint, curated dropdown lists, and the pageExists /
   pickProviders filters this markup depends on. */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  /* Barely-there depth so the sticky header reads as "above" scrolled
     content rather than sitting flush with it — not a heavy shadow. */
  box-shadow: var(--shadow-sm);
}

.site-header__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* Tightened from space-4 — with Login/Register/language/hamburger all
     sharing one row below the desktop breakpoint, the wider gap left no
     room at 320px. Still a real, deliberate gap (16px), not a squeeze. */
  gap: var(--space-3);
  /* Tightened from space-3 — this is the main "flatter header" lever:
     the interactive controls themselves (buttons, hamburger) keep their
     own 44px touch-target height regardless, only the air around them
     shrinks. */
  padding-block: var(--space-2);
}

.site-logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--color-ink);
  text-decoration: none;
  flex-shrink: 0;
}

.site-logo__image {
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
}

/* Wordmark hides below the desktop breakpoint — the mark alone plus
   Login/Register/hamburger already fills a 320px bar comfortably; adding
   the full "Winbox Online" text back in at that width is what forces
   the cramped/overflowing layout this header used to have. The link's
   own aria-label (see header.njk) keeps the accessible name either way,
   so hiding this text never removes a label — only a visual duplicate
   of one. */
.site-logo__text {
  display: none;
}

@media (min-width: 1200px) {
  .site-logo__text {
    display: inline;
  }
}

/* Mobile/tablet-only compact header — noticeably flatter than desktop,
   per explicit request. Real height/padding reductions (not
   transform: scale, which would blur the logo and SVG icons) — the
   individual controls below (buttons, language trigger, hamburger)
   get their own smaller real dimensions further down this file.
   Desktop is untouched: this block only matches <1200px, and neither
   selector here is set again anywhere else in the file, so there's no
   later-unconditional-rule source-order risk (see PROJECT.md). The logo
   stays at its base 2rem size here (no override) — at 32px it's still
   well under the 40px control row height, so it doesn't push the
   header taller; a smaller 1.75rem mobile-only size was tried and
   reverted per direct feedback that it read as too small. */
@media (max-width: 1199.98px) {
  .site-header__bar {
    padding-block: 0.375rem;
  }
}

/* Nav-panel section labels ("Browse" / "Access") — mobile only; the
   desktop bar doesn't need them since each group reads as its own row. */
.nav-panel__label {
  display: none;
}

/* Primary navigation — visible and usable with no JavaScript: every
   dropdown is a native <details>, which opens on click with zero JS in
   any browser, at any width. JS only adds hover-to-open on desktop,
   Escape-to-close, and the mobile hamburger toggle — all enhancements
   on top of a baseline that already works. */

.header__navigation {
  min-width: 0;
}

.primary-nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  list-style: none;
  padding-left: 0;
}

.primary-nav__item {
  position: relative;
}

.primary-nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  /* Comfortable touch target without inflating the header's visual height. */
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-ink);
  text-decoration: none;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.primary-nav__link::-webkit-details-marker {
  display: none;
}

.primary-nav__link:hover,
.primary-nav__link.is-active,
.primary-nav__link.is-active-parent,
.primary-nav__link[aria-current="page"] {
  color: var(--color-link);
}

.primary-nav__icon {
  display: none;
  width: 1.15rem;
  height: 1.15rem;
  flex-shrink: 0;
}

.chevron {
  width: 0.9rem;
  height: 0.9rem;
  color: var(--color-ink-muted);
  transition: transform var(--transition-fast);
}

.nav-dropdown[open] .chevron {
  transform: rotate(180deg);
}

/* Dropdown panel content — shared between the desktop floating panel and
   the mobile nested accordion; positioning differs per breakpoint below. */

.dropdown__label {
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-ink-muted);
  margin-bottom: var(--space-2);
}

/* A real divider between groups (e.g. Sportsbooks / Racing in the Sports
   dropdown) — comfortable space before it, a line, then comfortable space
   before the next group's label, so it never sits flush against the last
   link above or the heading below. Symmetric on purpose: both gaps do the
   same job (separating two groups), so there's no reason for them to
   differ. --space-lg, not --space-md: "content group → divider" is a
   LARGE-tier relationship in the permanent rhythm hierarchy (PROJECT.md),
   same tier as a section's closing CTA. */
.dropdown__group + .dropdown__group {
  margin-top: var(--space-lg);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
}

/* More dropdown's two columns — stacked (mobile/tablet default) with the
   same horizontal-divider rhythm as .dropdown__group above; the desktop
   override below (>=1200px) switches this same divider to vertical
   instead of introducing a new spacing rule. */
.dropdown__column + .dropdown__column {
  margin-top: var(--space-lg);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
}

/* Single column by default (mobile/tablet) — with Slots/Live Casino now
   showing every provider (15 / 10) instead of a curated ~6, a 2-3 column
   grid at narrow widths would cramp names or force tiny text. The
   desktop-only column counts live in the .dropdown--slots/--live
   overrides below, next to the .dropdown width overrides they pair
   with. */
.dropdown__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2) var(--space-3);
}

.dropdown__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* flex, not block — harmless for the plain-text provider items above (a
   single text child lays out identically either way) and what the More
   dropdown's per-item icons need for icon+label alignment. Those icons
   reuse .primary-nav__icon as-is, so they're already hidden at desktop
   and shown (with the same brand color) at mobile/tablet via the
   existing rules below — no extra CSS needed for that. */
.dropdown__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--color-ink);
  text-decoration: none;
  font-size: var(--text-sm);
}

a.dropdown__item:hover,
a.dropdown__item:focus-visible {
  background: var(--color-surface-alt);
  color: var(--color-link);
}

/* Providers without a real page yet — inert text, never a broken link. */
.dropdown__item--soon {
  color: var(--color-ink-muted);
  cursor: default;
}

.dropdown__viewall {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  /* content group → divider, LARGE tier — same rule as .dropdown__group above. */
  margin-top: var(--space-lg);
  padding: var(--space-3) var(--space-2);
  border-top: 1px solid var(--color-border);
  font-weight: 600;
  color: var(--color-link);
  text-decoration: none;
}

/* Access actions */

.header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.header__actions .primary-nav__icon {
  display: none;
}

/* Persistent mobile-only Login/Register (see header.njk) — hidden at
   desktop, where .header__actions above (unwrapped via .header__panel's
   display:contents) already renders them in the bar. margin-left: auto
   is what pushes this cluster — and the language switcher + hamburger
   right after it — to the far right, away from the logo;
   .site-header__bar's own gap is what keeps comfortable, non-cramped
   space before each control, same token the rest of the bar uses for
   item-to-item spacing (no one-off margins added for this). */
.header__mobile-actions {
  display: none;
}

@media (max-width: 1199.98px) {
  .header__mobile-actions {
    display: flex;
    align-items: center;
    /* Login/Register on the shared action-group gap, not a one-off
       margin on either button — was --space-1 (4px), which read as
       the two buttons almost touching. --space-1 + --space-2 (12px)
       is built from the same token scale and lands inside both the
       requested 8-12px (mobile) and 10-14px (tablet) target windows
       at once, so one value covers this whole <1200px range instead
       of splitting it into yet another breakpoint tier. */
    gap: calc(var(--space-1) + var(--space-2));
    margin-left: auto;
  }
}

/* Narrowest phones only — logo + Login + Register + language trigger +
   hamburger is a lot of controls for one row; at this width the general
   space-3 bar gap left the hamburger ~1-5px short and wrapping to a
   second row (measured, not assumed). Nothing above 374px needs this —
   375px+ already had room with the general gap alone. */
@media (max-width: 374.98px) {
  .site-header__bar {
    gap: var(--space-2);
  }

  /* Widening the Login/Register gap (12px) and the logo (32px) reopened
     the same deficit at exactly 320px — measured ~3.5px over budget.
     Login/Register still get real, deliberate spacing here (8px, the
     token floor of the requested 8-12px mobile range — they're never
     close to touching), and the logo settles at 30px rather than
     dropping all the way back to 28px. Recovers ~6px, not just the
     3.5px needed, so this isn't an exact-fit repeat of the same bug. */
  .header__mobile-actions {
    gap: var(--space-2);
  }

  .site-logo__image {
    width: 1.875rem;
    height: 1.875rem;
  }
}

/* Language switcher — see partials/language-switcher.njk. One control
   design (a round/pill dropdown trigger showing the current language's
   flag + abbreviation + chevron, opening a popover of flag+name rows),
   rendered twice from the same real locale data — same "one source,
   different display" approach as Login/Register above, not two separate
   systems: .lang-switcher--compact stays visible in the top bar below
   the desktop breakpoint, immediately left of the hamburger;
   .lang-switcher--full renders inside .header__panel, so
   display:contents naturally places it between nav and Login/Register
   at desktop with no extra positioning CSS, and appears as a bonus
   inside the open mobile drawer (never the only way to reach it there).
   Native <details>/<summary>, same pattern as the primary nav dropdowns:
   opens with zero JS, gets Escape-to-close + outside-click-close for
   free via the existing generic [data-nav-dropdown] handling in main.js. */

.lang-switcher {
  position: relative;
}

.lang-switcher--full {
  display: none;
}

@media (min-width: 1200px) {
  .lang-switcher--full {
    display: block;
    /* On top of .site-header__bar's own gap (already 16px) — enough to
       read as a distinct zone boundary from the nav without the huge
       margin .header__actions uses for its own, bigger separation from
       Login/Register. Trimmed once from space-4: at 1200px the
       container (capped 1200px wide) is at its tightest, and the
       6-item nav list ("Live Casino" is the long one) was wrapping to
       a second row until this and .header__actions' own margin below
       were both trimmed — verified nav stays single-row afterward. */
    margin-left: var(--space-2);
  }
}

@media (min-width: 1200px) {
  .lang-switcher--compact {
    display: none;
  }
}

.lang-switcher__trigger {
  display: inline-flex;
  align-items: center;
  /* Tight on purpose — at 320px this trigger sits between Register and
     the hamburger with zero width to spare (see components.css header
     comments / PROJECT.md); every px here was measured against an
     actual overflow check, not guessed. */
  gap: 0.1875rem;
  height: 2.75rem;
  padding-inline: var(--space-2) var(--space-1);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-brand);
  background: var(--color-white);
  color: var(--color-link);
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}

.lang-switcher__trigger::-webkit-details-marker {
  display: none;
}

.lang-switcher__trigger .chevron {
  width: 0.75rem;
  height: 0.75rem;
  flex-shrink: 0;
}

.lang-switcher[open] .lang-switcher__trigger .chevron {
  transform: rotate(180deg);
}

/* Shared circular-flag treatment for both the trigger's current-language
   flag and each dropdown row's flag — a plain rect SVG clipped into a
   circle here (CSS), rather than baking a circular clip into every SVG
   asset, so the same flag files also work anywhere else at native shape. */
.lang-switcher__flag,
.lang-switcher__option-flag {
  display: block;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

/* Mobile/tablet only — the compact trigger shrinks further than the
   desktop "full" instance (same .lang-switcher__trigger class, no
   override here so it stays 2.75rem), using the same visible-circle-
   smaller-than-hit-area trick as the hero slider arrows: a real height
   reduction plus an invisible ::before restoring a ~44px tap target. */
@media (max-width: 1199.98px) {
  .lang-switcher--compact .lang-switcher__trigger {
    position: relative;
    height: 2.5rem;
  }

  .lang-switcher--compact .lang-switcher__trigger::before {
    content: "";
    position: absolute;
    inset: -0.125rem;
  }

  .lang-switcher--compact .lang-switcher__flag {
    width: 1.125rem;
    height: 1.125rem;
  }
}

.lang-switcher__popover {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2);
  min-width: 12.5rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: 0 12px 28px rgba(16, 32, 46, 0.12), var(--shadow-sm);
  z-index: 30;
}

.lang-switcher__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-ink);
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
}

a.lang-switcher__option:hover,
a.lang-switcher__option:focus-visible {
  background: var(--color-surface-alt);
}

/* Pale-blue background + bolder brand-blue text — a second, non-color
   cue (weight) alongside aria-current="page" on the element itself, so
   the current language is never indicated by color alone. */
.lang-switcher__option.is-active {
  background: var(--color-surface-alt);
  color: var(--color-link);
  font-weight: 700;
}

.lang-switcher__option.is-disabled {
  color: var(--color-ink-muted);
  cursor: default;
}

/* Adding the flag (20px) to the compact trigger reintroduced the same
   320px-only deficit fixed earlier for .site-header__bar's own gap —
   measured at ~16.5px over budget. Shrinking the flag + tightening its
   own padding/gap here (never dropping the flag or the EN/中/BM
   abbreviation, per spec) recovers enough width to keep the header a
   single row again. Deliberately placed AFTER the unconditional
   .lang-switcher__trigger rule above — same selector, same specificity,
   so source order decides, and a version above these base rules would
   silently lose regardless of the media query (see PROJECT.md). */
@media (max-width: 374.98px) {
  .lang-switcher__trigger {
    gap: 0.125rem;
    padding-inline: 0.1875rem 0.125rem;
  }

  .lang-switcher--compact .lang-switcher__flag {
    width: 0.75rem;
    height: 0.75rem;
  }
}

/* Hamburger */

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-ink);
}

/* Same visible-box-smaller-than-hit-area trick used for the hero
   slider arrows and the compact language trigger: the box itself
   shrank from 2.75rem to 2.5rem, this invisible pseudo-element
   restores a ~44px tap target around it. */
.nav-toggle::before {
  content: "";
  position: absolute;
  inset: -0.125rem;
}

.hamburger {
  position: relative;
  display: inline-block;
  width: 1.125rem;
  height: 0.8125rem;
}

.hamburger span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  border-radius: var(--radius-full);
  background: currentColor;
  transition: transform var(--transition-fast), opacity var(--transition-fast), top var(--transition-fast);
}

.hamburger span:nth-child(1) { top: 0; }
.hamburger span:nth-child(2) { top: 50%; margin-top: -1px; }
.hamburger span:nth-child(3) { top: 100%; margin-top: -2px; }

.nav-toggle[aria-expanded="true"] .hamburger span:nth-child(1) {
  top: 50%;
  margin-top: -1px;
  transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .hamburger span:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .hamburger span:nth-child(3) {
  top: 50%;
  margin-top: -1px;
  transform: rotate(-45deg);
}

/* Desktop (>=1200px) — raised from 1100px when the "More" nav item and
   wider inter-item gap were added: a 7th nav item plus real breathing
   room between items no longer fit in one row at 1100px (measured, not
   assumed — it wrapped to two rows), while 1200px stays a clean single
   row through 1920px, since .container caps at 1200px regardless of
   viewport. Per the explicit brief, switching to the compact header
   earlier is preferred over ever wrapping the desktop nav. Verified
   empirically at 1024, 1100, 1200, 1280, 1440 and 1920px. */
@media (min-width: 1200px) {
  /* No-op wrapper at desktop — .header__navigation and .header__actions
     participate directly in .site-header__bar's flex layout, giving the
     brand/nav/actions grouping real breathing room instead of a nested
     flex context that would need extra margins to compensate. */
  .header__panel {
    display: contents;
  }

  .header__navigation {
    flex: 1;
    display: flex;
    justify-content: flex-end;
  }

  /* The main clearer-grouping fix: a deliberate, visible gap between the
     language switcher and the access actions — bigger than the gap
     between individual nav items, so Login/Register read as a distinct
     zone. Trimmed twice (space-7 → space-6 → space-4) as the language
     switcher was added between nav and actions and ate into the same
     1200px-capped container width — see .primary-nav__link below for
     the rest of that fix. */
  .header__actions {
    margin-left: var(--space-4);
  }

  .nav-panel__label {
    display: none;
  }

  .primary-nav__list {
    align-items: center;
    gap: var(--space-2);
  }

  /* .container caps at 1200px (--container-max) regardless of viewport —
     so unlike most "not enough room" problems, a wider screen doesn't
     buy more space here. Adding the language switcher between nav and
     actions used up real width, and the 6-item nav list (with real
     English words — "Live Casino" is the long one) started wrapping to
     a second row at every desktop width once that happened. Tightening
     inline padding here (was space-3) is what buys the room back —
     verified by checking .primary-nav__list stays single-row at 1100,
     1280, and 1920px afterward, not just "should work." */
  .primary-nav__link {
    padding-inline: var(--space-2);
  }

  .dropdown {
    position: absolute;
    /* No gap between trigger and panel — a gap here is a classic hover
       dead-zone: moving the mouse from summary to dropdown at speed or
       on a diagonal briefly lands on neither, firing a premature
       mouseleave on the parent. The border/shadow alone separates them
       visually without needing real space. */
    top: 100%;
    right: 0;
    width: 22rem;
    padding: var(--space-4);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: 0 12px 28px rgba(16, 32, 46, 0.12), var(--shadow-sm);
    z-index: 30;
  }

  /* More dropdown — 14 links is too many for one unstructured column, so
     it gets its own wider, 2-column treatment (a compact mega-menu, not
     a redesign of the dropdown component itself — .dropdown--more only
     overrides width; everything else above still applies). */
  .dropdown--more {
    width: 36rem;
  }

  /* Slots (15 providers) and Live Casino (10 providers) — same idea,
     sized to each one's actual provider count instead of one shared
     width for every dropdown. Sports (6, split across two short
     Sportsbooks/Racing lists) stays at the 22rem default above; it
     never needed its own modifier. Slots: 3 columns × 5 rows instead of
     a single tall column. Live Casino: 2 columns × 5 rows — noticeably
     narrower than Slots since it has a third fewer providers. */
  .dropdown--slots {
    width: 34rem;
    /* Slots sits near the LEFT of the nav (right after Download) — the
       base .dropdown's right:0 (measured against Live Casino/Sports/
       More further right, where it's correct) would hang this wider
       panel ~87px off the left edge of the viewport at 1280px
       (measured, not assumed). Left-aligned instead, it extends toward
       the (roomier) right side of the nav/viewport. */
    left: 0;
    right: auto;
  }

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

  .dropdown--live {
    width: 26rem;
  }

  .dropdown--live .dropdown__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .dropdown__columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }

  /* Same divider, rotated: a vertical rule between the two columns
     instead of a horizontal one between stacked groups — same
     --space-lg tier on the inline axis this time, so the rhythm stays
     the same, just turned 90deg for the 2-column layout. */
  .dropdown__column + .dropdown__column {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
    margin-left: var(--space-lg);
    padding-left: var(--space-lg);
    border-left: 1px solid var(--color-border);
  }
}

/* Mobile / tablet (<1200px) */
@media (max-width: 1199.98px) {
  .nav-toggle {
    display: inline-flex;
  }

  .nav-panel__label {
    display: block;
    font-size: var(--text-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-ink-muted);
    margin-bottom: var(--space-2);
  }

  .header__panel {
    display: none;
    /* flex: 0 0 100% (not just width: 100%) — with flex-wrap: wrap on
       .site-header__bar, a plain width would still let the panel shrink
       to fit the row's remaining space instead of wrapping onto its own
       line below the logo/hamburger. Verified via a real layout bug: it
       rendered squeezed into ~127px instead of spanning the header. */
    flex: 0 0 100%;
    flex-direction: column;
    align-items: stretch;
    /* Bigger than the gap between individual nav rows below — this is
       the boundary between the whole "Browse" block and the whole
       "Access" block, a bigger relationship than item-to-item. */
    gap: var(--space-5);
    max-height: 75vh;
    overflow-y: auto;
    padding-block: var(--space-4);
    border-top: 1px solid var(--color-border);
  }

  .header__panel[data-open="true"] {
    display: flex;
  }

  .primary-nav__list {
    flex-direction: column;
    gap: var(--space-2);
  }

  .primary-nav__link {
    width: 100%;
  }

  .primary-nav__icon {
    display: inline-flex;
    color: var(--color-brand-deep);
  }

  .header__actions .primary-nav__icon {
    display: inline-flex;
  }

  .dropdown {
    padding-top: var(--space-3);
    padding-left: var(--space-6);
  }

  /* Taller rows for touch — desktop's own hover-driven padding (space-1
     block) is fine with a mouse, but on the accordion-style mobile list
     (used by every dropdown here, including the 14-item More submenu)
     it measured under 31px tall, tighter than comfortable to tap. */
  .dropdown__item {
    padding-block: var(--space-2);
  }

  /* Login/Register now live persistently in the top bar on mobile
     (.header__mobile-actions) — showing them again inside the drawer
     would just be a redundant, less-discoverable copy of the same two
     links, so the drawer's copy is hidden entirely rather than kept at
     reduced prominence. Desktop is unaffected: .header__panel's
     display:contents there means this rule never applies to it. */
  .header__actions-wrap {
    display: none;
  }

  .header__actions {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }

  .header__actions .btn {
    justify-content: flex-start;
    padding: var(--space-3);
  }
}

/* Buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  transition: opacity var(--transition-fast);
}

.btn:hover {
  opacity: 0.9;
}

.btn--primary {
  /* --gradient-button, not --gradient-primary — see tokens.css for why
     (a weighted-stop gradient keeps white text safely contrasted). */
  background: var(--gradient-button);
  color: var(--color-white);
}

.btn--secondary {
  background: var(--color-surface);
  color: var(--color-link);
  border-color: var(--color-brand);
}

.btn--tertiary {
  padding-inline: 0;
  color: var(--color-link);
  border: none;
  background: none;
}

/* Used by the persistent mobile-header Login/Register (header.njk).
   Declared after .btn so its padding-inline actually wins over .btn's
   own padding shorthand — same physical properties, later source order
   needed since both rules share equal specificity. Tighter than the
   base space-4 inline padding: at 320px the header's minimum content
   width (logo + Login + Register + hamburger, already at their own
   minimums) came to ~333px with the base padding, wrapping the
   hamburger to a second row; space-2 here closes that gap with room to
   spare, verified across all 4 required widths. */
.btn--compact {
  height: 2.5rem;
  padding-inline: var(--space-2);
  font-size: var(--text-sm);
}

/* Provider page compact header — a small logo/icon area beside the H1,
   deliberately restrained (not a promotional hero banner). */

.provider-hero {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.provider-hero__media {
  width: 4.5rem;
  flex-shrink: 0;
}

/* The text column (title + eyebrow) is the other flex child. Flex items
   default to min-width: auto, which refuses to shrink below an
   unbreakable word's full width — a single long provider name with no
   spaces (e.g. "Spadegaming") pushed the whole row past the viewport at
   320px instead of wrapping. Found via an actual overflow check, not
   assumed. overflow-wrap is a second safety net for names longer still. */
.provider-hero__media + div {
  min-width: 0;
}

.provider-hero__media + div h1 {
  overflow-wrap: break-word;
}

/* Cards */

.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

/* Whole-card links (e.g. .card--provider on hub pages) — reset the
   anchor's own default color/underline so .card__title's own styling
   (not blue, not underlined) applies instead. */
a.card {
  color: inherit;
  text-decoration: none;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.card__title {
  font-size: var(--text-md);
  font-weight: 700;
}

.card__title a {
  color: var(--color-ink);
  text-decoration: none;
}

.card__title a:hover {
  color: var(--color-link);
}

/* Breadcrumbs */

.breadcrumbs {
  padding-block: var(--space-3);
}

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  padding-left: 0;
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
}

.breadcrumbs a {
  color: var(--color-ink-muted);
}

.breadcrumbs li:not(:last-child)::after {
  content: "/";
  margin-left: var(--space-2);
  color: var(--color-border);
}

/* Notice / callout — used only for genuine notices, not decoration */

.notice {
  padding: var(--space-4);
  border-left: 3px solid var(--color-notice-border);
  background: var(--color-notice-bg);
  border-radius: var(--radius-sm);
}

/* Accordion — native <details>/<summary>, no JS required. The +/× marker
   is a plain rotated CSS shape, not an image or icon font. */

.accordion summary {
  cursor: pointer;
  font-weight: 600;
  padding-block: var(--space-3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  list-style: none;
}

.accordion summary::-webkit-details-marker {
  display: none;
}

.accordion summary::after {
  content: "+";
  flex-shrink: 0;
  font-weight: 400;
  font-size: var(--text-md);
  color: var(--color-ink-muted);
  transition: transform var(--transition-fast);
}

.accordion[open] summary::after {
  transform: rotate(45deg);
}

.accordion summary:hover {
  color: var(--color-link);
}

.accordion p {
  padding-bottom: var(--space-3);
  color: var(--color-ink-muted);
}

.accordion + .accordion {
  border-top: 1px solid var(--color-border);
}

/* Table — a bordered, rounded frame (same shadow/radius language as
   .panel/.dropdown) rather than a bare HTML table; overflow-x:auto on
   the outer wrapper both clips the rounded corners and gives any future
   wider table a horizontal-scroll fallback instead of breaking layout. */

.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.table-scroll table {
  min-width: 100%;
}

.table-scroll th,
.table-scroll td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
}

.table-scroll thead th {
  background: var(--color-surface-alt);
  color: var(--color-ink);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.table-scroll tbody th {
  color: var(--color-link);
}

.table-scroll tbody tr:nth-child(even) {
  background: var(--color-surface-alt);
}

.table-scroll tbody tr:last-child th,
.table-scroll tbody tr:last-child td {
  border-bottom: none;
}

/* Article/policy meta line — published/updated/author/reviewed dates.
   Only rendered by layouts when a genuine front-matter value exists. */

.article-meta {
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
}

/* Section band background — used sparingly on the homepage as deliberate
   visual breaks between zones, not a mechanical per-section alternation. */

.band--tint {
  background: var(--color-surface-alt);
}

/* Global section accent — the permanent, site-wide marker for the start
   of a major section (see PROJECT.md, "Site-Wide Spacing / Vertical
   Rhythm"). One class, generated content, not a real DOM element: add
   .section--accent to a section's own .stack wrapper and the line plus
   its gap to the heading below both come for free, correctly positioned
   as the visual first thing in the block regardless of source order —
   nothing to remember to place, size, or space by hand. Was previously
   two separate things (.hero__accent, gradient; .section-accent, a
   different solid color per homepage category) — consolidated into one
   system per direct request, since "one reusable global accent" and
   "three different per-category colors" can't both be true at once.
   Never apply this to anything smaller than a major section (a card, a
   button, a single FAQ item, a nav/dropdown item) — see PROJECT.md. */
.section--accent::before {
  content: "";
  display: block;
  width: var(--section-accent-width);
  height: var(--section-accent-height);
  border-radius: var(--radius-full);
  background: var(--gradient-primary);
  margin-bottom: var(--section-accent-gap);
}

/* Hero — two-column on desktop (content, then a reserved visual), stacks
   content → CTA → visual on mobile via plain source order. */

.hero {
  display: grid;
  gap: var(--space-5);
  align-items: center;
}

@media (min-width: 960px) {
  .hero {
    /* Content ~45% / slider ~55% — the slider carries real supplied
       imagery now (see .hero-slider below), so it gets the larger share
       instead of the smaller share a placeholder visual used to get. */
    grid-template-columns: 0.9fr 1.1fr;
    gap: var(--space-6);
  }
}

/* Hero's Login/Join Now buttons — centered on mobile/tablet only (same
   <1200px boundary as the rest of the site's mobile/tablet vs. desktop
   split), left-aligned at desktop. Scoped to this one cluster, not the
   generic .cluster primitive other pages reuse (e.g. the 404 page's
   button row), so nothing outside the hero is affected. */
@media (max-width: 1199.98px) {
  .cluster--hero-cta {
    justify-content: center;
  }
}

/* Hero banner slider — 3 supplied provider promotional images, enhanced
   by main.js. The frame's aspect-ratio matches the source images exactly
   (1717×916 ≈ 1.874) so object-fit: cover never actually has to crop
   anything — full artwork, no distortion, no unintentional cropping.
   No-JS baseline: overflow: hidden + each slide at flex 0 0 100% means
   slide 1 alone is visible with zero inline transform applied — the
   prev/next/dot controls are simply inert without JS, same "static HTML
   already works" principle as the rest of the site's navigation. */

.hero-slider {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  aspect-ratio: 1717 / 916;
  /* So Tab can reach the slider as one stop before its buttons, and so
     Left/Right arrow keys work as soon as the slider (not a specific
     button) has focus — see main.js. */
  outline-offset: 4px;
}

.hero-slider__track {
  display: flex;
  width: 100%;
  height: 100%;
  transition: transform var(--transition-base);
}

.hero-slider__slide {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
}

.hero-slider__slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.hero-slider__control {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  /* Visible circle is ~38px — smaller and more refined than a full 44px
     button would look. The 44px tap target is preserved invisibly via
     the ::before below (negative inset), same size on desktop and
     mobile for one consistent control. */
  width: 2.375rem;
  height: 2.375rem;
  padding: 0;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.9);
  color: var(--color-ink);
  box-shadow: var(--shadow-sm);
  transition: background var(--transition-fast);
}

.hero-slider__control::before {
  /* Pseudo-elements are hit-tested as part of their host element, so
     this invisible, larger box restores a ~44px accessible tap target
     without enlarging the visible circle above. */
  content: "";
  position: absolute;
  inset: -0.1875rem;
}

.hero-slider__control:hover {
  background: var(--color-white);
}

.hero-slider__control svg {
  width: 1.0625rem;
  height: 1.0625rem;
}

.hero-slider__control svg path {
  stroke-width: 1.5;
}

.hero-slider__control--prev {
  left: var(--space-3);
}

.hero-slider__control--next {
  right: var(--space-3);
}

.hero-slider__dots {
  position: absolute;
  left: 50%;
  bottom: var(--space-3);
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-full);
  /* A small, restrained backdrop — not a label or gradient over the
     artwork, just enough contrast to keep light dots visible regardless
     of what's behind them on any given slide (some source banners have
     light content right where the dots sit). */
  background: rgba(16, 32, 46, 0.28);
}

.hero-slider__dot {
  width: 0.5rem;
  height: 0.5rem;
  padding: 0;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.6);
  box-shadow: var(--shadow-sm);
  transition: background var(--transition-fast), transform var(--transition-fast);
}

.hero-slider__dot:hover {
  background: rgba(255, 255, 255, 0.85);
}

.hero-slider__dot[aria-selected="true"] {
  background: var(--color-white);
  transform: scale(1.3);
}

/* Media slot — reserved space for a future real image. Decorative
   scaffolding only (see partials/media-slot.njk); the icon signals
   "image goes here" without pretending to be real content. */

.media-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg, var(--color-surface-alt) 0%, #e3f6fb 100%);
}

.media-slot::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px dashed var(--color-border);
  border-radius: inherit;
}

.media-slot__icon {
  width: 22%;
  max-width: 3rem;
  height: auto;
  color: var(--color-brand-light);
  opacity: 0.6;
}

.media-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.media-slot--4-3 {
  aspect-ratio: 4 / 3;
}

.media-slot--16-10 {
  aspect-ratio: 16 / 10;
}

.media-slot--16-9 {
  aspect-ratio: 16 / 9;
}

.media-slot--1-1 {
  aspect-ratio: 1 / 1;
}

/* QR code page — the standalone .media-slot (unlike the card grids above)
   has no card wrapper to constrain its width, so it would otherwise
   stretch to the full narrow container. */
.qr-code__preview {
  max-width: 12rem;
}

/* Category cards — image + title + description + directional link. */

.card--category {
  height: 100%;
  padding: 0;
  overflow: hidden;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.card--category .media-slot {
  border-radius: 0;
}

.card--category:hover,
.card--category:focus-within {
  border-color: var(--color-brand-light);
  box-shadow: var(--shadow-sm);
}

.card__body {
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  /* Fills the remaining height once the card itself is stretched to match
     its row (see .card--category height:100%), so cards with a short
     description don't end up visibly shorter than their row siblings. */
  flex: 1;
}

.card__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-weight: 600;
  color: var(--color-link);
  text-decoration: none;
  /* Anchors the directional link to the bottom of the card body
     regardless of how much description text sits above it. */
  margin-top: auto;
}

.card__link:hover {
  text-decoration: underline;
}

/* Provider cards — image + name. On the homepage these are plain divs
   (not links — see PROJECT.md, Phase 3 internal-link strategy). On hub
   pages (partials/provider-directory.njk) the same class is applied to a
   real <a> pointing at the provider's future Phase 5 URL; a.card above
   handles the link-specific color/underline reset. */

.card--provider {
  padding: 0;
  overflow: hidden;
  text-align: center;
}

.card--provider .media-slot {
  border-radius: 0;
}

.card--provider .card__title {
  padding: var(--space-3);
}

a.card--provider:hover,
a.card--provider:focus-visible {
  border-color: var(--color-brand-light);
  box-shadow: var(--shadow-sm);
}

/* HOLD providers on hub pages (see partials/provider-directory.njk) — a
   plain, non-interactive card so it never looks clickable. Scoping the
   hover/focus rule above to `a.card--provider` (not just `.card--provider`)
   is what stops these from picking up the link's hover affordance. */
.card--provider-soon .card__title {
  color: var(--color-ink-muted);
}

/* Eyebrow label — small caps-style tag above a heading. */

.eyebrow {
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  /* --color-brand-deep measures 4.41:1 on white — just under WCAG AA for
     normal text. Found during Phase 5 a11y checks; --color-link is the
     established accessible-text token (~5.5:1), reused here. */
  color: var(--color-link);
}

/* Compact feature list — used in the About section. */

.feature-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  list-style: none;
  padding-left: 0;
  font-weight: 600;
}

.feature-list li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.feature-list li::before {
  content: "";
  width: 0.4rem;
  height: 0.4rem;
  border-radius: var(--radius-full);
  background: var(--gradient-primary);
  flex-shrink: 0;
}

/* Contained panel — Guides section: a single intentional block rather
   than a plain paragraph floating in a full-width band. */

.panel {
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}

.panel--accent {
  background: linear-gradient(135deg, var(--color-surface-alt) 0%, var(--color-surface) 65%);
}

/* Action strip — Login/Register/Download as one connected bar rather than
   a repeat of the category-card grid. Register gets a tinted cell and the
   primary button; Login/Download stay equal-weight secondary actions. */

.action-strip {
  display: grid;
  grid-template-columns: 1fr;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
}

@media (min-width: 640px) {
  .action-strip {
    grid-template-columns: repeat(3, 1fr);
  }
}

.action-strip__item {
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
  border-bottom: 1px solid var(--color-border);
}

.action-strip__item:last-child {
  border-bottom: none;
}

@media (min-width: 640px) {
  .action-strip__item {
    border-bottom: none;
    border-right: 1px solid var(--color-border);
  }

  .action-strip__item:last-child {
    border-right: none;
  }
}

.action-strip__item--primary {
  background: var(--color-surface-alt);
}

.action-strip__label {
  font-weight: 700;
}

/* Resource list — Trust section: a single linked list rather than a card
   grid, so it reads as distinct from both the category cards and the
   action strip. Icons are one neutral navigational glyph, never a
   certification/shield/lock mark — see PROJECT.md. */

.resource-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
}

.resource-list__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  text-decoration: none;
  color: inherit;
  border-bottom: 1px solid var(--color-border);
  transition: background var(--transition-fast);
}

.resource-list__item:last-child {
  border-bottom: none;
}

.resource-list__item:hover,
.resource-list__item:focus-visible {
  background: var(--color-surface-alt);
}

.resource-list__icon {
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-full);
  background: var(--color-surface-alt);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-brand-deep);
}

.resource-list__icon svg {
  width: 1.1rem;
  height: 1.1rem;
}

.resource-list__title {
  display: block;
  font-weight: 700;
  color: var(--color-ink);
  margin-bottom: var(--space-1);
}

.resource-list__desc {
  display: block;
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
}

/* Footer — background is --gradient-button, the exact same token (not
   just matching colors) as the header's Register button, per direct
   request. Already verified for white text (5.25:1 in the flat 0-72%
   zone) — see tokens.css. */

.site-footer {
  background: var(--gradient-button);
  color: var(--color-white);
}

.site-footer a {
  color: var(--color-white);
  text-decoration: none;
}

.site-footer a:hover,
.site-footer a:focus-visible {
  text-decoration: underline;
}

/* Top area: About, two link columns, and an asset-ready Trust column.
   1 col (mobile) -> 2 col (tablet, .site-footer__nav-groups dissolves so
   its two children flow as ordinary grid items) -> 4 col (desktop) —
   same breakpoints the rest of the site already uses for this kind of
   grid (.grid--2/.grid--4, .site-footer__grid before this change). */
.site-footer__top {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}

/* Mobile only: Information + Explore as one compact 2-column grid
   rather than each taking a full stacked row — "intelligent" stacking
   per the brief, not maximal stacking. Declared before the ≥640px
   override below on purpose: both rules set `display` on the same
   element at equal specificity, so at ≥640px the later rule needs to
   win for the dissolve to actually take effect — the reverse order
   silently kept this stuck on `grid` at every width once measured
   (a real bug caught by an actual tablet screenshot, not assumed). */
.site-footer__nav-groups {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
}

@media (min-width: 640px) {
  .site-footer__top {
    grid-template-columns: repeat(2, 1fr);
  }

  .site-footer__nav-groups {
    display: contents;
  }
}

@media (min-width: 960px) {
  .site-footer__top {
    grid-template-columns: repeat(4, 1fr);
  }
}

.site-footer__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--color-white);
}

.site-footer__brand img {
  width: 2rem;
  height: 2rem;
}

.site-footer__desc {
  margin-top: var(--space-sm);
  max-width: 32rem;
  /* Secondary text: reduced-opacity white, verified against the darker
     scrimmed background (the worst case for contrast) — still clears
     WCAG AA at this opacity, not just "looks fine." */
  color: rgba(255, 255, 255, 0.85);
}

.site-footer__heading {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.75);
  margin-bottom: var(--space-sm);
}

.site-footer__list {
  list-style: none;
  padding-left: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Asset-ready placeholder — no certification/payment/social files exist
   yet (see PROJECT.md and src/assets/images/footer/). Real images:
   target ~2.5rem height, auto width, drop into the same flex-wrap row;
   the dashed border and placeholder text disappear the moment a real
   <img> replaces this markup, same "swap the placeholder, not the
   architecture" pattern as partials/media-slot.njk elsewhere. */
.site-footer__assets {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  min-height: 3rem;
}

/* Trust & Resources: fixed 3-per-row on every device, per direct
   request — a grid (not flex-wrap) is what guarantees exactly 3 per
   row regardless of each badge's own width, rather than however many
   happen to fit. Images stay their natural width within each cell
   (not stretched) since .site-footer__assets img keeps width:auto. */
.site-footer__assets--grid3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  justify-items: start;
}

/* Security: always one row on every device, per direct request. Only 2
   badges, so this fits comfortably down to 320px (verified) — overflow-
   x:auto is a safety net, not the expected behavior, in case a future
   third badge is added here without revisiting this rule. */
.site-footer__assets--nowrap {
  flex-wrap: nowrap;
  overflow-x: auto;
}

/* Payment Methods: fixed 5-per-row, per direct request — same grid
   approach as --grid3 above (10 real bank/e-wallet logos = exactly 2
   rows). Columns just narrow at small widths rather than overflowing
   (verified down to 320px), same as --grid3. */
.site-footer__assets--grid5 {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  justify-items: start;
}

/* The dashed "nothing here yet" treatment only applies while a section
   is still an empty placeholder (Payment Methods) — real confirmed
   images (Trust & Resources, Security) render as plain images with no
   placeholder framing around them. :has() keeps this one rule instead
   of a template-level conditional class. */
.site-footer__assets:has(.site-footer__asset-placeholder) {
  padding: var(--space-2);
  border: 1px dashed rgba(255, 255, 255, 0.35);
  border-radius: var(--radius-sm);
}

.site-footer__asset-placeholder {
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.6);
}

.site-footer__assets img {
  /* A fixed `height` here (tried first) combined with base.css's global
     `max-width: 100%` actively DISTORTS the widest/shortest badges: a
     grid column narrower than that fixed-height image's natural width
     forces max-width to win, but a fixed height can't also shrink to
     match, so the aspect ratio breaks — found from an actual screenshot
     (bmm/GoDaddy/DMCA, the three widest-and-shortest source files,
     visibly stretched taller than their real shape). max-height (a
     ceiling, not a fixed value) with both width/height left auto is
     what lets the browser pick whichever constraint actually binds —
     column width or the height cap — while always preserving the
     source image's real proportions. */
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 2.5rem;
  display: block;
}

.site-footer__assets--grid5 img {
  /* Payment logos read fine smaller, and it's what makes 5 fit per row
     comfortably at narrow widths. */
  max-height: 2rem;
}

.site-footer__license {
  /* base.css sets a global `img { height: auto }`, which wins over the
     HTML height="" attribute on this element (a real bug found from an
     actual screenshot — the badge was rendering at its native 82×62
     instead of the intended 40px-tall size). An explicit CSS height is
     what actually controls the rendered size; width:auto keeps the
     native aspect ratio instead of stretching. */
  height: 2rem;
  width: auto;
  margin-top: var(--space-sm);
  display: block;
}

/* Second row: Payment Methods / Follow Us / Security. 1 col (mobile) ->
   3 col (tablet+) — three roughly-equal-weight blocks, not text-heavy
   enough to need a 2-col intermediate step the way the top area does. */
.site-footer__row2 {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
  padding-block: var(--space-lg);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}

@media (min-width: 768px) {
  .site-footer__row2 {
    grid-template-columns: repeat(3, 1fr);
  }

  .site-footer__row2-block--center {
    text-align: center;
  }

  .site-footer__row2-block--center .site-footer__assets {
    justify-content: center;
  }
}

/* Social icons — same restrained circular-control language as the
   header's language pills, not a colorful icon-button row. Disabled
   (no confirmed profile URL — see site.js) renders identically minus
   the hover/focus affordance, so it never looks clickable. */
.site-footer__social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-full);
  border: 1px solid rgba(255, 255, 255, 0.35);
  color: var(--color-white);
  transition: background var(--transition-fast), border-color var(--transition-fast);
}

a.site-footer__social-link:hover,
a.site-footer__social-link:focus-visible {
  background: rgba(255, 255, 255, 0.15);
  border-color: rgba(255, 255, 255, 0.6);
}

.site-footer__social-link.is-disabled {
  opacity: 0.45;
  cursor: default;
}

.site-footer__social-icon {
  width: 1.1rem;
  height: 1.1rem;
}

.site-footer__bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  padding-block: var(--space-sm);
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.75);
  text-align: center;
  /* --gradient-button is verified safe for white text near its dark
     0-58% stop, but that verification was against a button-shaped box.
     Stretched across a much wider, taller footer, the same 135deg
     gradient's transition zone lands differently — measured (via a
     same-scale canvas re-render of the gradient, not assumed) at as low
     as 3.68:1 in this bar's bottom-left corner, failing AA. A light 15%
     dark overlay here — just this strip, not the whole footer, so the
     rest of the surface still matches the button exactly as asked —
     brings it back to ~4.6:1. */
  background: rgba(6, 23, 44, 0.15);
}

/* base.css sets a global `p { max-width: 70ch }` for body-copy
   readability — correct for prose, wrong for this one-line copyright
   string: it left the <p> itself only ~617px wide inside a ~1200px
   container, and since a plain block element isn't self-centered, the
   text-align: center above was only centering text within that
   narrower, left-sitting box — not truly centered on the bar (a real
   bug, found from an actual screenshot, not assumed from the CSS). */
.site-footer__bottom p {
  max-width: none;
}
