/** Shopify CDN: Minification failed

Line 3313:37 Unexpected "*"

**/
/* The Kart Depot — custom theme design system.
   Ported verbatim from evo-krt-schl/preview/index.html — see that file for the
   original static reference. Class names match 1:1 so markup stays traceable. */

:root {
  /* BRAND TOKENS: GENERATED — edit brand/tokens.json, run scripts/build_brand_tokens.py */
  --navy: #001a52;
  --navy-2: #04123b;
  --navy-3: #0a2468;
  --blue: #0a4cff;
  --blue-hi: #2f66ff;
  --yellow: #febf00;
  --yellow-hi: #ffce33;
  --white: #f5f8ff;
  --ink: #c4d2f0;
  --muted: #7e90bd;
  --accent-text: #febf00;
  --line: rgba(122, 148, 210, 0.18);
  --line-y: rgba(254, 191, 0, 0.28);
  --ok: #5ce3a4;
  --bad: #ff8f86;
  --deal: #C8102E;
  --deal-bg: #da6d82;
  --text-3xs: 1.2rem;
  --text-2xs: 1.504rem;
  --text-xs: 1.696rem;
  --text-sm: 1.904rem;
  --text-base: 2.096rem;
  --text-lg: 2.496rem;
  --text-xl: 3.2rem;
  --text-2xl: 4rem;
  --weight-regular: 400;
  --weight-bold: 700;
  --radius-sm: 0;
  --radius-md: 0;
  --radius-lg: 0;
  --radius-pill: 0;
  --radius-round: 0;
  --display-section: clamp(32px, 4vw, 51px);
  --deck-max: 1500px;
  --deck-gutter: 16px;
  --deck-col-gap: 8px;
  --deck-row-gap: 24px;
  /* END BRAND TOKENS */
}

[data-theme='light'] {
  /* LIGHT THEME TOKENS: GENERATED — edit brand/tokens.json, run scripts/build_brand_tokens.py */
  --navy: #f4f6fc;
  --navy-2: #e4e9f6;
  --navy-3: #ffffff;
  --blue: #0a4cff;
  --blue-hi: #083dcc;
  --yellow: #febf00;
  --yellow-hi: #e5ac00;
  --white: #0a1230;
  --ink: #2a3350;
  --muted: #5b6584;
  --accent-text: #8a6400;
  --line: rgba(42, 51, 80, 0.14);
  --line-y: rgba(138, 100, 0, 0.3);
  --ok: #1f9d5c;
  --bad: #c0392b;
  /* END LIGHT THEME TOKENS */
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: 'Barlow', sans-serif;
  background: var(--navy);
  color: var(--ink);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

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

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

.container {
  max-width: 1280px;
  margin: 0 auto;
}

/* ── TOP NOTICE / ANNOUNCEMENT ── */
.notice {
  background: linear-gradient(90deg, var(--blue), var(--yellow));
  color: var(--navy);
  text-align: center;
  /* 36px row, per spec §3.1. Was 44px. */
  padding: 0.28rem 1rem;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.notice a {
  text-decoration: underline;
}

.notice-slides {
  position: relative;
  min-height: 1.2em;
}

.notice-slide {
  display: none;
}

.notice-slide.is-active {
  display: block;
}

/* ── HEADER ── */
header.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--navy-2) 92%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
  padding: 0;
}

/* TKD-UX-SPEC-002 §8.5 — pinned header, hides on scroll-down, reveals on
   scroll-up. .tkd-belt is added by assets/tkd-belt-scroll.js, which also
   reserves the header's height as body padding (fixed removes it from
   flow, unlike the sticky rule above that this overrides). z-index stays
   at the header's existing 100 rather than the spec's illustrative 60 —
   this theme's header was already layered above that; .tkd-lang__panel
   and .tkd-country__panel are pinned to 110 to stay above it in turn. */
header.site-header.tkd-belt {
  position: fixed;
  inset-inline: 0;
  transform: translateY(0);
  transition: transform 180ms ease;
  will-change: transform;
}

header.site-header.tkd-belt[data-hidden='true'] {
  transform: translateY(-100%);
}

@media (prefers-reduced-motion: reduce) {
  header.site-header.tkd-belt {
    transition: none;
  }
}

.site-header__inner {
  width: 100%;
}

.site-header__bar {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 2rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  /* 60px per TKD-STORE-UX-SPEC §3.2. It was 70px; the spec's figure assumed
     the search bar, which landed 2026-09-07 (HANDOFF §4.11 said to revisit). */
  height: 60px;
}

.site-header__brand {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
}

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

.brand-wordmark {
  font-family: 'Barlow Condensed', sans-serif;
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  color: var(--white);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

/* Compressed 2026-09-07 (19px/0.08em -> 17px/0.06em, tighter gaps) so the
   search bar between the nav and the actions clears the spec's 480px at
   1440px. Below 1100px the nav folds into the hamburger — see the belt
   breakpoints after the mobile nav rules. */
nav[aria-label='Primary'] {
  display: flex;
  flex: 0 0 auto;
  gap: clamp(0.8rem, 1.3vw, 1.4rem);
  align-items: center;
}

nav[aria-label='Primary'] a {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink);
  transition: color 0.2s;
}

nav[aria-label='Primary'] a:hover {
  color: var(--accent-text);
}

nav[aria-label='Primary'] a[aria-current='page'] {
  color: var(--accent-text);
}

.race-system-nav-shell {
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line-y) transparent;
  background: var(--navy-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.race-system-nav {
  width: 100%;
  /* The shell already scrolls horizontally (overflow-x, thin scrollbar,
     overscroll-behavior) but the grid had no floor, so on a 390px phone each
     of the nine cells was 43px and every label stacked one letter per line —
     the rail measured ~300px tall under the new search row. 760px (84px
     cells) fixed that for English; once words stopped breaking mid-word
     (2026-09-09) the it/fr/pt labels still ran 3-5 lines in the cells left
     over after the long-word cells took their share. 900px = 100px cells:
     every locale measured at ≤3 lines, English at 2. Desktop is untouched
     (1440/9 = 160px). */
  min-width: 800px;
  max-width: 1440px;
  margin: 0 auto;
  display: grid;
  /* One implicit column per item (8 since Apparel and Fitment Help left the
     rail, 2026-09-09) -- the count is not hard-coded, so removing or adding
     a link never leaves an empty track. min-content, not 0: a cell can
     never be narrower than its longest single word, so labels wrap at
     spaces ("Chassis &" / "Components") and never mid-word; 84px cells were
     hyphenating "COMPO-NENTS" on every phone. 800px = 100px cells on a
     phone, where the shell scrolls; desktop divides 1440px evenly. */
  grid-auto-flow: column;
  grid-auto-columns: minmax(min-content, 1fr);
}

/* 40px, per TKD-STORE-UX-SPEC §3.4 ("Height 40px"). It was 62px, and with the
   announcement bar and the header belt that made 221px of chrome before any
   content. Icons removed 2026-09-09 (Luiz) — the rail reads faster as text
   only; the 1.5rem icon column collapsed with them, same "delete the child,
   collapse the template" fix as the v0.7.0 rail ordinals. */
.race-system-nav__link {
  position: relative;
  /* No min-width: 0 here (or on __copy below): the rail's cells are sized
     minmax(min-content, 1fr), and a grid item's min-content is what carries
     the longest word up to the cell. Zeroing it made the cells collapse to
     760px/9 again and the now-unbreakable words overflow their cells. */
  min-height: 40px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  padding: 0.2rem 0.6rem;
  border-right: 1px solid var(--line);
  color: var(--muted);
  transition: color 0.18s, background-color 0.18s;
}

.race-system-nav__link:first-child {
  border-left: 1px solid var(--line);
}

.race-system-nav__link::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--yellow);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.18s;
}

.race-system-nav__link:hover,
.race-system-nav__link:focus-visible,
.race-system-nav__link.is-active {
  color: var(--white);
  background: color-mix(in srgb, var(--blue) 8%, transparent);
}

.race-system-nav__link:hover::after,
.race-system-nav__link:focus-visible::after,
.race-system-nav__link.is-active::after {
  transform: scaleX(1);
}

.race-system-nav__copy {
  display: flex;
  flex-direction: column;
}

.race-system-nav__label {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  line-height: 1.1;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  /* Wrap at spaces only. Words are unbreakable here on purpose: the rail's
     cells are sized minmax(min-content, 1fr), so the longest word in any
     locale sets the cell's floor and there is never a reason to split one.
     Manual keeps an explicit &shy; working if a locale ever needs it. */
  overflow-wrap: normal;
  hyphens: manual;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem 1.3rem;
  border-radius: var(--radius-sm);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: all 0.18s;
  border: 1px solid transparent;
}

.btn-yellow {
  background: var(--yellow);
  color: var(--navy);
}

.btn-yellow:hover {
  background: var(--yellow-hi);
  transform: translateY(-1px);
}

.btn-blue {
  background: var(--blue);
  color: #fff;
}

.btn-blue:hover {
  background: var(--blue-hi);
  transform: translateY(-1px);
}

.btn-outline {
  border-color: var(--yellow);
  color: var(--accent-text);
}

.btn-outline:hover {
  background: var(--yellow);
  color: var(--navy);
}

.header-actions {
  display: flex;
  flex: 0 0 auto;
  gap: 0.75rem;
  align-items: center;
}

/* ── HEADER SEARCH — TKD-STORE-UX-SPEC §3.3 ──
   [ Category ▾ | 120px ][ input | flex:1 ][ 🔍 | 48px ], 44px tall, radius 0.
   Markup: snippets/header-search.liquid · rows: sections/predictive-search
   .liquid · driver: assets/tkd-search.js.

   The field is --white inside --navy-3 chrome, as the spec asks, so it is
   the brightest object in the belt. In light mode the tokens swap and it
   becomes a dark field on a light belt — deliberate: the search box keeps
   the highest contrast in the header either way. The input font is
   --text-xs (16.96px), above the 16px floor under which iOS zooms the
   viewport on focus. */
.tkd-search {
  position: relative;
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 760px;
}

.tkd-search__form {
  display: flex;
  align-items: stretch;
  height: 44px;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color 0.18s, box-shadow 0.18s;
}

/* The focus ring lives on the container, not the input, so the three parts
   read as one control. */
.tkd-search:focus-within .tkd-search__form {
  border-color: var(--yellow);
  box-shadow: var(--focused-base-box-shadow);
}

/* The select is wrapped so the caret can be drawn in currentColor — a caret
   baked into a background-image data URI cannot follow the theme tokens. */
.tkd-search__scope-wrap {
  position: relative;
  display: flex;
  flex: 0 0 120px;
  min-width: 0;
  border-right: 1px solid var(--line);
}

.tkd-search__scope-wrap::after {
  content: '';
  position: absolute;
  right: 11px;
  top: 50%;
  width: 6px;
  height: 6px;
  border-right: 1.5px solid var(--ink);
  border-bottom: 1.5px solid var(--ink);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}

.tkd-search__scope {
  width: 100%;
  min-width: 0;
  appearance: none;
  -webkit-appearance: none;
  background: var(--navy-3);
  color: var(--white);
  border: 0;
  border-radius: 0;
  padding: 0 24px 0 10px;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

.tkd-search__scope:focus-visible {
  outline: var(--focused-base-outline);
  outline-offset: -3px;
}

.tkd-search__scope option {
  background: var(--navy-3);
  color: var(--white);
  font-family: 'Barlow', sans-serif;
  letter-spacing: 0;
  text-transform: none;
}

.tkd-search__input {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--white);
  color: var(--navy-2);
  border: 0;
  border-radius: 0;
  padding: 0 12px;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  line-height: 1;
}

.tkd-search__input::placeholder {
  color: var(--muted);
  opacity: 1;
}

/* The container's :focus-within ring is the indicator for the whole control;
   a second ring inside the field would draw a box within a box. */
.tkd-search__input:focus-visible {
  outline: none;
  box-shadow: none;
}

.tkd-search__input::-webkit-search-decoration {
  -webkit-appearance: none;
}

.tkd-search__submit {
  flex: 0 0 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: var(--yellow);
  color: rgb(var(--color-button-text));
  cursor: pointer;
  transition: background-color 0.18s;
}

.tkd-search__submit:hover,
.tkd-search__submit:focus-visible {
  background: var(--yellow-hi);
}

.tkd-search__submit:focus-visible {
  outline: var(--focused-base-outline);
  outline-offset: -3px;
}

.tkd-search__submit svg {
  width: 20px;
  height: 20px;
}

/* Autocomplete panel. --navy-3 with a hairline, full bar width, ten rows at
   most. Rows are 44px so the list is usable with gloves on a phone. */
.tkd-search__panel {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  z-index: 110;
  max-height: min(70vh, 560px);
  overflow-y: auto;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
}

tkd-search[open] .tkd-search__panel {
  display: block;
}

tkd-search[loading] .tkd-search__panel {
  opacity: 0.75;
}

.tkd-search__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.tkd-search__list + .tkd-search__list,
.tkd-search__group + .tkd-search__group,
.tkd-search__footer {
  border-top: 1px solid var(--line);
}

/* --ink, not --muted: the panel is --navy-3, where --muted is banned (spec §13). */
.tkd-search__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 10px 12px 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--text-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}

.tkd-search__clear-recent {
  padding: 4px;
  background: none;
  border: 0;
  color: var(--accent-text);
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}

.tkd-search__clear-recent:hover,
.tkd-search__clear-recent:focus-visible {
  text-decoration: underline;
}

.tkd-search__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 6px 12px;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--ink);
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-xs);
  line-height: 1.25;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.tkd-search__item:hover,
.tkd-search__option[aria-selected='true'] > .tkd-search__item {
  background: color-mix(in srgb, var(--blue) 14%, transparent);
  color: var(--white);
}

/* Term rows: Shopify marks the matched substring; the rest stays --ink. */
.tkd-search__item--query mark {
  background: none;
  color: var(--white);
  font-weight: var(--weight-bold);
}

.tkd-search__thumb {
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--navy-2);
  border: 1px solid var(--line);
}

.tkd-search__thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.tkd-search__title {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tkd-search__price {
  flex: 0 0 auto;
  font-family: 'JetBrains Mono', monospace;
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--accent-text);
}

.tkd-search__item--collection {
  font-family: 'Barlow Condensed', sans-serif;
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.tkd-search__item--all {
  color: var(--accent-text);
  font-weight: var(--weight-bold);
}

.tkd-search__empty,
.tkd-search__note {
  margin: 0;
  padding: 10px 12px;
  color: var(--ink);
  font-size: var(--text-2xs);
}

.tkd-search__note {
  color: var(--accent-text);
  border-bottom: 1px solid var(--line);
}

/* ── SEARCH RESULTS — scope chip and the no-results recovery (spec §3.3) ── */
.search-scope-tag {
  display: inline-block;
  margin-left: 0.6rem;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.55em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
  vertical-align: middle;
}

.search-empty {
  max-width: 760px;
}

.search-empty__title {
  margin: 0 0 0.6rem;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.search-empty__actions {
  list-style: none;
  margin: 1.6rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.8rem 1rem;
}

.search-empty__hint {
  flex: 1 1 100%;
  color: var(--ink);
  font-size: var(--text-sm);
}

.search-empty__hint a {
  margin-left: 0.4rem;
  color: var(--accent-text);
  text-decoration: underline;
}

/* ── TKD-UX-SPEC-002 §7.2/§7.3 — LANGUAGE SELECTOR ──
   snippets/tkd-language-selector.liquid. Supersedes the plain-link
   .lang-switch/.lang-menu pair (which linked to language.root_url directly
   and lost request.path/active filters on switch). 240px panel, matching
   Amazon's measured M13; hover is an enhancement only where a fine pointer
   exists (§7.3) — the base <details> click/tap-toggle always works. */
.tkd-lang {
  position: relative;
}

.tkd-lang__anchor {
  list-style: none;
  cursor: pointer;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.4rem 0.7rem;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 34px;
}

.tkd-lang__anchor::-webkit-details-marker {
  display: none;
}

.tkd-lang__anchor:hover,
.tkd-lang__anchor:focus-visible {
  color: var(--accent-text);
  border-color: var(--line-y);
}

.tkd-lang__details[open] .tkd-lang__anchor {
  color: var(--accent-text);
}

.tkd-lang__caret {
  width: 10px;
  height: 6px;
}

.tkd-lang__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.4rem);
  width: 240px;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.6rem;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
  z-index: 110; /* above .tkd-belt, which sits at the header's existing z-index */
}

.tkd-lang__title {
  font-size: var(--text-2xs);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.2rem 0.5rem 0.5rem;
}

.tkd-lang__list {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.tkd-lang__option {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  min-height: 44px;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius-sm);
  color: var(--ink);
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
}

.tkd-lang__option:hover,
.tkd-lang__option:focus-visible {
  background: rgba(254, 191, 0, 0.1);
  color: var(--accent-text);
}

.tkd-lang__option[aria-current='true'] {
  color: var(--accent-text);
}

.tkd-lang__iso {
  font-size: var(--text-2xs);
  color: var(--muted);
}

/* Hover is an enhancement only where a fine pointer exists (§7.3) — this
   just opens the affordance visually a beat earlier; click/tap always
   works via native <details>, on every pointer type. */
@media (hover: hover) and (pointer: fine) {
  .tkd-lang:hover .tkd-lang__anchor {
    border-color: var(--line-y);
  }
}

/* ── TKD-UX-SPEC-002 §7.4 — COUNTRY/CURRENCY SELECTOR ──
   snippets/tkd-country-selector.liquid, footer tier 4. Net-new — no
   country/currency control existed anywhere in this theme before. */
.tkd-country__details {
  position: relative;
}

.tkd-country__anchor {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0.4rem 0.9rem;
  font-size: var(--text-xs);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}

.tkd-country__anchor::-webkit-details-marker {
  display: none;
}

.tkd-country__anchor:hover,
.tkd-country__anchor:focus-visible {
  color: var(--accent-text);
  border-color: var(--line-y);
}

.tkd-country__currency {
  color: var(--muted);
  font-size: var(--text-2xs);
  margin-left: 0.3rem;
}

.tkd-country__caret {
  width: 10px;
  height: 6px;
  flex-shrink: 0;
}

.tkd-country__panel {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: calc(100% + 0.4rem);
  width: 280px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.6rem;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
  z-index: 20;
}

.tkd-country__title {
  font-size: var(--text-2xs);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.2rem 0.5rem 0.5rem;
}

.tkd-country__list {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.tkd-country__option {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  min-height: 44px;
  font-size: var(--text-sm);
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius-sm);
  color: var(--ink);
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
}

.tkd-country__option:hover,
.tkd-country__option:focus-visible {
  background: rgba(254, 191, 0, 0.1);
  color: var(--accent-text);
}

.tkd-country__option[aria-current='true'] {
  color: var(--accent-text);
}

/* Mobile nav. The toggle and the <details> panel have been in the markup
   since the custom header shipped, but the toggle was display:none at EVERY
   width and the panel had no [open] rule — the hamburger never rendered
   anywhere. It is needed now: below 1100px the primary nav gives its room
   to the search bar.

   Positioned ABSOLUTE under the sticky header, not fixed: header.site-header
   has backdrop-filter, which makes it the containing block for fixed
   descendants too, so a fixed panel measured 46px tall and sat inside the
   header. Absolute + top:100% needs no JS to place it and scrolls with the
   sticky header. */
.mobile-nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s;
}

.mobile-nav-toggle:hover,
.mobile-nav-toggle:focus-visible {
  color: var(--accent-text);
  border-color: var(--line-y);
}

.mobile-nav-panel {
  display: none;
}

.mobile-nav-panel[open] {
  display: block;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 120;
  max-height: min(70vh, 560px);
  overflow-y: auto;
  padding: 1.5rem 2rem 3rem;
  background: var(--navy-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
}

.mobile-nav-panel summary {
  display: none;
}

.mobile-nav-close {
  position: absolute;
  top: 12px;
  right: 16px;
  width: 44px;
  height: 44px;
  padding: 0;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
}

.mobile-nav-panel nav {
  display: flex;
  flex-direction: column;
  padding-top: 3.5rem;
}

.mobile-nav-panel nav a {
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--white);
}

.mobile-nav-panel nav a:hover,
.mobile-nav-panel nav a:focus-visible {
  color: var(--accent-text);
}

.mobile-nav-panel nav a.btn {
  margin-top: 1.5rem;
  border-bottom: 0;
  justify-content: center;
  color: rgb(var(--color-button-text));
}

/* Belt breakpoints. ≤1280px the yellow CTA goes — the search bar is the
   belt's action now, and 480px of search matters more than a second "Shop"
   link; ≤1100px the primary nav folds into the hamburger; ≤640px the search
   bar wraps to its own row under logo + actions (spec §10: search visible at
   every breakpoint, never an icon). */
@media (max-width: 1280px) { /* component exception: the belt CTA goes before the nav folds (spec §10, note above) */
  .desktop-only {
    display: none !important;
  }
}

@media (max-width: 1100px) { /* component exception: the nav's fold point beside a 480px search bar (spec §10) */
  nav[aria-label='Primary'] {
    display: none;
  }

  .mobile-nav-toggle {
    display: inline-flex;
  }
}

@media (max-width: 719px) { /* store sm (720/1060/1400, responsive-standard §7 row 8) */
  .site-header__bar {
    flex-wrap: wrap;
    height: auto;
    min-height: 60px;
    padding: 8px 1.25rem 10px;
    row-gap: 8px;
  }

  .site-header__brand {
    order: 1;
  }

  .header-actions {
    order: 2;
    margin-left: auto;
  }

  .tkd-search {
    order: 3;
    flex-basis: 100%;
    max-width: none;
  }

  .tkd-search__scope-wrap {
    flex-basis: 104px;
  }
}

/* ── "ALL" DRAWER, DEPARTMENT DROPDOWNS, ACCOUNT FLYOUT ──
   TKD-STORE-UX-SPEC §3.2/§3.5/§3.6. Driven by assets/tkd-header-nav.js.
   Shares this file's existing navy-2/navy-3 surfaces, 0 radius, --line
   borders and Barlow Condensed uppercase label style rather than
   introducing new tokens — see docs/TKD-STORE-UX-SPEC.md §2. */

/* -- "All" trigger, pinned to the left edge of the scrolling rail shell -- */
.race-system-nav-shell {
  display: flex;
  align-items: stretch;
}

.race-system-nav {
  flex: 1 1 auto;
}

.race-all-btn {
  flex: 0 0 auto;
  position: sticky;
  left: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0 1rem;
  background: var(--navy-2);
  border: 0;
  border-right: 1px solid var(--line);
  color: var(--white);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.18s, background-color 0.18s;
}

.race-all-btn:hover,
.race-all-btn:focus-visible {
  color: var(--accent-text);
}

.race-all-btn svg {
  flex: 0 0 auto;
}

/* -- shared list styling: dropdown sub-lists, drawer accordion sub-lists,
   drawer department/brand/footer rows -- */
.tkd-drawer-count {
  color: var(--muted);
  font-size: var(--text-2xs);
  margin-left: 0.3rem;
}

.tkd-drawer-sublist,
.tkd-drawer-list {
  list-style: none;
}

.tkd-drawer-sublist a,
.tkd-drawer-list > li > a,
.tkd-drawer-row__link,
.tkd-drawer-sublist__hub {
  display: block;
  padding: 0.55rem 0;
  color: var(--ink);
  font-size: var(--text-sm);
}

.tkd-drawer-sublist a:hover,
.tkd-drawer-sublist a:focus-visible,
.tkd-drawer-list > li > a:hover,
.tkd-drawer-list > li > a:focus-visible,
.tkd-drawer-row__link:hover,
.tkd-drawer-row__link:focus-visible {
  color: var(--accent-text);
}

.tkd-drawer-sublist__hub {
  color: var(--yellow);
  font-weight: var(--weight-bold);
  border-bottom: 1px solid var(--line);
  margin-bottom: 0.2rem;
}

/* -- department dropdown (compact hover/focus panel, §3.5) -- */
.tkd-dept-wrap {
  display: contents;
}

.tkd-dept-dropdown {
  position: fixed;
  z-index: 150;
  width: 260px;
  max-width: calc(100vw - 16px);
  background: var(--navy-3);
  border: 1px solid var(--line);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
  padding: 1rem 1.2rem 1.2rem;
}

.tkd-dept-dropdown__heading {
  color: var(--yellow);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 0.4rem;
}

.tkd-dept-dropdown__list {
  list-style: none;
}

.tkd-dept-dropdown__all {
  display: inline-block;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--line);
  color: var(--yellow);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tkd-dept-dropdown__all:hover,
.tkd-dept-dropdown__all:focus-visible {
  text-decoration: underline;
}

.tkd-dept-dropdown a:focus-visible,
.tkd-all-drawer a:focus-visible,
.account-flyout a:focus-visible,
.account-flyout button:focus-visible,
.race-all-btn:focus-visible,
.tkd-drawer-accordion__summary:focus-visible,
.account-flyout__accordion-summary:focus-visible {
  box-shadow: var(--focused-base-box-shadow);
  outline: none;
}

/* -- "All" drawer: modal overlay + left slide-in panel, same conventions
   as assets/component-cart-drawer.css's .drawer/.drawer__inner (right
   slide-in), reused rather than a third animation approach -- */
.tkd-all-drawer {
  display: block;
}

.tkd-all-drawer[hidden] {
  display: none;
}

/* Verified live via theme:dev: two header-specific traps, both fixed here.
   (1) header.site-header has backdrop-filter, which — like `filter` —
   creates a new containing block for position:fixed descendants. This
   drawer is DOM-nested inside the header (rendered right after
   .race-system-nav-shell), so a percentage size or `inset: 0` resolves
   against the HEADER's own ~103px box, not the viewport, unless pinned
   with viewport units instead. (2) assets/base.css's global
   `div:empty { display: none; }` rule (an intentional a11y cleanup for
   accidentally-empty elements elsewhere in Dawn) matches this overlay,
   which is deliberately empty — a plain class selector loses that
   specificity fight, so the selector below is compounded to win it. */
.tkd-all-drawer .tkd-all-drawer__overlay {
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 200;
  background: rgba(0, 0, 0, 0.55);
  opacity: 0;
  transition: opacity var(--duration-default, 0.25s) ease;
}

.tkd-all-drawer.is-open .tkd-all-drawer__overlay {
  opacity: 1;
}

.tkd-all-drawer__panel {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 201;
  width: 365px;
  max-width: calc(100vw - 2rem);
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--navy-2);
  border-right: 1px solid var(--line);
  transform: translateX(-100%);
  transition: transform var(--duration-default, 0.25s) ease;
  overflow-y: auto;
}

.tkd-all-drawer.is-open .tkd-all-drawer__panel {
  transform: translateX(0);
}

.tkd-all-drawer__header {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.4rem 1.5rem;
  background: var(--navy-3);
  border-bottom: 1px solid var(--line);
}

.tkd-all-drawer__heading {
  color: var(--white);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tkd-all-drawer__close {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--line);
  color: var(--ink);
  cursor: pointer;
}

.tkd-all-drawer__close:hover,
.tkd-all-drawer__close:focus-visible {
  color: var(--accent-text);
  border-color: var(--line-y);
}

.tkd-all-drawer__body {
  padding: 0.5rem 1.5rem 2.5rem;
}

.tkd-all-drawer__group {
  padding: 1.2rem 0;
  border-bottom: 1px solid var(--line);
}

.tkd-all-drawer__group--footer {
  border-bottom: 0;
}

.tkd-all-drawer__group-heading {
  color: var(--yellow);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 0.4rem;
}

.tkd-drawer-row {
  border-bottom: 1px solid var(--line);
}

.tkd-drawer-row:last-child {
  border-bottom: 0;
}

.tkd-drawer-accordion__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  list-style: none;
  padding: 0.6rem 0;
  color: var(--white);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  cursor: pointer;
}

.tkd-drawer-accordion__summary::-webkit-details-marker {
  display: none;
}

.tkd-drawer-accordion__caret {
  display: inline-flex;
  color: var(--ink);
  transition: transform 0.18s;
}

.tkd-drawer-accordion[open] .tkd-drawer-accordion__caret {
  transform: rotate(180deg);
}

.tkd-drawer-accordion .tkd-drawer-sublist {
  padding: 0 0 0.6rem 0.8rem;
}

/* -- account flyout (§3.2) -- */
.account-flyout {
  position: relative;
}

.account-flyout__trigger {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.5rem;
  background: none;
  border: 1px solid transparent;
  color: var(--ink);
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s;
}

.account-flyout__trigger:hover,
.account-flyout__trigger:focus-visible {
  color: var(--accent-text);
  border-color: var(--line);
}

.account-flyout__icon {
  display: inline-flex;
  width: 20px;
  height: 20px;
}

.account-flyout__lines {
  display: flex;
  flex-direction: column;
  text-align: left;
  line-height: 1.15;
}

.account-flyout__line1 {
  font-size: var(--text-2xs);
  color: var(--muted);
}

.account-flyout__line2 {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--white);
}

.account-flyout__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.6rem);
  z-index: 150;
  width: 280px;
  background: var(--navy-3);
  border: 1px solid var(--line);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
  padding: 1.2rem;
}

.account-flyout__auth {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.account-flyout__greeting {
  color: var(--white);
  font-weight: var(--weight-bold);
  margin-bottom: 0.2rem;
}

.account-flyout__signin {
  justify-content: center;
}

.account-flyout__link {
  color: var(--ink);
  font-size: var(--text-sm);
}

.account-flyout__link--primary {
  color: var(--white);
  font-weight: var(--weight-bold);
}

.account-flyout__link:hover,
.account-flyout__link:focus-visible {
  color: var(--accent-text);
}

.account-flyout__divider {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 1rem 0;
}

.account-flyout__accordion {
  border-top: 1px solid var(--line);
}

.account-flyout__accordion:last-child {
  padding-bottom: 0;
}

.account-flyout__accordion-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  list-style: none;
  padding: 0.7rem 0;
  color: var(--white);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  cursor: pointer;
}

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

.account-flyout__caret {
  display: inline-flex;
  color: var(--ink);
  transition: transform 0.18s;
}

.account-flyout__accordion[open] .account-flyout__caret {
  transform: rotate(180deg);
}

.account-flyout__list {
  padding-bottom: 0.8rem;
}

.account-flyout__list-loading,
.account-flyout__empty {
  color: var(--ink);
  font-size: var(--text-2xs);
}

.account-flyout__item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0;
  color: var(--ink);
}

.account-flyout__item:hover,
.account-flyout__item:focus-visible {
  color: var(--accent-text);
}

.account-flyout__item img,
.account-flyout__item-noimg {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  background: var(--navy-2);
  border: 1px solid var(--line);
  object-fit: cover;
}

.account-flyout__item-title {
  font-size: var(--text-2xs);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 719px) { /* store sm */
  .account-flyout__lines {
    display: none;
  }

  .account-flyout__panel {
    right: -0.5rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tkd-all-drawer__overlay,
  .tkd-all-drawer__panel {
    transition: none;
  }
}

/* ── HERO ── */
.hero {
  position: relative;
  overflow: hidden;
  /* TKD-STORE-UX-SPEC 4.3 caps this at 420px so the hero cannot own the fold
     alone. It was clamp(440px, 43vh, 500px) and measured 463px live. The
     four-stat row that used to sit inside this box now renders beneath it as
     .hero-credentials, which is what freed the height. */
  min-height: clamp(300px, 30vh, 420px);
  display: flex;
  align-items: center;
  padding: 2.4rem 2rem;
  /* Photo sits under a heavy left-weighted scrim so the headline stays legible
     while the kart reads on the right. `hero-track.jpg` is a sibling of this
     file in assets/, so the relative url resolves on the Shopify CDN. */
  background:
    linear-gradient(
      100deg,
      rgba(2, 16, 47, 0.96) 0%,
      rgba(2, 16, 47, 0.88) 32%,
      rgba(6, 36, 95, 0.55) 62%,
      rgba(6, 36, 95, 0.32) 100%
    ),
    url('hero-track.jpg') center 30% / cover no-repeat,
    linear-gradient(125deg, #02102f 0%, var(--navy) 48%, #06245f 100%);
}

.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 72% 45%, rgba(10, 76, 255, 0.16) 0%, transparent 60%);
}

.hero-slashes {
  position: absolute;
  inset: 0;
  opacity: 0.5;
  pointer-events: none;
  background:
    repeating-linear-gradient(-32deg, transparent 0 58px, rgba(10, 76, 255, 0.1) 58px 60px),
    repeating-linear-gradient(-32deg, transparent 0 120px, rgba(254, 191, 0, 0.06) 120px 122px);
}

.hero-content {
  position: relative;
  z-index: 1;
  max-width: 720px;
}

.hero-content.container {
  width: 100%;
  max-width: 1370px;
}

/* Spec 4.3: "Left 40%: --navy panel". 40% of the 1370px container is 548px.
   The photo's subject sits right of centre, so this keeps the headline clear
   of the driver rather than overlapping him. */
.hero-panel {
  max-width: 548px;
}

.hero-eyebrow {
  margin-bottom: 1.4rem;
}

/* Heading clamps: ONLY the rem halves track the type scale. `vw` is
   viewport-relative and root-independent, so it already renders as authored --
   scaling it too would double-count. Whenever --text-* moves, these five
   clamps must be recomputed by the same factor or headings stop tracking body
   text; docs/CROSS-REPO-CONTRACT.md §2 names this exact trap, and on
   2026-09-06 it briefly left h2 (20px) SMALLER than body text (20.96px).
   scripts/check_type_scale.py guards them. */
.hero h1,
h1.page-h1 {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: clamp(4.16rem, 4.4vw, 6.4rem);
  font-weight: var(--weight-bold);
  line-height: 0.92;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--white);
  margin-bottom: 1.4rem;
}

.hero h1 .accent {
  color: var(--accent-text);
  display: block;
}

.hero-tagline {
  font-size: var(--text-base);
  color: var(--white);
  margin-bottom: 0.4rem;
  font-style: italic;
  font-weight: var(--weight-regular);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
}

/* --muted is tuned for the dark navy panels; over the hero photo it crosses the
   driver's lit helmet and washes out. Use the brighter .stat-label treatment. */
.hero-tagline-en {
  font-size: var(--text-sm);
  color: #dbe4fb;
  margin-bottom: 2.2rem;
  letter-spacing: 0.04em;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.65);
}

.hero-ctas {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

/* The four stats, moved out of .hero on 2026-09-08 (spec 4.3 height cap).
   --navy-2, not --navy-3: the labels are --muted, and the spec's definition
   of done forbids --muted on --navy-3. */
.hero-credentials {
  background: var(--navy-2);
  border-bottom: 1px solid var(--line);
  /* .container carries no gutter in this theme — each section supplies its
     own — so this matches .hero's 2rem or the stats sit flush to the edge. */
  padding: 1.6rem 2rem;
}

/* .hero-content.container overrides the global 1280px to 1370px. The strip has
   to match it, or "ROK" lands 45px right of "RACING PARTS" at 1440px. */
.hero-credentials .container {
  max-width: 1370px;
}

.hero-stats {
  display: flex;
  gap: 2.8rem;
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding: 0;
}

.hero-stats li {
  display: flex;
  flex-direction: column;
}

.stat-num {
  display: block;
}

.stat-num {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--accent-text);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.stat-label {
  font-size: var(--text-2xs);
  color: var(--muted);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-top: 0.35rem;
}

/* The hero photo + scrim above never changes with the theme toggle (same
   reasoning as .hero-tagline-en's hardcoded colour), so the text sitting on
   it can't use tokens that flip for light mode — it would go near-invisible
   against the still-dark photo. --yellow itself never flips, so that one is
   still a token; --white does flip, so it is pinned here.

   The .stat-num / .stat-label pins that used to live here were dropped on
   2026-09-08: the stats moved out of .hero into .hero-credentials, which is a
   token surface rather than the photo, so those two are free to follow the
   theme toggle again via --accent-text and --muted. */
.hero h1,
h1.page-h1,
.hero-tagline {
  color: #f5f8ff;
}

.hero h1 .accent,
.hero .hero-eyebrow {
  color: var(--yellow);
}

/* ── MARQUEE (brand logos) ── */
.marquee {
  background: var(--yellow);
  padding: 0.9rem 0;
  overflow: hidden;
  white-space: nowrap;
}

.marquee-inner {
  display: inline-flex;
  align-items: center;
  animation: marquee 30s linear infinite;
}

.marquee-item {
  display: inline-flex;
  align-items: center;
  padding: 0 2.2rem;
}

.marquee-item img {
  height: 32px;
  width: auto;
  max-width: 140px;
  object-fit: contain;
  background: #fff;
  border-radius: var(--radius-sm);
  padding: 0.4rem 0.9rem;
  box-sizing: content-box;
}

.marquee-item-text {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--navy);
  padding: 0 1.8rem;
}

@keyframes marquee {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .marquee-inner {
    animation: none;
  }
}

/* ── SECTIONS ── */
section.tkd-section {
  padding: 5rem 2rem;
}

.section-label {
  margin-bottom: 0.6rem;
}

/* .collection-title is an h1 that has to look exactly like the section h2 it
   replaced — see the note in sections/main-collection-banner.liquid. Sharing
   the rule keeps them from drifting, and adds no clamp for
   scripts/check_type_scale.py to track. */
.tkd-section h2,
.tkd-section h1.collection-title {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: clamp(3.2rem, 3.2vw, 4.16rem);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--white);
  line-height: 1.02;
  margin-bottom: 1rem;
}

.section-sub {
  color: var(--muted);
  font-size: var(--text-base);
  max-width: 520px;
}

/* ── RACE-SYSTEM CATALOG ── */
section.tkd-section.race-system-section {
  padding: 1.4rem 2rem 1.6rem;
  background:
    linear-gradient(115deg, color-mix(in srgb, var(--blue) 8%, transparent), transparent 42%),
    var(--navy-2);
}

.race-system-section h2.race-system-section__heading {
  margin: 0 0 1rem;
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 1.4;
  letter-spacing: 0.18em;
  color: var(--accent-text);
}

.race-system-section .container {
  max-width: 1370px;
}

.race-system-catalog {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}

.cat-card {
  position: relative;
  min-width: 0;
  display: grid;
  align-items: center;
  background: color-mix(in srgb, var(--navy) 34%, transparent);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  transition: border-color 0.18s, background-color 0.18s;
}

.cat-card::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--yellow);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform 0.18s;
}

.cat-card:hover,
.cat-card:focus-visible {
  background: color-mix(in srgb, var(--blue) 12%, transparent);
  border-color: var(--line-y);
}

.cat-card:hover::before,
.cat-card:focus-visible::before {
  transform: scaleY(1);
}

.cat-card--major {
  grid-column: 1 / -1;
  min-height: 60px;
  grid-template-columns: 2.9rem minmax(0, 1fr) 2.2rem;
  gap: 0.7rem;
  padding: 0.42rem 1.2rem;
}

.cat-card--compact {
  min-height: 64px;
  grid-template-columns: 2.2rem minmax(0, 1fr);
  gap: 0.5rem;
  padding: 0.55rem 0.75rem;
}

.cat-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
}

.cat-icon svg {
  width: 1.8rem;
  height: 1.8rem;
  stroke-width: 1.45;
}

.cat-card--compact .cat-icon svg {
  width: 1.7rem;
  height: 1.7rem;
  stroke-width: 1.65;
}

.cat-copy {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.cat-name {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  line-height: 1.05;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--white);
}

.cat-card--compact .cat-name {
  font-size: var(--text-sm);
}

.cat-count {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-2xs);
  line-height: 1.35;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.cat-total::before {
  content: ' / ';
  color: var(--line-y);
}

.cat-arrow {
  display: inline-flex;
  justify-content: flex-end;
  color: var(--white);
}

.cat-arrow svg {
  width: 1.6rem;
}

.cat-card--compact .cat-arrow {
  display: none;
}

.race-system-section__cta {
  display: flex;
  justify-content: center;
  margin-top: 1rem;
}

.race-system-section__cta .btn {
  width: min(100%, 360px);
  justify-content: center;
}

/* ── ALWAYS-AVAILABLE TEAM CONTACTS ── */
.support-contact-band {
  padding: 64px max(20px, calc((100vw - 1370px) / 2));
  background:
    linear-gradient(118deg, color-mix(in srgb, var(--blue) 9%, transparent), transparent 44%),
    var(--navy);
  border-top: 1px solid var(--line-y);
}

.support-contact-band__inner {
  max-width: 1370px;
}

.support-contact-band__heading {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 32px;
  margin-bottom: 22px;
}

.support-contact-band__heading h2 {
  margin: 5px 0 0;
  font-size: var(--display-section);
  color: var(--white);
}

.support-contact-band__body {
  max-width: 66ch;
  margin: 11px 0 0;
  color: var(--ink);
  font-size: var(--text-base);
  line-height: 1.55;
}

.support-contact-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}

/* Never had a mobile override -- 3 equal columns of a card carrying a name,
   role sentence, and two action buttons has no readable width below the
   footer's own 1059px "collapse to one track" floor (kept in step with it
   here rather than inventing a different threshold). Below that it visibly
   overlapped: names and phone numbers overlapping between adjacent ~110px
   columns, e-mail addresses breaking one character per line. */
@media (max-width: 1059px) {
  .support-contact-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .support-contact-card {
    border-right: 0;
  }
}

/* 2026-09-10 (Luiz): the Evolution site's card, on every property - portrait,
   first name, WhatsApp number, email. Values are the Evolution stylesheet's
   (evo-krt-schl site/styles.css .contact-card ...), in px so they land the
   same on this 10px root. The 2026-09-07 slimming that removed the 78px
   portrait track is reversed because the portraits were supplied; the 24/7
   status is not restored. */
.support-contact-card {
  display: grid;
  align-content: space-between;
  gap: 20px;
  min-width: 0;
  min-height: 190px;
  padding: 18px;
  background: var(--navy-3);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.support-contact-card__profile {
  display: grid;
  grid-template-columns: 78px minmax(0, 1fr);
  align-items: center;
  gap: 14px;
}

.support-contact-card__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 78px;
  height: 78px;
  overflow: hidden;
  background: var(--navy-2);
  border: 1px solid var(--line-y);
}

.support-contact-card__avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.support-contact-card h3 {
  margin: 0;
  color: var(--white);
  font-size: var(--text-lg);
}

.support-contact-card__actions {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
}

/* One action per row, the number and the address in the mono face, exactly
   as on evolution.thekartdepot.com. (The 2026-09-07 note about the 20px glyph
   track wrapping labels one character per line still applies: there is no
   glyph column here, and there must not be one.) */
.support-contact-action {
  display: flex;
  align-items: center;
  min-width: 0;
  min-height: 44px;
  padding: 7px 12px;
  color: var(--white);
  background: var(--navy-2);
  border: 1px solid var(--line);
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.support-contact-action--whatsapp {
  color: var(--accent-text);
  border-color: var(--line-y);
}

.support-contact-action:hover,
.support-contact-action:focus-visible {
  color: var(--accent-text);
  border-color: var(--yellow);
  background: color-mix(in srgb, var(--blue) 12%, var(--navy-3));
}

/* ── PRODUCTS ── */
.products-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  gap: 1.25rem;
  margin-top: 2.6rem;
}

.product-card {
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: all 0.2s;
  display: flex;
  flex-direction: column;
  /* TKD-STORE-UX-SPEC §5.4: fixed tile height so grid rows align regardless
     of title length. .products-grid is a CSS grid, which already stretches
     every card in a row to match the tallest one (default align-items:
     stretch) — height: 100% takes that stretched height, and the flex
     column below anchors the price/CTA row to the bottom via margin-top:
     auto on .product-footer, so short titles don't leave the footer
     floating mid-card. min-height is the floor for contexts without grid
     stretch (e.g. a future single-row carousel): image (190px) + info
     padding + one brand line + a 2-line clamped title + the footer row,
     with headroom for the optional .product-review line. */
  height: 100%;
  min-height: 400px;
}

.product-card:hover {
  border-color: var(--blue);
  transform: translateY(-3px);
}

.product-img {
  height: 190px;
  background: linear-gradient(135deg, var(--navy-3), var(--navy-2));
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  /* Positions the badge, wishlist heart, hover-swap images and hover
     Add-to-Cart overlay below, all absolutely, against this box. */
  position: relative;
}

.product-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Hover image-swap (§5.4): two stacked <img> elements, no JS. Only rendered
   by the card markup when product.images.size > 1; a single image just gets
   the .product-img__primary class and behaves exactly as before. */
.product-img__primary,
.product-img__secondary {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.2s ease;
}

.product-img__secondary {
  opacity: 0;
}

.product-card:hover .product-img__secondary,
.product-card:focus-within .product-img__secondary {
  opacity: 1;
}

.product-card:hover .product-img__primary,
.product-card:focus-within .product-img__primary {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .product-img__primary,
  .product-img__secondary {
    transition: none;
  }
}

/* Badge slot (§5.4) — one badge maximum, top-left. Colors are existing
   tokens repurposed by state so a NEW/LOW STOCK badge doesn't add a third
   yellow element next to the price and the hover Add-to-Cart button:
   discount keeps the spec's explicit yellow, NEW borrows --ok (a positive
   signal), LOW STOCK borrows --bad (already TKD's urgency color per §2.3's
   Amazon mapping table). Navy text on any of the three clears AA/AAA per
   §2.2 — the ratio is symmetric with --ok/--bad/--yellow on navy, all
   already measured AAA there. */
.tkd-badge {
  position: absolute;
  top: 0.7rem;
  left: 0.7rem;
  z-index: 2;
  display: inline-block;
  padding: 0.3rem 0.7rem;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: var(--radius-sm);
  background: var(--yellow);
  color: var(--navy);
}

.tkd-badge--new {
  background: var(--ok);
}

.tkd-badge--low-stock {
  background: var(--bad);
}

/* Light theme redefines --navy as a near-white page background (it's a
   background-role token, not literally "the color navy"), so --navy text
   on --ok/--yellow stops meeting AA there even though it's AAA in dark mode
   per §2.2. Same fix as the existing .badge/.pill-badge--blue light
   override above: swap the text color per variant instead of leaving a
   theme-only contrast failure. --bad is the one variant --navy text still
   clears (measured ~5:1) so it's left alone. */
[data-theme='light'] .tkd-badge {
  color: var(--white);
}

[data-theme='light'] .tkd-badge--low-stock {
  color: var(--navy);
}

/* Wishlist heart (§5.4, optional) — top-right, localStorage-backed via
   assets/tkd-wishlist.js. Square (0 radius) icon button; the heart glyph
   itself is Dawn's stock icon-heart.svg outline shape, so "filled" is
   conveyed by the fill color, not a different glyph.

   --navy-2 (chip) and --ink (unsaved glyph) are both semantic tokens that
   already flip correctly per theme (surface-role tokens go pale in light
   mode, text-role tokens go dark), so the unsaved state needs no override.
   --yellow does NOT flip — it's #febf00 in both themes — and yellow reads
   fine on this dark chip in dark mode but fails contrast once the chip goes
   pale in light mode. --accent-text is this palette's existing fix for
   exactly that (dark-mode value is --yellow itself; light-mode redefines it
   to a dark gold): it's the same token .product-brand already uses two
   rules up, so the saved heart is legible in both themes with no
   [data-theme='light'] override of its own. */
.tkd-wishlist-btn {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 2;
  width: 3.2rem;
  height: 3.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--navy-2);
  cursor: pointer;
  transition: border-color 0.15s;
}

.tkd-wishlist-btn svg {
  width: 1.7rem;
  height: 1.7rem;
  fill: var(--ink);
}

.tkd-wishlist-btn:hover,
.tkd-wishlist-btn:focus-visible {
  border-color: var(--yellow);
}

.tkd-wishlist-btn.is-saved svg {
  fill: var(--accent-text);
}

/* Hover-reveal Add to Cart (§5.4) — slides up from the bottom edge of the
   image on tile hover/focus-within (desktop); always visible with no hover
   input (mobile/touch), via the (hover: none) query below. */
.tkd-card-atc {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  transform: translateY(100%);
  transition: transform 0.18s ease;
}

.product-card:hover .tkd-card-atc,
.product-card:focus-within .tkd-card-atc {
  transform: translateY(0);
}

@media (hover: none) {
  .tkd-card-atc {
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tkd-card-atc {
    transition: none;
  }
}

.tkd-card-atc__form {
  margin: 0;
}

.tkd-card-atc__submit {
  width: 100%;
  justify-content: center;
  border-radius: 0;
  position: relative;
}

.tkd-card-atc__submit.loading {
  color: transparent;
}

.tkd-card-atc__submit.loading > .loading__spinner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  height: auto;
}

.tkd-card-atc__submit.loading > .loading__spinner .path {
  /* Same --accent-text rationale as the wishlist heart above: --navy is a
     background-role token that goes pale in light mode, so a --navy stroke
     on this still-yellow button would nearly vanish there. */
  stroke: var(--accent-text);
}

/* Branded stand-in for a product with no photo — spec §5.4, which forbids a
   glyph or a blank box. This replaced a 🏁 emoji on 2026-09-08.
   .product-img img above is width/height 100% + object-fit: cover, which would
   stretch the mark across the tile, so the mark opts out explicitly. */
.product-img__placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  padding: 1.2rem;
  background: var(--navy-2);
  text-align: center;
}

.product-img .product-img__placeholder-mark {
  width: min(62%, 150px);
  height: auto;
  object-fit: contain;
  opacity: 0.3;
}

.product-img__placeholder-type {
  font-size: var(--text-2xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  line-height: 1.25;
}

.product-info {
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.badge {
  margin-bottom: 0.55rem;
}

.product-brand {
  font-size: var(--text-2xs);
  color: var(--accent-text);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: var(--weight-bold);
  margin-bottom: 0.3rem;
}

.product-name {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--white);
  margin-bottom: 0.9rem;
  /* §5.4: "2 lines max, ellipsis" — clamp the title instead of letting a
     long one grow the tile. min-height reserves the full 2-line box even
     when the title is short, so cards don't shrink the footer upward. */
  line-height: 1.3;
  min-height: calc(var(--text-base) * 1.3 * 2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.product-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Anchors price + View to the bottom of the fixed-height card regardless
     of how much text sits above (brand line, clamped title, the optional
     .product-review line). */
  margin-top: auto;
}

.product-price {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--white);
  font-variant-numeric: tabular-nums;
}

.product-price .compare-at {
  font-size: var(--text-2xs);
  color: var(--muted);
  font-weight: var(--weight-regular);
  display: block;
  letter-spacing: 0.04em;
  text-decoration: line-through;
}

.product-review {
  font-size: var(--text-xs);
  color: var(--muted);
  margin-top: 0.3rem;
}

.catalog-note {
  margin-top: 2rem;
  font-size: var(--text-xs);
  color: var(--muted);
  border-left: 2px solid var(--line-y);
  padding-left: 1rem;
  max-width: 620px;
}

/* ── TEAM / ABOUT ── */
.team-section {
  background: linear-gradient(180deg, var(--navy) 0%, var(--navy-2) 100%);
}

.team-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 3.5rem;
  align-items: center;
  margin-top: 2.6rem;
}

.team-photo {
  border-radius: var(--radius-lg);
  border: 1px solid var(--line-y);
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4);
}

.team-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.team-copy p {
  color: var(--ink);
  line-height: 1.7;
  font-size: var(--text-base);
  margin-bottom: 1.2rem;
}

/* Evolution mark, homepage school block. The white card, padding and shadow
   that framed the old badge are gone: the official lockup has no background
   and carries its own chrome plate, so it sits straight on the section.
  The file is the client's master as supplied, 298x286, unmodified (Luiz,
  2026-09-08: use it as is, no crop). The wordmark plate sits in the middle
  third of that canvas and the speed streaks fill the rest, so the image box
  is ~2.9x taller than the plate. Height is chosen for the plate, and the
  negative block margin folds the streak halo back over the surrounding
  space so the row keeps its rhythm. Do not re-crop the file. */
.evolution-mark {
  display: inline-block;
  margin-bottom: 1.6rem;
}

.evolution-mark img {
  display: block;
  height: 160px;
  width: auto;
  margin-block: -50px;
}

.affiliation-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.4rem;
}

.affil-tag {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  color: var(--ink);
}

.team-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
  margin-top: 3rem;
}

.team-stat {
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 1.2rem;
  text-align: center;
}

.team-stat-num {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--accent-text);
}

.team-stat-label {
  font-size: var(--text-2xs);
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-top: 0.3rem;
}

/* ── VALUES ── */
.values-section {
  background: var(--navy-3);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.values-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
  margin-top: 2.6rem;
}

.value-card {
  padding: 1.8rem 1.6rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--navy) 50%, transparent);
}

.value-name {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 0.6rem;
}

.value-desc {
  font-size: var(--text-sm);
  color: var(--muted);
  line-height: 1.65;
}

/* ── CTA BANNER (school-banner pattern) ── */
.cta-banner {
  background: linear-gradient(120deg, #06245f, var(--navy));
  border: 1px solid var(--line-y);
  border-radius: var(--radius-lg);
  padding: 3rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  margin-top: 2rem;
  flex-wrap: wrap;
  position: relative;
  overflow: hidden;
}

.cta-banner::before {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(-32deg, transparent 0 70px, rgba(254, 191, 0, 0.05) 70px 72px);
  pointer-events: none;
}

.cta-banner > div {
  position: relative;
  z-index: 1;
}

/* .cta-banner's own gradient (#06245f -> --navy) never flips for light mode
   either — same reasoning as the hero pins above. */
.cta-banner h3 {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #f5f8ff;
}

.cta-banner h3 span {
  color: var(--yellow);
}

.cta-banner p {
  color: #c4d2f0;
  font-size: var(--text-sm);
  margin-top: 0.6rem;
  max-width: 480px;
  line-height: 1.6;
}

.cta-banner-ctas {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

/* ── CONTACT ── */
.contact-section {
  background: linear-gradient(180deg, var(--navy-2), var(--navy));
}

.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 3rem;
  margin-top: 2.6rem;
  align-items: start;
}

.contact-card {
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 1.6rem;
}

.contact-card h4 {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 0.7rem;
}

.contact-card p,
.contact-card a {
  font-size: var(--text-sm);
  color: var(--ink);
}

.contact-card a:hover {
  color: var(--accent-text);
}

.contact-ctas {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}

.contact-form-fields {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin-top: 1rem;
}

.contact-form-fields label {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.3rem;
  display: block;
}

.contact-form-fields input,
.contact-form-fields textarea {
  width: 100%;
  background: var(--navy);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.8rem;
  color: var(--white);
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-sm);
}

.contact-form-fields input:focus,
.contact-form-fields textarea:focus {
  outline: none;
  border-color: var(--blue);
}

/* ── SPONSORS ── */
.sponsors {
  padding: 3rem 2rem;
  border-top: 1px solid var(--line);
}

.sponsors-label {
  font-size: var(--text-2xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  margin-bottom: 1.5rem;
}

.sponsors-list {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 2rem;
  align-items: center;
}

.sponsor-tag {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(196, 210, 240, 0.45);
  transition: color 0.2s;
}

/* Same fix as .ap-credit — --ink at 45% opacity goes near-invisible once
   the (flippable) page ground behind it turns light. */
[data-theme='light'] .sponsor-tag {
  color: rgba(42, 51, 80, 0.45);
}

.sponsor-tag:hover {
  color: var(--white);
}

/* ── FOOTER ── */
footer.site-footer {
  background: var(--navy-2);
  border-top: 1px solid var(--line);
  padding: 3rem 2rem 1.5rem;
}

.site-footer__inner {
  max-width: 1280px;
  margin: 0 auto;
}

.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 3rem;
  margin-bottom: 2rem;
}

/* Legacy footer (sections/footer.liquid, unwired on main since tkd-footer).
   Shipped with no mobile override: 2fr 1fr 1fr 1fr + 3rem gaps is 449px on a
   390px phone -- the sideways scroll on every page of the published theme.
   Hot-fixed on the live theme 2026-09-09 with exactly these rules; kept here
   so re-wiring footer.liquid can't bring the overflow back. */
@media (max-width: 1059px) {
  .footer-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 2rem;
  }

  .footer-grid .footer-brand {
    grid-column: 1 / -1;
  }
}

@media (max-width: 719px) {
  .footer-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
  }
}

.footer-brand img {
  height: 52px;
  width: auto;
  margin-bottom: 1rem;
}

.footer-brand p {
  font-size: var(--text-xs);
  color: var(--muted);
  line-height: 1.6;
  max-width: 280px;
}

.footer-col h4 {
  margin-bottom: 1rem;
}

.footer-col ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.footer-col ul li a {
  font-size: var(--text-sm);
  color: var(--muted);
  transition: color 0.2s;
}

.footer-col ul li a:hover {
  color: var(--accent-text);
}

.lang-flags {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
  flex-wrap: wrap;
}

.lang-flag {
  font-size: var(--text-2xs);
  padding: 0.18rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--muted);
}

.lang-flag[aria-current='true'] {
  color: var(--accent-text);
  border-color: var(--line-y);
}

.footer-bottom {
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.footer-bottom p {
  font-size: var(--text-2xs);
  color: var(--muted);
}

.footer-meta {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* Phones: the legal row was one non-wrapping flex line -- "Privacy" pinned
   bottom-left, the AP credit squeezed into a three-line middle column, the
   GitHub mark and version pushed right (2026-09-09). Stack it: copyright,
   then Privacy / GitHub / version on one line, the credit on its own. */
@media (max-width: 719px) {
  .footer-bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.6rem;
  }

  .footer-meta {
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 1.25rem;
  }

  .footer-meta .ap-credit {
    flex-basis: 100%;
    order: 1;
  }
}

.footer-version {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 0.15rem 0.6rem;
}

.ap-credit {
  font-size: var(--text-2xs);
  /* 0.65, not 0.4: at 40% this measured 2.87:1 on --navy-2 (axe, every
     page, 2026-09-09) against the 4.5:1 AA floor for 15px text. 65% lands
     near 5.4:1 and still reads as the quiet line it is meant to be. */
  color: rgba(196, 210, 240, 0.65);
}

/* Same subtle low-emphasis treatment, but --ink at 40% opacity is close to
   invisible once the footer ground flips light — swap to dark --ink so it
   stays legibly faint rather than disappearing (0.75 clears 4.5:1 on a
   white ground; the social icons keep their own lower emphasis). */
[data-theme='light'] .ap-credit {
  color: rgba(42, 51, 80, 0.75);
}

[data-theme='light'] .social-icon {
  color: rgba(42, 51, 80, 0.4);
}

.ap-credit a {
  /* 0.7, not 0.6: 60% yellow on --navy-2 measured 4.47:1 (axe), a hair
     under the 4.5:1 AA floor for 15px text; 70% is ~5.7:1. */
  color: rgba(254, 191, 0, 0.7);
  /* WCAG 1.4.1: a link inside running text can't rely on colour alone. */
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.ap-credit a:hover {
  color: var(--accent-text);
}

/* AP's own identity row (GitHub + social) — monochrome line-art icons per
   AP's house visual identity, never colour brand icons. Lives next to the
   AP credit line since both are agency-identity elements, not the client
   brand's own content. */
.footer-social {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.social-icon {
  display: inline-flex;
  color: rgba(196, 210, 240, 0.4);
}

.social-icon:hover,
.social-icon:focus-visible {
  color: var(--accent-text);
}

/* ── TKD-UX-SPEC-002 §6 — FOOTER ──
   sections/tkd-footer.liquid. Five tiers, two-tone per §6.1: tiers 1-4 on
   --navy, tier 5 (.tkd-footer__legal) on the darker --navy-2 — the same two
   grounds .site-footer already used, now split explicitly instead of one
   flat surface. Breakpoints are the spec's own derived set (§8.2:
   1060/720), not the pre-existing ad-hoc values elsewhere in this file —
   scoped to the rebuilt surfaces only, per the independence/sequencing
   decision; PDP/cart/search keep their current breakpoints for now. */
.tkd-footer {
  display: block;
}

.tkd-footer__top {
  display: block;
  width: 100%;
  height: 64px;
  background: var(--navy-2);
  border: none;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  cursor: pointer;
  transition: color 0.18s;
}

.tkd-footer__top:hover,
.tkd-footer__top:focus-visible {
  color: var(--accent-text);
}

.tkd-footer__body {
  background: var(--navy);
  padding: 2.5rem 0;
}

.tkd-footer__inner {
  max-width: var(--deck-max, 1280px);
  margin: 0 auto;
  padding-inline: var(--deck-gutter, 2rem);
}

.tkd-footer__inner + .tkd-footer__inner {
  margin-top: 2rem;
}

.tkd-footer__newsletter {
  padding: 1.5rem 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.tkd-footer__newsletter-heading {
  font-size: var(--text-sm);
  color: var(--white);
  margin-bottom: 0.85rem;
}

.tkd-footer__newsletter-field {
  display: flex;
  gap: 0.6rem;
  max-width: 420px;
}

.tkd-footer__newsletter-field input {
  flex: 1;
  min-width: 0;
  font-size: 16px; /* iOS zoom floor, spec-002 §8.4 */
  padding: 0.6rem 0.8rem;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
}

.tkd-footer__newsletter-submit {
  flex-shrink: 0;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.tkd-footer__newsletter-message {
  display: block;
  margin-top: 0.6rem;
  font-size: var(--text-2xs);
  color: var(--muted);
}

.tkd-footer__newsletter-message--success {
  color: var(--ok);
}

.tkd-footer__columns {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 2rem;
  padding-top: 2rem;
}

@media (max-width: 1059px) {
  .tkd-footer__columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 719px) {
  .tkd-footer__columns {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .tkd-footer__col {
    border-bottom: 1px solid var(--line);
  }

  .tkd-footer__col-details summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    cursor: pointer;
    padding: 0.85rem 0;
    list-style: none;
  }

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

  .tkd-footer__col-details summary::after {
    content: '+';
    font-size: var(--text-sm);
    color: var(--muted);
  }

  .tkd-footer__col-details[open] summary::after {
    content: '\2212'; /* minus sign */
  }

  .tkd-footer__col-details:not([open]) ul {
    display: none;
  }

  .tkd-footer__col-details ul {
    padding-bottom: 0.85rem;
  }
}

@media (min-width: 720px) {
  /* Desktop/tablet: always-visible columns, not a real disclosure — force
     the content open regardless of the `open` attribute's actual state (a
     user who toggled one closed on a phone keeps that DOM state across a
     resize) and strip the summary's own interactivity/marker so it reads
     as a plain heading. Free per spec-002 §6.3: no min-width floor is
     needed, and this uses only <details>/<summary>'s native semantics. */
  .tkd-footer__col-details summary {
    pointer-events: none;
    cursor: default;
  }

  .tkd-footer__col-details summary::-webkit-details-marker,
  .tkd-footer__col-details summary::marker {
    display: none;
  }

  .tkd-footer__col-details ul {
    display: flex !important;
  }
}

.tkd-footer__locale-row {
  padding: 1.25rem 0;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* Light/dark toggle — sat in the header's .header-actions until 2026-09-10,
   where it was the one control that pushed the phone bar (logo, language,
   account, cart, hamburger) onto two lines. Lives beside the country
   selector now, styled as its sibling: same --line border, same 44px target
   (responsive-standard). */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s;
}

.theme-toggle:hover,
.theme-toggle:focus-visible {
  color: var(--accent-text);
  border-color: var(--line-y);
}

.theme-toggle__icon--moon {
  display: none;
}

[data-theme='light'] .theme-toggle__icon--sun {
  display: none;
}

[data-theme='light'] .theme-toggle__icon--moon {
  display: block;
}

.tkd-footer__legal {
  background: var(--navy-2);
}

.tkd-footer__legal-inner {
  padding-block: 1.25rem;
}

/* ── TKD-UX-SPEC-002 §3/§4 — DECK GRID + CARD SHELL ──
   sections/tkd-deck.liquid, sections/tkd-fold.liquid, snippets/tkd-card.liquid.
   Breakpoints here (1400/1060/720) are the spec's own derived values (from
   §8.2's tile-geometry math), scoped ONLY to these new components per the
   2026-09-09 decision to converge new surfaces first and defer a sitewide
   breakpoint migration (PDP/cart/search keep their existing ad-hoc values —
   see docs/HANDOFF.md). Uses --deck-* (brand/tokens.json, storefront-only,
   not shared with events/trackside-intake) for the grid geometry and the
   existing shared --text-*/--radius-*/palette tokens for everything else. */
.tkd-deck-section {
  padding-block: 3.2rem;
}

.tkd-deck-inner {
  max-width: var(--deck-max);
  margin-inline: auto;
  padding-inline: var(--deck-gutter);
}

.tkd-deck__heading {
  margin-bottom: 1.2rem;
}

.tkd-deck {
  display: grid;
  /* --tkd-deck-cols is set inline per-instance from the section's "Columns
     (desktop, >=1400px)" setting (sections/tkd-deck.liquid); 4 is the
     fallback for any usage that omits it. */
  grid-template-columns: repeat(var(--tkd-deck-cols, 4), minmax(0, 1fr));
  column-gap: var(--deck-col-gap);
  row-gap: var(--deck-row-gap);
}

@media (max-width: 1399px) {
  .tkd-deck {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 1059px) {
  .tkd-deck {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 719px) {
  .tkd-deck {
    grid-template-columns: minmax(0, 1fr);
  }

  .tkd-deck > .tkd-card--half,
  .tkd-deck > .tkd-icon-strip {
    grid-column: 1 / -1;
  }
}

.tkd-deck > .tkd-card--full {
  grid-column: 1 / -1;
}

.tkd-deck > .tkd-card--half {
  grid-column: span 2;
}

@media (max-width: 1059px) {
  .tkd-deck > .tkd-card--half {
    grid-column: 1 / -1;
  }
}

/* The card shell -- identical for every fill. Equal-height rows: the grid
   item stretches (CSS Grid's own default align-items: stretch), and
   .tkd-card itself fills that stretched height, with the footer link
   pinned to the bottom via margin-top: auto -- ragged card bottoms never
   happen in a dense grid (spec §4.1). */
.tkd-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 20px;
}

.tkd-card__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--white);
  text-decoration: none;
  margin-bottom: 0.9rem;
}

@media (max-width: 1059px) {
  .tkd-card__heading {
    font-size: var(--text-xs);
  }
}

.tkd-card__heading:hover,
.tkd-card__heading:focus-visible {
  color: var(--accent-text);
}

.tkd-card__heading--static {
  cursor: default;
}

.tkd-card__chevron svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.tkd-card__fill {
  flex: 1 0 auto;
}

.tkd-card__footer-link {
  margin-top: auto;
  padding-top: 0.9rem;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: var(--yellow);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  text-decoration: underline;
}

.tkd-card__footer-link:hover,
.tkd-card__footer-link:focus-visible {
  color: var(--yellow-hi);
}

/* Fills A/F (quadrant/brand tile) and B (product quad) -- a 2x2 (or 2x3 for
   a 6-slot brand tile) sub-grid of tiles. Tile width floor per §8.2 is
   ~140px; that constraint lives in the deck/card widths above, not here. */
.tkd-card__quad {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.tkd-card__quad--brands {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.tkd-card__tile {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  color: var(--ink);
  text-decoration: none;
}

.tkd-card__tile-image {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: var(--navy-2);
}

/* A collection with no featured image renders an empty plate in the same
   box (snippets/tkd-collection-tile.liquid), so the grid keeps its rhythm
   instead of a label floating in a blank cell. */
.tkd-card__tile-image--empty {
  display: block;
  background: var(--navy-3);
}

.tkd-card__tile-label,
.tkd-card__tile-title {
  font-size: var(--text-3xs);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

@media (max-width: 359px) { /* component exception: 320-class phones only — one-line tile titles */
  .tkd-card__tile-title {
    -webkit-line-clamp: 1;
  }
}

.tkd-card__tile-label {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--weight-bold);
  color: var(--white);
  -webkit-line-clamp: 2;
}

.tkd-card__tile-price {
  font-size: var(--text-3xs);
  font-weight: var(--weight-bold);
  color: var(--accent-text);
}

.tkd-card__tile--product {
  gap: 0.3rem;
}

/* Fill D -- price bands: a label only, no image, no product data. */
.tkd-card__tile--band {
  align-items: center;
  justify-content: center;
  text-align: center;
  border: 1px solid var(--line);
  padding: 1.4rem 0.6rem;
  aspect-ratio: 1 / 1;
}

.tkd-card__tile--band .tkd-card__tile-label {
  color: var(--ink);
}

/* Fill E -- single promo: one large image, one CTA. */
.tkd-card__promo {
  position: relative;
  display: block;
  height: 100%;
  min-height: 220px;
  text-decoration: none;
  overflow: hidden;
}

.tkd-card__promo-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.tkd-card__promo-content {
  position: absolute;
  left: 1rem;
  bottom: 1rem;
  right: 1rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
}

.tkd-card__promo-heading {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--white);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
}

/* The static "Why TKD" icon strip (spec §5 row 10) -- not a card, so it does
   not use .tkd-card at all: no heading-row-as-link, no footer link. */
.tkd-icon-strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  gap: 1.5rem;
  background: var(--navy-3);
  border: 1px solid var(--line);
  padding: 1.6rem;
}

.tkd-icon-strip__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  text-align: center;
}

.tkd-icon-strip__num {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--yellow);
}

.tkd-icon-strip__label {
  font-size: var(--text-2xs);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ── TKD-UX-SPEC-002 §5.1 — THE FOLD SPLIT ──
   sections/tkd-fold.liquid. Replaces sections/hero.liquid on the homepage
   (thekartdepot.com no longer ships a billboard hero; Evolution's own
   photographic hero is a separate, unaffected codebase). Hard ceiling per
   v1 §4.3, reaffirmed by spec-002: 420px desktop / 360px tablet / 300px
   mobile (spec-002 §8.3's per-breakpoint table). */
.tkd-fold {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2.4fr);
  gap: var(--deck-col-gap);
  max-width: var(--deck-max);
  margin-inline: auto;
  padding-inline: var(--deck-gutter);
}

/* height, not max-height: the row-track sizing below needs a concrete box
   to distribute, and an aspect-ratio-less tile image (next rule) needs a
   real cell height to fill via object-fit -- a mere cap on a shrink-to-fit
   grid left both children shorter than the "hard ceiling" and let a square
   aspect-ratio image overflow into the row below it (visible as two tile
   labels overlapping until this was caught in a live preview, not just
   theme:check, which cannot see rendered layout). */
.tkd-fold__promo,
.tkd-fold__router {
  height: 420px;
}

.tkd-fold__router {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.tkd-fold__router .tkd-card__tile {
  height: 100%;
  overflow: hidden;
}

/* flex-basis 0 (not auto, not 100%) is deliberate: `auto` resolves the basis
   from the image's own height, and a percentage height on a column flex
   item needs a definite ancestor height to resolve at all -- when it does
   not, the browser falls back to the image's INTRINSIC size, so each tile's
   image claimed a different height off its own photo's aspect ratio
   (measured 248-310px against a 204px tile) and squeezed the label flex
   sibling to 0 in the process. Starting from 0 and growing to fill
   leftover space is the standard "sibling keeps its natural size, this one
   takes the rest" pattern -- verified in a live preview, not just
   theme:check, which cannot see this class of layout bug. */
.tkd-fold__router .tkd-card__tile-image {
  aspect-ratio: auto;
  flex: 1 1 0%;
  min-height: 0;
}

.tkd-fold__router .tkd-card__tile-label {
  flex: none;
}

@media (max-width: 1059px) {
  .tkd-fold {
    grid-template-columns: minmax(0, 1fr);
  }

  .tkd-fold__promo {
    order: 1;
  }

  .tkd-fold__router {
    order: 2;
  }

  .tkd-fold__promo,
  .tkd-fold__router {
    height: 360px;
  }
}

@media (max-width: 719px) {
  /* On a phone the customer wants the router before the billboard (§5.1). */
  .tkd-fold__promo {
    order: 2;
  }

  /* 3x2, not 2x3: inside the 300px ceiling, three rows left each tile ~65px
     of image -- object-fit: cover showed a cropped sliver of every photo with
     its top hidden under the header, which read as the nav overlapping the
     page (2026-09-09). Two rows of three keep the ceiling and give each
     tile a ~110px near-square image on a 390px phone. */
  .tkd-fold__router {
    order: 1;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }

  .tkd-fold__router .tkd-card__tile-label {
    font-size: var(--text-3xs);
  }

  .tkd-fold__promo,
  .tkd-fold__router {
    height: 300px;
  }
}

/* ── SEARCH RESULTS ── */
.search-form {
  display: flex;
  gap: 0.6rem;
  margin-top: 1.6rem;
  max-width: 760px;
  flex-wrap: wrap;
}

.search-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}

.search-sort {
  display: flex;
  align-items: center;
}

.search-sort__label {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-right: 0.5rem;
}

.search-sort__select {
  background: var(--navy-3);
  color: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.4rem 0.6rem;
  font-family: 'Barlow', sans-serif;
  min-width: 11rem;
  max-width: 100%;
}

.search-content-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.25rem;
}

.search-content-card {
  display: block;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 1.4rem 1.5rem;
  transition: border-color 0.2s, transform 0.2s;
}

.search-content-card:hover {
  border-color: var(--blue);
  transform: translateY(-3px);
}

.search-content-card__type {
  font-size: var(--text-2xs);
  color: var(--accent-text);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: var(--weight-bold);
  margin-bottom: 0.4rem;
}

.search-content-card__title {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--white);
  margin-bottom: 0.6rem;
}

.search-content-card__excerpt {
  font-size: var(--text-sm);
  color: var(--muted);
  line-height: 1.6;
  margin-bottom: 0.9rem;
}

.search-content-card__more {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
}

/* Shared by the collection grid and search results. */
.tkd-sort-bar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

/* ── BREADCRUMB — TKD-STORE-UX-SPEC §5.1 ──
   "Home › Engines › Vortex › in --muted, current page in --ink, separators ›
   in --muted." --muted is 15.04px here, clearing §13's "never below 14px". */
.breadcrumb {
  margin-bottom: 1.2rem;
}

.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.breadcrumb__item {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--text-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.breadcrumb__link {
  color: var(--muted);
  text-decoration: none;
}

.breadcrumb__link:hover,
.breadcrumb__link:focus-visible {
  color: var(--accent-text);
  text-decoration: underline;
}

.breadcrumb__sep {
  color: var(--muted);
}

.breadcrumb__current {
  color: var(--ink);
}

/* ── PLP: FILTER RAIL + GRID — TKD-STORE-UX-SPEC §5.1/§5.2 ──
   The rail is 260px and sticky per §5.1. .site-header is position: sticky /
   top: 0 and measures 103px on desktop, so the spec's 108px offset clears it
   with 5px to spare. */
.plp {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 2.4rem;
  align-items: start;
}

.plp__main {
  min-width: 0;
}

.plp__toolbar {
  justify-content: space-between;
}

.plp__count {
  font-size: var(--text-2xs);
  color: var(--muted);
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}

.plp__sort {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.plp-rail {
  position: sticky;
  top: 108px;
  background: var(--navy);
  border: 1px solid var(--line);
  padding: 1.6rem;
}

.plp-rail__heading {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--white);
  margin-bottom: 1.2rem;
}

.plp-group + .plp-group {
  border-top: 1px solid var(--line);
  margin-top: 2rem;
  padding-top: 2rem;
}

.plp-group__label {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink);
  margin-bottom: 0.9rem;
}

.plp-options {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.plp-option__label {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.7rem;
  cursor: pointer;
}

/* §5.2: "Checkbox: 18x18, 1px solid var(--line); checked = --yellow fill with
   a --navy check glyph." accent-color paints the box and the glyph together
   and keeps the control native, so it stays keyboard- and AT-operable. */
.plp-option__box {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--yellow);
  cursor: pointer;
}

.plp-option__text {
  font-size: var(--text-2xs);
  color: var(--white);
}

.plp-option__count {
  font-size: var(--text-2xs);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* §5.2: an option with no results is "disabled and dimmed to --muted, not
   hidden — disappearing options make the UI feel broken." */
.plp-option--empty .plp-option__text,
.plp-option--empty .plp-option__count {
  color: var(--muted);
}

.plp-option--empty .plp-option__label {
  cursor: not-allowed;
}

.plp-price {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0.7rem;
}

.plp-price__field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.plp-price__legend {
  font-size: var(--text-2xs);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.plp-price__field input {
  width: 100%;
  padding: 0.5rem 0.6rem;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: 0;
  color: var(--white);
  font-family: inherit;
  font-size: var(--text-2xs);
}

.plp-price__go {
  grid-column: 1 / -1;
  /* .btn-outline is yellow text on whatever sits behind it; here that is the
     light price-filter panel, which measured 1.44:1 (axe, 2026-09-09). A
     navy fill keeps the yellow and clears AA at ~11:1 on any ground; the
     .btn-outline hover (yellow fill, navy text) is unchanged. */
  background: var(--navy);
}

.plp-rail__apply {
  width: 100%;
  margin-top: 1.6rem;
}

/* §5.2: chips are "--navy-3 bg, 1px solid var(--yellow), --white label, x in
   --yellow. Plus a Clear all link." */
.plp-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1.5rem;
}

.plp-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.35rem 0.8rem;
  background: var(--navy-3);
  border: 1px solid var(--yellow);
  color: var(--white);
  font-size: var(--text-2xs);
  text-decoration: none;
}

.plp-chip__x {
  color: var(--yellow);
  font-size: var(--text-sm);
  line-height: 1;
}

.plp-chip:hover,
.plp-chip:focus-visible {
  background: var(--navy-2);
}

.plp-chips__clear {
  font-size: var(--text-2xs);
  color: var(--accent-text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* §5.1's grid columns: 4 @1440 / 3 @1024. The global .products-grid track is
   minmax(258px, 1fr), which yields only 3 columns in the 996px the rail leaves
   at 1440px, and 2 in the 700px it leaves at 1024px. 210px is the widest track
   that satisfies both of the spec's counts: 1008.5/222.5 = 4.5 -> 4 columns at
   1440, 712.5/222.5 = 3.2 -> 3 at 1024. Narrowed here and here only — the
   homepage row and search results keep the wider track. */
.plp__main .products-grid {
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}

@media (max-width: 900px) { /* component exception: rail + 3-up grid fit down to 900 (note above); below, the rail stacks */
  .plp {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Sticky is wrong once the rail is a full-width block above the grid: it
     would pin the whole rail over the products while scrolling. */
  .plp-rail {
    position: static;
  }

  .plp-options {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  }
}

.product-card__cta {
  padding: 0.45rem 0.95rem;
  font-size: var(--text-xs);
}

.product-price__soldout {
  color: var(--muted);
  font-size: var(--text-sm);
}

.tkd-pagination {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 3rem;
  flex-wrap: wrap;
}

.tkd-pagination__page {
  opacity: 0.7;
}

/* Real product count on a category tile — only rendered once the tile's
   collection is published and therefore resolvable in Liquid. */
.cat-total {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-text);
}

/* ── ENQUIRY FORM ── */
.contact-form-fields select {
  background: var(--navy-3);
  color: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.55rem 0.7rem;
  font-family: 'Barlow', sans-serif;
  font-size: var(--text-base);
  width: 100%;
}

.contact-form-fields select:focus,
.contact-form-fields input:focus,
.contact-form-fields textarea:focus {
  outline: none;
  border-color: var(--blue);
}

.field-optional {
  color: var(--muted);
  font-weight: var(--weight-regular);
  text-transform: none;
  letter-spacing: 0;
}

.contact-submit {
  width: fit-content;
}

.form-success {
  color: var(--accent-text);
  font-weight: var(--weight-bold);
}

.form-error {
  color: var(--bad);
  font-size: var(--text-sm);
}

/* ── ENQUIRY CTA (products we don't hold) ── */
.enquiry-cta {
  background: var(--navy-3);
  border: 1px solid var(--line-y);
  border-left: 4px solid var(--yellow);
  border-radius: var(--radius-md);
  padding: 1.2rem 1.3rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.55rem;
}

.enquiry-cta__status {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0;
}

.enquiry-cta__body {
  font-size: var(--text-sm);
  color: var(--ink);
  line-height: 1.55;
  margin: 0;
  max-width: 46ch;
}

.enquiry-cta__button {
  margin-top: 0.2rem;
}

.enquiry-cta__sku {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* ── BRAND LOGO ── */
.site-header__brand .brand-logo {
  height: 40px;
  width: auto;
}

.footer-brand .footer-logo {
  height: 54px;
  width: auto;
  margin-bottom: 0.9rem;
}

@media (max-width: 719px) { /* store sm */
  .site-header__brand .brand-logo {
    height: 36px;
  }

  .hero {
    min-height: 300px;
    padding: 2rem 1.25rem;
  }

  .hero-panel {
    max-width: none;
  }

  .hero-credentials {
    padding: 1.4rem 1.25rem;
  }

  /* Four stacked stats were 337px of the 844px mobile hero. Two-up keeps them
     to roughly a fifth of that, below the fold-critical region. */
  .hero-stats {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1.4rem 2rem;
  }

  .hero h1,
  h1.page-h1 {
    font-size: clamp(4.56rem, 14vw, 5.76rem);
  }

  .race-system-catalog {
    grid-template-columns: minmax(0, 1fr);
  }

  .cat-card--major,
  .cat-card--compact {
    grid-column: 1 / -1;
  }

  .cat-card--compact {
    grid-template-columns: 2.35rem 2.9rem minmax(0, 1fr);
  }

  .support-contact-band {
    padding: 44px 18px;
  }

  .support-contact-card__actions {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* .lang-switch used to hide below 520px. TKD-UX-SPEC-002 §8.3 wants the
   language selector functional at every width ("full-width sheet from
   bottom" below 720px is a future enhancement, not a requirement to be
   visible at all) — .tkd-lang stays visible here by design, not omission. */

/* Sponsor tags that actually go somewhere. */
a.sponsor-tag--link {
  transition: border-color 0.2s, color 0.2s;
}

a.sponsor-tag--link:hover,
a.sponsor-tag--link:focus-visible {
  border-color: var(--yellow);
  color: var(--accent-text);
}

/* ── CONTENT PAGES ──
   Styled from semantic elements only. The body of these pages is authored in
   Shopify's rich-text editor, which rewrites markup it does not recognise, so
   nothing here may depend on a custom class inside .page-content. */
.page-title {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: clamp(3.52rem, 5vw, 5.44rem);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 0.98;
  color: var(--white);
  margin-bottom: 0.8rem;
  text-wrap: balance;
}

.page-standfirst {
  font-size: var(--text-base);
  color: var(--ink);
  max-width: 62ch;
  line-height: 1.6;
  margin-bottom: 2.4rem;
}

.page-content {
  max-width: 68ch;
  color: var(--ink);
  font-size: var(--text-base);
  line-height: 1.75;
}

.page-content > * + * { margin-top: 1.1rem; }

.page-content h2 {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: clamp(2.4rem, 3vw, 3.36rem);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--white);
  margin-top: 3rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--line);
}

.page-content h3 {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-top: 2rem;
}

.page-content a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 2px; }
.page-content a:hover { color: var(--yellow-hi); }
.page-content ul, .page-content ol { padding-left: 1.2rem; }
.page-content li + li { margin-top: 0.4rem; }
.page-content strong { color: var(--white); }

.page-content blockquote {
  border-left: 3px solid var(--yellow);
  padding-left: 1.1rem;
  color: var(--white);
  font-style: italic;
}

.page-content hr { border: 0; border-top: 1px solid var(--line); margin: 2.4rem 0; }

/* A person: image + caption, from a plain <figure> the editor produces. */
.page-content figure { margin: 1.6rem 0; }
.page-content figure img { border-radius: var(--radius-md); border: 1px solid var(--line); }
.page-content figcaption {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.5rem;
}
.page-content img { max-width: 100%; height: auto; }

/* ── LAYOUT LANGUAGE (shared primitives) ──
   Racing-crowd layout refresh, 2026-09. Reference: a booking-cart prototype
   Emerson built at thekartdepot.netlify.app ("Race Day Loadout") — its
   colours were explicitly NOT adopted (Trackside Navy stays as documented in
   docs/BRAND.md), only its layout language: HUD-style mono kicker labels,
   bordered price/feature panel cards, pill-tag rows, checkbox-row line
   items, sticky totals, hairline dividers, tabular numerals. See docs/BRAND.md
   "Layout language" for the prose spec. These 7 classes are hand-mirrored
   into cloudflare/events/public/styles.css and the screen-chrome block of
   cloudflare/trackside-intake/public/index.html — same discipline already
   used for the colour tokens, but these are hand-authored, not generated. */

/* .kicker-mono — small mono "telemetry" label. Canonical rule for what used
   to be separately-declared .hero-eyebrow / .section-label treatments;
   those two class names stay in the section liquid files (only spacing is
   still declared under their own names, just above) and now render through
   this shared rule. */
.kicker-mono,
.hero-eyebrow,
.section-label,
.footer-col h4 {
  display: block;
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-text);
}

.kicker-mono::before,
.hero-eyebrow::before,
.section-label::before,
.footer-col h4::before {
  content: '\2014\a0';
}

.kicker-mono--muted {
  color: var(--muted);
}

/* .pill-badge / .pill-badge-row — generalizes .badge/.badge-hero (kept as
   aliases below, their liquid markup is unchanged) into a reusable tag,
   plus a wrapping row for a feature-tag list under a panel. */
.pill-badge,
.badge-hero {
  display: inline-block;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.22rem 0.6rem;
  border-radius: var(--radius-pill);
  background: rgba(254, 191, 0, 0.16);
  color: var(--accent-text);
  border: 1px solid var(--line-y);
}

.pill-badge--blue,
.badge {
  display: inline-block;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.22rem 0.6rem;
  border-radius: var(--radius-pill);
  background: rgba(10, 76, 255, 0.2);
  color: #9db9ff;
  border: 1px solid rgba(10, 76, 255, 0.4);
}

/* #9db9ff is a light blue tuned for this pill's 20%-opacity fill over the
   dark page ground; once the ground flips light the same fill reads pale,
   and light-on-pale fails contrast. --blue-hi is already deepened for light
   mode, so reuse it here instead of inventing a third blue. */
[data-theme='light'] .pill-badge--blue,
[data-theme='light'] .badge {
  color: var(--blue-hi);
}

.pill-badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* .hr-hairline — a reusable divider for new markup (e.g. inside
   .panel-card, the product-page overlay). .hero-stats and .footer-bottom
   keep their own border-top declarations since those are container edges
   inside a flex layout, not standalone divider elements; .page-content hr
   is raw rich-text-editor output and can't carry a class, so it keeps its
   own rule too — all three already resolve through the same var(--line). */
.hr-hairline {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 1.4rem 0;
}

/* .panel-card — bordered price/feature card. Generalizes .enquiry-cta with
   a right-aligned price block, a hairline, and a pill-badge-row. */
.panel-card {
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 1.4rem 1.5rem;
}

.panel-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.panel-card__title {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--white);
  margin: 0 0 0.3rem;
}

.panel-card__desc {
  font-size: var(--text-sm);
  color: var(--ink);
  margin: 0;
  max-width: 42ch;
}

.panel-card__price {
  flex: 0 0 auto;
  text-align: right;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--white);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.panel-card__price-unit {
  display: block;
  font-size: var(--text-2xs);
  font-weight: var(--weight-regular);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.panel-card .hr-hairline {
  margin: 1rem 0;
}

/* .checkbox-row — selectable line-item row (formalizes the RSVP microsite's
   .day-options label / .check-row / .cart-card-top). */
.checkbox-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 0.75rem 0.9rem;
  cursor: pointer;
}

.checkbox-row.is-selected {
  border-color: var(--line-y);
  background: rgba(254, 191, 0, 0.08);
}

.checkbox-row input[type='checkbox'] {
  width: 18px;
  height: 18px;
  accent-color: var(--yellow);
  flex: 0 0 auto;
}

/* .sticky-total-bar — running total + CTA pinned to the bottom of a
   cart/quote flow. Scoped to the RSVP microsite's custom checkout-adjacent
   flow only; the Shopify cart page keeps Dawn's own totals UI untouched. */
.sticky-total-bar {
  position: sticky;
  bottom: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  background: var(--navy-2);
  border-top: 1px solid var(--line-y);
  padding: 1rem 1.25rem calc(1rem + env(safe-area-inset-bottom));
}

.sticky-total-bar__total {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--white);
  font-variant-numeric: tabular-nums;
}

/* .tabular-num — telemetry-style numeral treatment for prices/stats/counts.
   Applied selectively; not every number in the theme needs this. */
.tabular-num {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-variant-numeric: tabular-nums;
}

/* ── PRODUCT / CART (stock Dawn overlay) ──
   The product page (main-product.liquid) and cart page (main-cart-items.liquid,
   main-cart-footer.liquid) are stock Dawn markup, unlike the rest of the
   storefront — this is a small, CSS-only overlay onto Dawn's own class names
   so pricing reads with the same tabular-numeral treatment as the rest of the
   site, without touching Dawn's liquid, disclosures, or checkout-adjacent
   cart JS. Collection page needs no overlay: main-collection-banner.liquid
   and main-collection-product-grid.liquid already reuse the custom
   .tkd-section/.section-label/.product-card classes above. */
.price .price-item,
.totals__total-value,
.cart-item__price-wrapper .price-item {
  font-variant-numeric: tabular-nums;
}

/* ── EVENTS LIST ── */
.events-grid {
  margin-top: 2.4rem;
}

.events-loading {
  color: var(--muted);
  font-size: var(--text-sm);
}

.event-card {
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-left: 4px solid var(--yellow);
  border-radius: var(--radius-md);
  padding: 1.4rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.event-card__series {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0;
}

.event-card__name {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--white);
  margin: 0;
  line-height: 1.05;
}

.event-card__dates {
  color: var(--white);
  font-weight: var(--weight-bold);
  margin: 0 0 0.4rem;
  font-variant-numeric: tabular-nums;
}

.event-card__meta {
  margin: 0 0 1rem;
  display: grid;
  gap: 0.15rem;
}

.event-card__meta dt {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.event-card__meta dd {
  margin: 0 0 0.5rem;
  font-size: var(--text-sm);
  color: var(--ink);
  line-height: 1.5;
}

.event-card__cta,
.events-fallback-cta {
  align-self: flex-start;
  margin-top: auto;
  padding: 0.5rem 1rem;
  font-size: var(--text-xs);
}

/* ── SHOPIFY COOKIE CONSENT BANNER ──
   The banner itself is injected at runtime by Shopify's customer-privacy API,
   not by this theme — there is no Liquid for it. Its real size/position
   controls live in Shopify admin → Settings → Customer privacy → Cookie
   banner; this block only shrinks what ships today. The #shopify-pc__ ids are
   Shopify internals and can be renamed without notice: if the banner suddenly
   renders full-size again, check that these selectors still match before
   assuming a regression here. */
#shopify-pc__banner {
  inset: auto 1rem 1rem auto !important;
  max-width: 24rem !important;
}

/* NB: shopify-pc__banner__dialog / __wrapper / __body / __btns are CLASSES;
   only the banner root and the individual buttons are ids. Shopify's own
   injected <style id="shopify-pc__banner__styles"> sizes the copy in rem, so
   it inflates with our raised root — these pin it back to the token scale. */
.shopify-pc__banner__dialog {
  padding: 0.85rem 1rem !important;
  background: var(--navy-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: var(--radius-sm) !important;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4) !important;
}

.shopify-pc__banner__body,
.shopify-pc__banner__body p {
  margin: 0 0 0.5rem !important;
  color: var(--ink) !important;
  font-size: var(--text-2xs) !important;
  line-height: 1.35 !important;
}

#shopify-pc__banner__body-title {
  margin-bottom: 0.25rem !important;
  font-family: 'Barlow Condensed', sans-serif !important;
  font-size: var(--text-xs) !important;
  line-height: 1.15 !important;
}

.shopify-pc__banner__btns {
  gap: 0.4rem !important;
}

#shopify-pc__banner__btn-accept,
#shopify-pc__banner__btn-decline,
#shopify-pc__banner__btn-manage-prefs {
  min-height: 2rem !important;
  padding: 0.3rem 0.7rem !important;
  font-family: 'Barlow Condensed', sans-serif !important;
  font-size: var(--text-2xs) !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
}

@media (max-width: 719px) { /* store sm */
  #shopify-pc__banner {
    inset: auto 0.5rem 0.5rem 0.5rem !important;
    max-width: none !important;
  }
}

/* ── EVENTS CALENDAR ──
   Replaces the old floating event cards. One month is visible at a time and
   the prev/next buttons page through the months that actually have events;
   the feed jumps Dec 2026 → Nov 2027, so empty months are never emitted. A
   table (not a grid of divs) because a calendar is tabular data — weekday
   headers are real <th scope="col"> and the month name is the <caption>,
   visually hidden because the nav bar shows it. */
.event-cal {
  /* Wide and open: the calendar is the page's primary content on
     /pages/events, not a sidebar widget. */
  width: 100%;
  max-width: 64rem;
  margin-top: 1.6rem;
}

/* The header stays put while the tables swap underneath, so the calendar
   never jumps around as the visitor pages through the season. */
.event-cal__nav {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0.6rem;
  background: color-mix(in srgb, var(--blue) 14%, transparent);
  border: 1px solid var(--line);
  border-bottom: 0;
}

.event-cal__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  background: none;
  border: 1px solid var(--line);
  color: var(--white);
  cursor: pointer;
  font-size: var(--text-xs);
  transition: color 0.18s, border-color 0.18s, opacity 0.18s;
}

.event-cal__step:hover:not(:disabled),
.event-cal__step:focus-visible:not(:disabled) {
  color: var(--accent-text);
  border-color: var(--line-y);
}

.event-cal__step:disabled {
  opacity: 0.32;
  cursor: default;
}

.event-cal__title {
  flex: 1 1 auto;
  margin: 0;
  color: var(--white);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
}

.event-cal__pos {
  color: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: var(--text-2xs);
  font-variant-numeric: tabular-nums;
}

/* Reserve the tallest month (6 rows) so paging never reflows the page. */
.event-cal__viewport {
  position: relative;
  min-height: 21rem;
}

/* TKD badge watermarked behind the grid. Very low opacity so day numbers and
   series tags stay legible; pointer-events off so it never eats a click, and
   aria-hidden via CSS content (it is a background, not an <img>), so screen
   readers and the table semantics are untouched. */
.event-cal__viewport::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: var(--event-cal-watermark);
  background-position: center;
  background-repeat: no-repeat;
  background-size: min(58%, 22rem) auto;
  opacity: 0.07;
  pointer-events: none;
}

[data-theme='light'] .event-cal__viewport::before {
  opacity: 0.1;
}

/* Cells sit above the watermark; the table itself must not paint over it. */
.event-cal__month {
  position: relative;
  z-index: 1;
  background: transparent;
}

.event-cal__day,
.event-cal__pad {
  background-color: transparent;
}

.event-cal__pad {
  background-color: color-mix(in srgb, var(--navy) 22%, transparent);
}

.event-cal__month {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  border: 1px solid var(--line);
}

.event-cal__month caption {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.event-cal__month th {
  padding: 0.5rem 0.2rem;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.event-cal__month th abbr {
  text-decoration: none;
  border: 0;
}

.event-cal__day,
.event-cal__pad {
  width: 14.28%;
  height: 4.2rem;
  padding: 0;
  border: 1px solid var(--line);
  vertical-align: top;
}

.event-cal__pad {
  background: color-mix(in srgb, var(--navy) 40%, transparent);
  border-color: transparent;
}

.event-cal__num {
  display: block;
  padding: 0.28rem 0.36rem;
  color: var(--muted);
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-2xs);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.event-cal__day.is-event {
  background: color-mix(in srgb, var(--yellow) 13%, transparent);
  border-color: var(--line-y);
}

.event-cal__day.is-event a {
  display: block;
  height: 100%;
  text-decoration: none;
}

.event-cal__day.is-event .event-cal__num {
  color: var(--accent-text);
  font-weight: var(--weight-bold);
}

.event-cal__tag {
  display: block;
  padding: 0 0.36rem 0.3rem;
  overflow: hidden;
  color: var(--ink);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  line-height: 1.1;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.event-cal__more {
  display: inline-block;
  margin-left: 0.36rem;
  color: var(--accent-text);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: var(--text-2xs);
}

.event-cal__day.is-event a:hover,
.event-cal__day.is-event a:focus-visible {
  background: color-mix(in srgb, var(--yellow) 26%, transparent);
}

.event-cal__foot {
  margin-top: 1.4rem;
}

@media (max-width: 719px) { /* store sm */
  .event-cal {
    max-width: none;
  }

  .event-cal__viewport::before {
    background-size: min(70%, 14rem) auto;
  }

  .event-cal__day,
  .event-cal__pad {
    height: 3rem;
  }

  .event-cal__tag {
    display: none;
  }
}

/* The Kart Depot's own social row — sits above the footer meta line. The AP
   GitHub mark in .footer-social is separate (attribution, footer-standard §2). */
.footer-brand-social {
  display: flex;
  gap: 0.9rem;
  margin: 0 0 1.1rem;
  padding: 0;
  list-style: none;
}

.footer-brand-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  border: 1px solid var(--line);
  color: var(--ink);
  transition: color 0.18s, border-color 0.18s;
}

.footer-brand-social a:hover,
.footer-brand-social a:focus-visible {
  color: var(--accent-text);
  border-color: var(--line-y);
}

/* Touch targets — WCAG 2.2 AA (2.5.8) wants at least 24x24 CSS px for pointer
   inputs. These link families were rendering ~23px tall on their line-height
   alone; the padding is vertical only so nothing reflows horizontally. */
nav[aria-label='Primary'] a,
nav[aria-label='Mobile'] a,
.footer-col a,
.footer-meta a,
.ap-credit a,
.event-cal__day.is-event a {
  padding-block: 0.35rem;
}

.footer-col li,
.footer-meta {
  line-height: 1.6;
}

/* Last two sub-24px targets: the announcement-bar link sat at 20px on its
   line-height, and the AP GitHub mark was a 16px-wide svg with no box.

   Values scaled x1.6 on 2026-09-06. These were written as measured fixes
   against a 16px root -- 0.3rem meaning 4.8px, 1.5rem meaning 24px -- but the
   storefront root is 10px, so they had been rendering 3px and 15px and never
   actually fixed anything. See "Two roots" in docs/BRAND.md. Unlike the
   spacing elsewhere in this file, which was tuned by eye against the live 10px
   rendering and is therefore already correct, these two came from a
   measurement and had to move. */
.notice a {
  display: inline-block;
  padding-block: 0.48rem;
}

.social-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.4rem;
  min-height: 2.4rem;
}

/* Cross-property navigation aid in the notice bar. Sits beside the rotating
   slides rather than joining them: the carousel advances every 5s, and a
   navigation aid visible a third of the time is not a navigation aid. */
.notice {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
}

.notice-slides {
  flex: 1 1 auto;
}

.notice-crosslink {
  flex: 0 0 auto;
  padding-block: 0.3rem;
  text-decoration: underline;
  white-space: nowrap;
}

@media (max-width: 719px) { /* store sm */
  .notice {
    flex-direction: column;
    gap: 0.15rem;
  }

  .notice-crosslink {
    white-space: normal;
  }
}

/* ── PARTNER PROMO ──
   A sister brand's advertisement sitting inside a TKD page. It must read as
   somebody else's unit, not as house content — hence the inset frame, the
   yellow rule, and the panel surface rather than the page ground. Palette is
   still Trackside Navy: brand-tokens.md is explicit that the two businesses
   share ONE palette and differ by logo, so a bespoke ad colour would break
   the brand standard, not reinforce the distinction. */
.partner-promo-shell {
  padding: 1.6rem 2rem 2.4rem;
}

.partner-promo {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 1.6rem;
  padding: 1.5rem 1.7rem;
  background: var(--navy-2);
  border: 1px solid var(--line-y);
  border-left: 3px solid var(--yellow);
}

/* Required attribution — the advertiser is named, never implied. */
.partner-promo__label {
  position: absolute;
  top: -0.62rem;
  left: 1.4rem;
  padding: 0 0.5rem;
  background: var(--navy);
  color: var(--accent-text);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Evolution mark, partner-promo band.
  The file is the client's master as supplied, 298x286, unmodified (Luiz,
  2026-09-08: use it as is, no crop). The wordmark plate sits in the middle
  third of that canvas and the speed streaks fill the rest, so the image box
  is ~2.9x taller than the plate. Height is chosen for the plate, and the
  negative block margin folds the streak halo back over the surrounding
  space so the row keeps its rhythm. Do not re-crop the file. */
.partner-promo__mark img {
  display: block;
  width: auto;
  height: 120px;
  margin-block: -38px;
}

.partner-promo__heading {
  margin: 0 0 0.35rem;
  color: var(--white);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  line-height: 1.1;
  text-transform: none;
}

.partner-promo__body {
  margin: 0;
  max-width: 68ch;
  color: var(--ink);
  font-size: var(--text-2xs);
  line-height: 1.45;
}

.partner-promo__cta {
  flex: 0 0 auto;
  white-space: nowrap;
}

@media (max-width: 860px) { /* component exception: the promo's copy + CTA columns' natural wrap */
  .partner-promo {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    text-align: left;
  }

  .partner-promo__cta {
    justify-self: start;
    white-space: normal;
  }

  /* One column: the mark's folded halo (margin-block: -38px above) now lands
     on the label above it and the heading below it — the same §1.14 bug the
     footer logo had (responsive-standard §8 row 3). Keep the 120px box, drop
     the fold; the row rhythm it protected only exists in the 3-column layout. */
  .partner-promo__mark img {
    margin-block: 0;
  }
}

/* ------------------------------------------------------------------
   Square corners on stock Dawn components — Luiz, 2026-09-06

   Dawn's own CSS is deliberately left unedited (it is upstream code and
   the repo keeps it that way), and almost all of it already resolves to
   0 through --inputs-radius / --media-radius / --buttons-radius /
   --badge-corner-radius, which layout/theme.liquid now clamps. These are
   the few places Dawn hardcodes a radius instead, so they are overridden
   here in the custom layer rather than upstream.

   Two hardcoded circles are INTENTIONALLY left alone: `.media--circle`,
   an explicitly opt-in circular media variant, and the loading spinner at
   `border-radius: 100%` — a spinner is a rotating disc, and squaring it
   would read as a rendering bug rather than a design choice.
   ------------------------------------------------------------------ */
/* `body` prefix is load-order insurance, not decoration. These selectors match
   Dawn's own at equal specificity (0,1,0), and section-main-product.css loads
   AFTER theme-custom.css, so the unprefixed version lost and the icons stayed
   round on staging. Verified by measuring computed style, not by reading the
   cascade. */
body .product__media-icon,
body .thumbnail__badge,
body .product-media-modal__toggle,
body .product-popup-modal__toggle,
body span.active-facets__button-inner {
  border-radius: var(--radius-sm);
}

/* ------------------------------------------------------------------
   Footer logo pair — TKD + Evolution (Luiz, 2026-09-07)

   Matched on HEIGHT, not width. The two marks have different aspect
   ratios (TKD 2.97:1, Evolution 4.54:1), so equal widths would render
   Evolution's wordmark visibly shorter and the pair would read as a
   mistake. Equal height is what makes a logo row read as a set — the
   Evolution badge is simply the wider of the two.

   Wraps on narrow screens rather than shrinking, so neither mark drops
   below a legible size on a phone.
   ------------------------------------------------------------------ */
.footer-logos {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.6rem 2.4rem;
  margin-bottom: 0.9rem;
}

/* The pair owns the spacing now; the single-logo margin would double it. */
.footer-brand .footer-logos .footer-logo {
  margin-bottom: 0;
}

.footer-logo-link {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

/* Evolution mark, footer pair.
  The file is the client's master as supplied, 298x286, unmodified (Luiz,
  2026-09-08: use it as is, no crop). The wordmark plate sits in the middle
  third of that canvas and the speed streaks fill the rest, so the image box
  is ~2.9x taller than the plate. Height is chosen for the plate, and the
  negative block margin folds the streak halo back over the surrounding
  space so the row keeps its rhythm. Do not re-crop the file.
  Selector is deliberately more specific than the pair's own
  `margin-bottom: 0` reset above, which otherwise wins and cancels the
  bottom half of the negative margin (measured 2026-09-08: the box came out
  92px tall instead of 52px and the plate sat 20px above the TKD badge). */
.footer-brand .footer-logos .footer-logo--evolution {
  height: 132px;
  width: auto;
  margin-block: -40px;
}

/* Below the desktop footer the streak canvas has no room to hang over its
   neighbours: the negative margins put the streaks through the description
   paragraph below, the back-to-top bar above, and at 320px through the TKD
   mark beside it (measured 2026-09-09). Let the box reserve its own height
   instead. The master file is still shown whole -- nothing is cropped. */
@media (max-width: 1059px) {
  .footer-brand .footer-logos .footer-logo--evolution {
    height: 120px;
    margin-block: 0;
  }
}

.footer-logo-link:hover .footer-logo--evolution,
.footer-logo-link:focus-visible .footer-logo--evolution {
  opacity: 0.85;
}

/* ══════════════════════════════════════════════════════════════════════
   PDP THREE-COLUMN FRAME — TKD-STORE-UX-SPEC §6
   sections/main-product.liquid, snippets/main-product-block.liquid,
   snippets/pdp-*.liquid, sections/pdp-*.liquid, assets/tkd-pdp.js.

   Every selector below that has to beat a Dawn rule from
   assets/section-main-product.css uses two classes (`.product.pdp-frame`,
   `.pdp-frame .product__info-wrapper`, …) so it wins on specificity — that
   Dawn stylesheet is included from inside the section itself and so loads
   AFTER this file in the document; without the extra specificity, "last in
   the cascade" would let a same-specificity Dawn rule win instead.
   ══════════════════════════════════════════════════════════════════════ */

/* §6.1 frame: gallery ~40% / details ~35% / buy box ~25% at >=1024px. Below
   that, §10's table says gallery+details stack and the buy box drops below
   — which is exactly what happens here for free, because `.pdp-frame` only
   applies grid-template-columns inside this media query and Dawn's own
   `grid--1-col` (single column) rule already governs everything under it. */
@media screen and (min-width: 1024px) { /* Dawn breakpoint — matches the vendor grid the PDP frame overrides */
  .product.pdp-frame {
    grid-template-columns: minmax(0, 40fr) minmax(0, 35fr) minmax(0, 25fr);
    column-gap: 4rem;
    row-gap: 0;
    align-items: start;
  }

  /* media_size keeps meaning something: it narrows the gallery column and
     grows the details column, same relative direction as Dawn's own
     small/medium/large semantics for this setting. */
  .product.pdp-frame.product--medium {
    grid-template-columns: minmax(0, 35fr) minmax(0, 38fr) minmax(0, 27fr);
  }

  .product.pdp-frame.product--small {
    grid-template-columns: minmax(0, 30fr) minmax(0, 42fr) minmax(0, 28fr);
  }

  /* media_position=right still flips gallery vs. details, but the buy box
     is pinned rightmost regardless — Amazon's/the spec's own convention
     (§6.1), and a deliberate deviation from this setting's original
     either-side-of-everything meaning. Noted in the PR. */
  .product.pdp-frame.product--right .pdp-frame__media {
    order: 2;
  }

  .product.pdp-frame.product--right .pdp-frame__details {
    order: 1;
  }

  .product.pdp-frame .pdp-frame__buybox {
    order: 3;
  }

  .pdp-frame .product__info-wrapper.pdp-frame__details {
    padding: 0 4rem 0 0;
  }

  .product.pdp-frame.product--right .product__info-wrapper.pdp-frame__details {
    padding: 0 0 0 4rem;
  }
}

@media screen and (max-width: 1023.98px) { /* Dawn breakpoint */
  .pdp-frame__buybox {
    margin-top: 3.2rem;
  }
}

.pdp-frame__buybox {
  min-width: 0;
}

/* §6.4: navy-3 panel, 1px border, 20px padding, sticky at the same 108px
   offset the PLP filter rail uses (this file, ~line 2286) — both sit below
   the same 103px sticky header. */
.pdp-buybox {
  background: var(--navy-3);
  border: 1px solid var(--line);
  padding: 2rem;
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
}

@media screen and (min-width: 1024px) { /* Dawn breakpoint */
  .pdp-buybox {
    position: sticky;
    top: 108px;
  }

  /* §6.4: "the sticky panel must never overlap the footer." Belt-and-braces
     on top of the natural stop at the bottom of the grid row — see
     assets/tkd-pdp.js's footer IntersectionObserver. */
  .pdp-frame__buybox--unstuck .pdp-buybox {
    position: static;
  }
}

.pdp-buybox .price {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--white);
}

.pdp-buybox .product__inventory {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}

/* §6.4 item 4: "44px tall, 0 radius." */
.pdp-buybox quantity-input {
  height: 44px;
  border-radius: 0;
}

.pdp-buybox .product-form__submit {
  height: 48px;
}

/* §6.4 item 5: Add to Cart is "the single highest-priority yellow on the
   page." Fixed 2026-09-09, caught in staging QA before this went live:
   `snippets/buy-buttons.liquid` puts `button--secondary` on the ADD TO CART
   button itself whenever `show_dynamic_checkout` is on (line ~92) — it is
   Dawn's own submit button that gets demoted, not the payment widget. The
   rule below had that backwards: it ghosted Add to Cart and left the actual
   dynamic-checkout button (Shop Pay etc., rendered by `{{ form |
   payment_button }}`, a Shopify-hosted widget CSS cannot restyle — its
   brand color is enforced by Shopify, not a theme choice) untouched. Net
   effect on staging: Add to Cart rendered as a yellow outline and Shop Pay's
   own purple pill became the visually dominant button — the opposite of
   §6.4's intent.
   Fix: force the submit button back to the primary (filled) palette
   regardless of which class Dawn assigned, by resetting the two custom
   properties `.button--secondary` overrides (base.css:1192-1195) rather
   than fighting it with `!important` background/border rules. Scoped to
   the buy box's submit button only — `.button--secondary` keeps its normal
   meaning everywhere else in the theme. */
.pdp-buybox .product-form__submit {
  /* Same literal RGB triplets layout/theme.liquid sets at :root for
     --color-button/--color-button-text (--yellow / --navy) — matching the
     root's own hardcoded-not-picker-driven pattern, not inventing a new one. */
  --color-button: 254, 191, 0;
  --color-button-text: 0, 26, 82;
}

.pdp-buybox__trust {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  font-size: var(--text-2xs);
  color: var(--ink);
}

.pdp-buybox__trust a {
  color: var(--yellow);
}

.pdp-buybox__garage {
  background: none;
  border: none;
  padding: 0;
  color: var(--yellow);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
  text-align: left;
}

.pdp-buybox__garage--saved {
  color: var(--ok);
}

.pdp-buybox__divider {
  border: none;
  border-top: 1px solid var(--line);
  margin: 0;
}

.pdp-buybox__whatsapp {
  color: var(--yellow);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
}

.pdp-buybox__whatsapp:hover {
  text-decoration: underline;
}

/* ---------- Details column (§6.3) ---------- */

.pdp-details__brand a,
.pdp-details__brand--unlinked {
  color: var(--yellow);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: var(--weight-bold);
}

.pdp-details__brand {
  margin-bottom: 0.8rem;
}

/* §6.3 item 2: "normal weight; bold titles at this size read as shouting."
   The visible title element in this markup is the bare <h1> — Dawn hides
   the <a><h2> alternate (assets/section-main-product.css's
   `.product__title > a { display: none }`) except inside a quick-add
   modal, so overriding the h2 here would do nothing on the PDP itself. */
.pdp-frame__details .product__title h1 {
  font-size: var(--text-lg);
  font-weight: var(--weight-regular);
  color: var(--white);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pdp-details__reviews-anchor {
  margin-top: 0.6rem;
}

.pdp-details__reviews-anchor a {
  color: var(--yellow);
  font-size: var(--text-2xs);
}

.pdp-details__divider {
  border: none;
  border-top: 1px solid var(--line);
  margin: 1.6rem 0;
}

.pdp-sku-copy {
  background: none;
  border: 1px solid var(--line);
  color: var(--ink);
  font-size: var(--text-2xs);
  padding: 0.3rem 0.8rem;
  margin-left: 0.8rem;
  cursor: pointer;
}

.pdp-sku-copy:hover {
  border-color: var(--yellow);
  color: var(--yellow);
}

.pdp-sku-copy--done {
  border-color: var(--ok);
  color: var(--ok);
}

/* ---------- Specs table (§6.6) ---------- */

.pdp-specs {
  margin-top: 3.2rem;
}

.pdp-specs__heading {
  font-size: var(--text-sm);
  color: var(--white);
  margin-bottom: 1.2rem;
}

.pdp-specs__scroll {
  overflow-x: auto;
}

.pdp-specs__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-2xs);
}

.pdp-specs__table thead tr {
  background: var(--navy-3);
}

.pdp-specs__table th,
.pdp-specs__table td {
  text-align: left;
  padding: 1rem 1.4rem;
  border-bottom: 1px solid var(--line);
}

.pdp-specs__table tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--navy-3) 45%, transparent);
}

.pdp-specs__table th[scope='row'] {
  color: var(--ink);
  font-weight: var(--weight-bold);
  width: 40%;
}

.pdp-specs__table td {
  color: var(--white);
}

/* ---------- Cross-sell carousels (§6.7 items 1-2) ---------- */

.pdp-cross-sell,
.pdp-compare,
.pdp-fbt {
  margin-top: 3.2rem;
}

.pdp-cross-sell__heading,
.pdp-compare__heading,
.pdp-fbt__heading {
  font-size: var(--text-sm);
  color: var(--white);
  margin-bottom: 1.6rem;
}

.pdp-carousel {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.8rem;
}

.pdp-carousel__track {
  display: flex;
  gap: 1.6rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  list-style: none;
  margin: 0;
  padding: 0.4rem 0;
  scrollbar-width: none;
}

.pdp-carousel__track::-webkit-scrollbar {
  display: none;
}

.pdp-carousel__item {
  flex: 0 0 auto;
  width: 200px;
  scroll-snap-align: start;
}

.pdp-carousel__nav {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  background: var(--navy-3);
  border: 1px solid var(--line);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.pdp-carousel__nav:hover {
  border-color: var(--yellow);
}

.pdp-carousel__nav svg {
  width: 14px;
  height: 14px;
}

.pdp-carousel__nav--prev svg {
  transform: rotate(90deg);
}

.pdp-carousel__nav--next svg {
  transform: rotate(-90deg);
}

/* ---------- Compare table (§6.7 item 3) ---------- */

.pdp-compare__scroll {
  overflow-x: auto;
}

.pdp-compare__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-2xs);
}

.pdp-compare__table th,
.pdp-compare__table td {
  padding: 1.2rem;
  border-bottom: 1px solid var(--line);
  text-align: center;
  vertical-align: top;
}

.pdp-compare__table th[scope='row'] {
  text-align: left;
  color: var(--ink);
  font-weight: var(--weight-bold);
}

.pdp-compare__this-item {
  border-top: 2px solid var(--yellow);
}

.pdp-compare__badge {
  display: block;
  color: var(--yellow);
  font-size: var(--text-2xs);
  text-transform: uppercase;
  font-weight: var(--weight-bold);
  margin-bottom: 0.6rem;
}

.pdp-compare__table img {
  margin: 0 auto 0.8rem;
}

/* ---------- Frequently bought together (§6.7 item 3) ---------- */

.pdp-fbt__row {
  display: flex;
  align-items: center;
  gap: 1.6rem;
  flex-wrap: wrap;
}

.pdp-fbt__item {
  text-align: center;
  font-size: var(--text-2xs);
  color: var(--ink);
  max-width: 140px;
}

.pdp-fbt__item img {
  margin: 0 auto 0.8rem;
}

.pdp-fbt__item-price {
  color: var(--white);
  font-weight: var(--weight-bold);
}

.pdp-fbt__plus {
  font-size: var(--text-lg);
  color: var(--muted);
}

.pdp-fbt__footer {
  display: flex;
  align-items: center;
  gap: 2rem;
  margin-top: 2rem;
  flex-wrap: wrap;
}

.pdp-fbt__total {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--white);
}

/* ---------- Reviews & Q&A empty states (§6.8) ---------- */

.pdp-reviews-qna {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.4rem;
  margin-top: 3.2rem;
  border-top: 1px solid var(--line);
  padding-top: 3.2rem;
}

@media screen and (min-width: 750px) { /* Dawn breakpoint */
  .pdp-reviews-qna {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

.pdp-reviews-qna__heading {
  font-size: var(--text-sm);
  color: var(--white);
  margin-bottom: 0.8rem;
}

.pdp-reviews-qna__empty {
  color: var(--ink);
  font-size: var(--text-sm);
}

.pdp-reviews-qna__empty a {
  color: var(--yellow);
}

/* ---------- Mobile sticky add-to-cart bar (§6.1, §10) ---------- */

.pdp-sticky-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 90;
  background: var(--navy-2);
  border-top: 1px solid var(--line);
  padding: 1rem 1.6rem;
  display: flex;
  align-items: center;
  gap: 1.2rem;
}

.pdp-sticky-bar[hidden] {
  display: none;
}

.pdp-sticky-bar__image {
  width: 44px;
  height: 44px;
  object-fit: cover;
  flex: 0 0 auto;
}

.pdp-sticky-bar__price {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--white);
}

.pdp-sticky-bar__price .price {
  font-size: inherit;
}

.pdp-sticky-bar__cta {
  flex: 0 0 auto;
  height: 44px;
  padding: 0 1.6rem;
}

@media screen and (min-width: 1024px) { /* Dawn breakpoint */
  .pdp-sticky-bar {
    display: none !important;
  }
}

/* ---------- Gallery: vertical thumbnail strip (§6.2) ---------- */

/* Dawn's `gallery_layout: thumbnail` (templates/product.json) renders the
   thumbnails as a wrapping grid alongside/under the main image, not a fixed
   left-hand column — this arranges the same two <slider-component>s
   (GalleryViewer, GalleryThumbnails) side by side with the thumbnails
   first, without touching media-gallery.js's DOM lookups (both elements
   keep their ids; only their visual order/layout changes). */
@media screen and (min-width: 750px) { /* Dawn breakpoint — thumbnails beside the gallery, media-gallery.js markup */
  .pdp-frame__media media-gallery {
    display: flex;
    align-items: flex-start;
    gap: 1.2rem;
  }

  .pdp-frame__media media-gallery > [id^='GalleryViewer'] {
    order: 2;
    flex: 1 1 auto;
    min-width: 0;
  }

  .pdp-frame__media media-gallery > [id^='GalleryThumbnails'] {
    order: 1;
    flex: 0 0 72px;
  }

  .pdp-frame__media .thumbnail-list {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: 8px;
    max-height: 64rem;
    overflow-y: auto;
    padding-right: 0;
  }

  .pdp-frame__media .thumbnail-list__item {
    aspect-ratio: 1 / 1;
    flex: 0 0 auto;
  }

  /* Dawn's prev/next chevrons on the thumbnail strip assume a horizontal
     slider; the vertical strip scrolls natively with the mouse wheel /
     touch instead. */
  .pdp-frame__media .thumbnail-slider .slider-button {
    display: none;
  }
}

/* §6.2: "Active thumbnail: 2px solid var(--yellow). Inactive: 1px solid
   var(--line)." Overrides Dawn's box-shadow-based active state
   (assets/section-main-product.css's `.thumbnail[aria-current]`), which
   used `--color-foreground` instead of the yellow accent this spec reserves
   for exactly this kind of selected-state signal. */
.pdp-frame__media .thumbnail {
  border: 1px solid var(--line);
  box-shadow: none;
}

.pdp-frame__media .thumbnail[aria-current] {
  border: 2px solid var(--yellow);
  box-shadow: none;
}
/* ------------------------------------------------------------------
   Promotional slots — TKD-STORE-UX-SPEC §9

   Six reserved merchandising slots: promo-hero, promo-inline-plp,
   promo-pdp-brand, promo-search-top, promo-footer-strip (sections) and
   promo-cart-upsell (a reference-implementation snippet, not yet wired in).
   All six render nothing when their settings are empty — see each file's own
   comment header — so none of this CSS ever paints an empty box.

   `.promo-unit` is the shared "this is an ad-like unit" surface for the
   three explicitly brand-partner fills (inline-plp, pdp-brand, search-top):
   --navy-2 background, accent hairline border, 3px yellow left rule — the
   same treatment sections/partner-promo.liquid already uses for the same
   purpose. promo-hero and promo-footer-strip are in-house merchandising and
   use plain --navy-3 card / --navy-3 strip surfaces instead, matching the
   rest of the site rather than the ad-like treatment.
   ------------------------------------------------------------------ */
.promo-unit {
  position: relative;
  background: var(--navy-2);
  border: 1px solid var(--line-y);
  border-left: 3px solid var(--yellow);
}

/* Required attribution — reuses .partner-promo__label's cut-tab technique
   (absolutely positioned, background matching the page so it reads as cut
   into the unit's top border) at the colour and size §9 mandates for a
   generic "Sponsored" attribution: --muted, --text-2xs, uppercase,
   letterspaced. partner-promo's own label uses --accent-text because it
   names a specific advertiser's brand, not a generic disclosure; §9's
   "Sponsored" is generic, so it takes the spec's literal call-out instead.
   The label's own background is --navy (the page ground), never --navy-3,
   so --muted stays on the one surface where §2.2 allows it. */
.promo-sponsored-label {
  position: absolute;
  top: -0.62rem;
  left: 1.4rem;
  padding: 0 0.5rem;
  background: var(--navy);
  color: var(--muted);
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  z-index: 1;
}

/* ── promo-hero — homepage 4-up, in-house campaigns ── */
.promo-hero-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.25rem;
}

.promo-hero-card {
  display: flex;
  flex-direction: column;
  background: var(--navy-3);
  border: 1px solid var(--line);
  overflow: hidden;
  text-decoration: none;
  transition: border-color 0.15s;
}

.promo-hero-card:hover {
  border-color: var(--yellow);
}

.promo-hero-card__image-wrap {
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--navy-2);
}

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

.promo-hero-card__body {
  display: block;
  padding: 1rem 1.1rem 1.2rem;
}

.promo-hero-card__heading {
  display: block;
  margin-bottom: 0.5rem;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--white);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.15;
}

.promo-hero-card__cta {
  display: block;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--yellow);
}

.promo-hero-card:hover .promo-hero-card__cta {
  color: var(--yellow-hi);
  text-decoration: underline;
}

@media (max-width: 860px) { /* component exception: three promo cards → two at the row's natural wrap */
  .promo-hero-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 719px) { /* store sm */
  .promo-hero-row {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ── promo-inline-plp — PLP full-row banner, brand-partner ── */
.promo-inline-plp {
  display: block;
  margin: 0;
  overflow: hidden;
  text-decoration: none;
}

.promo-inline-plp__media {
  display: block;
  aspect-ratio: 3 / 1;
}

.promo-inline-plp__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.promo-inline-plp__caption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 1rem 1.4rem;
}

.promo-inline-plp__heading {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--white);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.promo-inline-plp__cta {
  flex: 0 0 auto;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--yellow);
  white-space: nowrap;
}

.promo-inline-plp:hover .promo-inline-plp__cta {
  color: var(--yellow-hi);
  text-decoration: underline;
}

/* ── promo-pdp-brand — PDP rail, brand-partner ── */
.promo-pdp-brand {
  max-width: 300px;
  padding: 1.6rem 1.1rem 1.1rem;
}

.promo-pdp-brand__heading {
  margin: 0 0 0.9rem;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
}

.promo-pdp-brand__products {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

/* ── promo-search-top — search results, brand-partner ── */
.promo-search-top {
  display: block;
  padding: 1.6rem 1.4rem 1.4rem;
}

.promo-search-top__grid {
  margin-top: 0;
}

/* ── promo-footer-strip — above the footer, in-house ── */
.promo-footer-strip-section {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.promo-footer-strip {
  display: block;
  background: var(--navy-3);
  text-decoration: none;
}

.promo-footer-strip__media {
  display: block;
  aspect-ratio: 6 / 1;
  min-height: 90px;
}

.promo-footer-strip__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.promo-footer-strip__caption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 1rem 2rem;
}

.promo-footer-strip__heading {
  font-family: 'Barlow Condensed', sans-serif;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--white);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.promo-footer-strip__cta {
  flex: 0 0 auto;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--yellow);
  white-space: nowrap;
}

.promo-footer-strip:hover .promo-footer-strip__cta {
  color: var(--yellow-hi);
  text-decoration: underline;
}

/* ── promo-cart-upsell — reference implementation, not yet wired in ──
   See snippets/promo-cart-upsell.liquid. In-house, no Sponsored label. */
.promo-cart-upsell {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}

.promo-cart-upsell__heading {
  margin: 0 0 0.8rem;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
}

.promo-cart-upsell__row {
  display: flex;
  gap: 0.9rem;
  overflow-x: auto;
  padding-bottom: 0.4rem;
  scroll-snap-type: x mandatory;
}

.promo-cart-upsell__row .product-card {
  flex: 0 0 160px;
  scroll-snap-align: start;
}

/* ------------------------------------------------------------------
   Cart drawer cross-sell carousel — TKD-STORE-UX-SPEC §8.1
   "You might also need". Lives inside #CartDrawer-CartItems, which is the
   flex-scrolling region (component-cart-drawer.css: `cart-drawer-items {
   overflow: auto; flex: 1 }`); .drawer__footer with the checkout button is a
   separate, non-scrolling sibling below it, so this content only makes the
   scroll area taller — it never pushes checkout off screen. Checked at a
   700px-tall viewport (above the 650px breakpoint where the drawer switches
   to scrolling as one block).

   Reuses the theme's stock <slider-component> (assets/global.js) and the
   `.slider` / `.slider__slide` / `slider-buttons` contract from
   component-slider.css — same component featured-collection.liquid uses —
   so it is user-driven only (buttons + swipe/scroll, no autoplay) and
   already respects prefers-reduced-motion via that file's
   `.slider { scroll-behavior: auto }` rule. No new JS.

   The free-shipping progress bar named in spec §8.1 is deliberately absent
   — see CHANGELOG.md [Unreleased] and GitHub issue #46: this store's only
   delivery profile has flat paid rates with no free-shipping tier at any
   threshold, so the copy would be fabricated.
   ------------------------------------------------------------------ */
.cart-drawer__cross-sell {
  border-top: 1px solid var(--line);
  margin-top: 2rem;
  padding-top: 1.6rem;
}

.cart-drawer__cross-sell-heading {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink);
  margin: 0 0 1.2rem;
}

.cart-drawer__cross-sell-list {
  display: flex;
  gap: 1rem;
  padding: 0;
  margin: 0;
  list-style: none;
}

.cart-drawer__cross-sell-item {
  width: 148px;
}

/* Compact tile for a 400px-wide drawer — same .product-card component the
   PLP and homepage grids use (snippets/tkd-product-card.liquid), scoped
   down rather than forked, so a catalog-wide card change still reaches
   this carousel. */
.cart-drawer__cross-sell-item .product-img {
  height: 110px;
}

.cart-drawer__cross-sell-item .product-info {
  padding: 0.9rem;
}

.cart-drawer__cross-sell-item .product-name {
  font-size: var(--text-2xs);
  margin-bottom: 0.6rem;
}

.cart-drawer__cross-sell-item .product-price {
  font-size: var(--text-sm);
}

.cart-drawer__cross-sell-item .product-footer {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
}

.cart-drawer__cross-sell-item .product-card__cta {
  width: 100%;
  text-align: center;
}

.cart-drawer__cross-sell-buttons {
  margin-top: 0.8rem;
}

/* ------------------------------------------------------------------
   Cart page two columns — TKD-STORE-UX-SPEC §8.2. main-cart-items and
   main-cart-footer are two independent Shopify sections in this theme
   (Dawn's stock cart template keeps them in one file; this fork's split
   left the old `.cart__items` / `.cart__footer` grid-column rules in
   component-cart.css dead — those selectors need literal DOM adjacency
   that two separate `.shopify-section` wrappers can never have). This
   targets the sections' auto-generated `.shopify-section-<id>` wrappers
   directly instead.

   `main.template-cart` is set in layout/theme.liquid only for the cart
   template, and `.template-cart--empty` when the cart has no items, so the
   empty-cart state (a single centered message, per component-cart.css)
   keeps its current single-column layout untouched.
   ------------------------------------------------------------------ */
@media screen and (min-width: 1024px) { /* Dawn breakpoint — cart page grid over component-cart.css */
  main.template-cart:not(.template-cart--empty) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 38rem;
    gap: 0 4rem;
    align-items: start;
  }

  main.template-cart:not(.template-cart--empty) .shopify-section-cart-footer {
    position: sticky;
    top: 108px;
  }

  /* component-cart.css puts the footer's "subtotal" and "buttons" blocks
     side by side at 35rem each once the viewport clears 750px — correct
     when the footer spans the full page width, but this column is only
     38rem wide, so left unchanged the two blocks would overflow it.
     Higher specificity than that rule (2 classes vs. 1) wins regardless
     of the two stylesheets' load order. */
  main.template-cart:not(.template-cart--empty) .shopify-section-cart-footer .cart__footer {
    display: block;
  }

  main.template-cart:not(.template-cart--empty) .shopify-section-cart-footer .cart__footer > * {
    width: 100%;
  }

  main.template-cart:not(.template-cart--empty) .shopify-section-cart-footer .cart__footer > * + * {
    margin-left: 0;
    margin-top: 2rem;
  }
}

.cart-summary {
  background: var(--navy-3);
  border: 1px solid var(--line);
  padding: 2rem;
}

.cart-summary__row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: var(--text-xs);
  color: var(--ink);
  padding: 0.6rem 0;
}

.cart-summary__row + .cart-summary__row {
  border-top: 1px solid var(--line);
}

.cart-summary__row--total {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--white);
  border-top: 1px solid var(--line-y);
  margin-top: 0.4rem;
  padding-top: 1.2rem;
}

/* This row also carries Dawn's stock `.totals` class (component-totals.css),
   whose own `display: flex; justify-content: flex-end` has equal (single
   class) specificity and loads later in the document, so it would otherwise
   win over .cart-summary__row's `space-between` and bunch the label and
   value together at the right edge. The two-class selector here outranks
   both single-class rules regardless of load order. */
.cart-summary__row.cart-summary__row--total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

/* Same reasoning one level down: component-totals.css sets a raw font-size
   directly on .totals__total (the h2) and .totals__total-value (the p),
   which — being element-specific rules of the same specificity — would
   otherwise win over inheriting the row's --text-lg. Spec §8.2 wants this
   row at --text-lg 700. */
.cart-summary__row--total .totals__total,
.cart-summary__row--total .totals__total-value {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--white);
  margin: 0;
}

.cart-summary__payment-icons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  margin-top: 1.6rem;
  justify-content: center;
}

.cart-summary__payment-icons .icon {
  height: 2.4rem;
  width: auto;
}

/* ------------------------------------------------------------------
   Save for later — TKD-STORE-UX-SPEC §8.2. Client-side v1: no app or
   backend, same honest scope as the Garage feature's "even a localStorage
   v1 is worth shipping" (§6.4). Removal from the real cart still goes
   through the theme's existing AJAX cart-change endpoint (see
   assets/tkd-cart-save-for-later.js); only the "remember it" half is
   localStorage.
   ------------------------------------------------------------------ */
.cart-item__save-for-later {
  color: var(--muted);
  font-size: var(--text-2xs);
  text-decoration: underline;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

.cart-item__save-for-later:hover,
.cart-item__save-for-later:focus-visible {
  color: var(--yellow);
}

.saved-for-later {
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}

.saved-for-later[hidden] {
  display: none;
}

.saved-for-later__heading {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--white);
  margin: 0 0 1.6rem;
}

.saved-for-later__list {
  display: grid;
  gap: 1.6rem;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  padding: 0;
  margin: 0;
  list-style: none;
}

.saved-for-later__item {
  display: flex;
  gap: 1.2rem;
  align-items: flex-start;
  border: 1px solid var(--line);
  padding: 1.2rem;
}

.saved-for-later__item-image {
  width: 64px;
  height: 64px;
  object-fit: cover;
  background: var(--navy-2);
  flex-shrink: 0;
}

.saved-for-later__item-details {
  min-width: 0;
}

.saved-for-later__item-title {
  display: block;
  color: var(--white);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  margin-bottom: 0.4rem;
  overflow-wrap: anywhere;
}

.saved-for-later__item-price {
  display: block;
  color: var(--ink);
  font-size: var(--text-2xs);
  margin-bottom: 0.8rem;
}

.saved-for-later__item-move {
  background: transparent;
  border: 1px solid var(--yellow);
  color: var(--yellow);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.6rem 1.2rem;
  cursor: pointer;
}

.saved-for-later__item-move:hover,
.saved-for-later__item-move:focus-visible {
  background: var(--yellow);
  color: var(--navy);
}

/* ── TKD-UX-SPEC-002 §5.2 — RAIL (SCROLL-SNAP CAROUSEL) ──
   Native CSS scroll-snap per spec: fewer lines than Amazon's overflow:hidden
   + JS-paged rail, works with zero JS, and gives touch users the momentum
   scrolling they already expect. overscroll-behavior-x:contain stops a rail
   swipe at either end from triggering the browser's back/forward gesture. */
.tkd-rail-section__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.tkd-rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(165px, 1fr);
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
  padding-bottom: 0.4rem;
}

.tkd-rail > * {
  scroll-snap-align: start;
}

@media (prefers-reduced-motion: reduce) {
  .tkd-rail {
    scroll-behavior: auto;
  }
}

/* Chevrons are a desktop enhancement layered on top -- hidden on coarse
   (touch) pointers per spec §5.2, where native swipe already works. */
.tkd-rail__chevrons {
  display: flex;
  gap: 0.5rem;
}

@media (pointer: coarse) {
  .tkd-rail__chevrons {
    display: none;
  }
}

.tkd-rail__chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  background: var(--navy-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
  cursor: pointer;
}

.tkd-rail__chevron:hover:not(:disabled),
.tkd-rail__chevron:focus-visible {
  color: var(--accent-text);
  border-color: var(--line-y);
}

.tkd-rail__chevron:disabled {
  opacity: 0.4;
  cursor: default;
}

.tkd-rail__chevron--prev svg {
  transform: rotate(90deg);
}

.tkd-rail__chevron--next svg {
  transform: rotate(-90deg);
}
