/* ==========================================================================
   Dynamite Athletics storefront - design system
   --------------------------------------------------------------------------
   Everything visual is driven by the custom properties in :root. Change those
   (or use the brand lab at ?dev=1) and the whole site re-skins, including the
   SVG bike illustrations, which read their colours from the same variables.

   Contents
     1.  Tokens
     2.  Reset and base
     3.  Typography
     4.  Layout primitives
     5.  Buttons
     6.  Badges, chips and pills
     7.  Header, navigation and mega menu
     8.  Hero
     9.  Cards
     10. Shop: facets and results
     11. Product detail
     12. Basket drawer
     13. Forms
     14. Content blocks (services, steps, FAQ, legal)
     15. Footer
     16. Prototype notice, breadcrumbs, toasts
     17. Brand lab (dev only)
     18. Responsive
     19. Accessibility and motion
   ========================================================================== */

/* 1. Tokens ---------------------------------------------------------------- *
 * The palette lives here and the whole site is skinned from it - including the
 * SVG bike illustrations, which read these same variables.
 *
 * Three themes ship. "light" is the default; "graphite" is a softer, greyer
 * dark for anyone who wants the mood without the near-black; "dark" is the
 * original noir. Pick one with data-theme on the <html> element. brand.js sets
 * the default, the head script in each page reapplies a saved choice before
 * first paint, and the brand lab (?dev=1) swaps them live.
 *
 * There are two accent families, and they have different jobs:
 *
 *   GOLD   (--accent)      actions and brand marks. Primary buttons, the
 *                          wordmark tagline, the trust strip, prices-adjacent
 *                          emphasis. It is the colour you click or that says
 *                          "this is us".
 *   PURPLE (--secondary)   structure and interaction. Section labels, links,
 *                          anything selected, tabular headings, band tints.
 *                          It is the colour that describes the page.
 *
 * Colours used as TEXT are deliberately separate from colours used as FILLS.
 * Gold is lovely as a button fill with near-black text on it, but gold text on
 * a pale background is unreadable. So --accent is the fill and --accent-text is
 * the readable version of the same hue for each theme. The purple pair follows
 * the same rule: --secondary is the border or wash purple, which has to stay
 * visible against a dark theme's surface, and --secondary-fill is the purple
 * safe to put white text on.
 * ------------------------------------------------------------------------- */

/* Theme-independent tokens. */
:root {
  /* Type. No web fonts: nothing to load, nothing to block rendering. */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, "Noto Sans", sans-serif;
  --font-num: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, monospace;

  /* Space and shape. */
  --gap: 20px;
  --gap-lg: 32px;
  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 22px;
  --wrap: 1240px;
  --header-h: 104px;

  --transition: 160ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* ---- "light": warm off-white, the default ---- */
:root,
[data-theme="light"] {
  color-scheme: light;

  --bg: #f6f4ef;
  --surface: #ffffff;
  --surface-2: #f0ede6;
  --surface-3: #e5e1d6;
  /* The black header, mega menu and footer bands. The page is white, but the
     frame around it keeps the brand's black, gold and purple. */
  --chrome-bg: #0a0a0a;
  /* Solid, high-contrast buttons - not just inside the bands. */
  --solid: #0a0a0a;
  --solid-ink: #ffffff;
  --solid-hover: #262626;
  /* Used for the alternating band and other barely-there tints. */
  --tint-overlay: rgba(20, 18, 15, 0.04);

  /* Text, from most prominent to most incidental. All above 4.5:1 on --bg. */
  --ink: #2c2a26;
  --ink-strong: #14120f;
  --ink-soft: #4a4740;
  --ink-faint: #5f5b54;
  --ink-muted: #6b675f;
  --ink-ghost: rgba(20, 18, 15, 0.16);

  --line: rgba(20, 18, 15, 0.1);
  --line-strong: rgba(20, 18, 15, 0.22);

  /* Gold as a fill, and the same gold darkened until it can be read. */
  --accent: #d4af37;
  --accent-bright: #b8912a;
  --accent-text: #7d5f0f;
  --accent-text-hover: #5c4508;
  --accent-ink: #14120f;
  --accent-wash: rgba(212, 175, 55, 0.18);

  --secondary: #6d28d9;
  --secondary-fill: #6d28d9;
  --secondary-ink: #ffffff;
  --secondary-text: #5b21b6;
  --secondary-text-hover: #4c1d95;
  --secondary-wash: rgba(109, 40, 217, 0.1);
  /* The tint for whole alternating bands. Deliberately weaker than
     --secondary-wash: a muted caption sitting on a full-width tinted band has
     far less headroom than a label inside a small pill, and at wash strength
     muted text measured 4.35:1 here. Derived from --secondary so the brand
     lab's accent presets carry the band with them. */
  --band-tint: rgba(109, 40, 217, 0.06);
  --band-tint: color-mix(in srgb, var(--secondary) 6%, transparent);

  --ok-text: #14603a;
  --info-text: #4b5b6b;
  --danger: #c0392b;
  --danger-text: #b3261e;

  --shadow: 0 18px 40px rgba(20, 18, 15, 0.12);
  --shadow-sm: 0 6px 18px rgba(20, 18, 15, 0.08);
}

/* ---- "graphite": dark, but nothing like as black ---- */
[data-theme="graphite"] {
  color-scheme: dark;

  --bg: #191a1e;
  --surface: #212328;
  --surface-2: #2a2d33;
  --surface-3: #343840;
  --chrome-bg: #101114;
  --solid: #3a3f48;
  --solid-ink: #ffffff;
  --solid-hover: #474d57;
  --tint-overlay: rgba(255, 255, 255, 0.035);

  --ink: #e3e4e7;
  --ink-strong: #ffffff;
  --ink-soft: #b9bcc2;
  --ink-faint: #94979e;
  --ink-muted: #8a8e95;
  --ink-ghost: rgba(255, 255, 255, 0.22);

  --line: rgba(255, 255, 255, 0.1);
  --line-strong: rgba(255, 255, 255, 0.2);

  --accent: #d4af37;
  --accent-bright: #ffd700;
  --accent-text: #e0bd52;
  --accent-text-hover: #ffd700;
  --accent-ink: #14120f;
  --accent-wash: rgba(212, 175, 55, 0.14);

  --secondary: #8b5cf6;
  /* Darker than --secondary on purpose: white text needs 4.5:1, and #8b5cf6
     only reaches 4.2:1. The lighter value stays for borders and washes. */
  --secondary-fill: #7c3aed;
  --secondary-ink: #ffffff;
  --secondary-text: #cbb6ff;
  --secondary-text-hover: #ece2ff;
  --secondary-wash: rgba(139, 92, 246, 0.16);
  --band-tint: rgba(139, 92, 246, 0.06);
  --band-tint: color-mix(in srgb, var(--secondary) 6%, transparent);

  --ok-text: #6fdca0;
  --info-text: #a9bccd;
  --danger: #ff8080;
  --danger-text: #ff9c9c;

  --shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
  --shadow-sm: 0 6px 18px rgba(0, 0, 0, 0.35);
}

/* ---- "dark": the original noir ---- */
[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0a0a0a;
  --surface: #151515;
  --surface-2: #1c1c1c;
  --surface-3: #242424;
  --chrome-bg: #0a0a0a;
  --solid: #2a2d33;
  --solid-ink: #ffffff;
  --solid-hover: #383b42;
  --tint-overlay: rgba(255, 255, 255, 0.02);

  --ink: #ededed;
  --ink-strong: #ffffff;
  --ink-soft: #b8b8b8;
  --ink-faint: #8f8f8f;
  /* Lifted from #7a7a7a: on the noir page background muted text was already at
     4.89:1, and any tint over a band ate the remaining headroom. */
  --ink-muted: #858585;
  --ink-ghost: rgba(255, 255, 255, 0.22);

  --line: rgba(255, 255, 255, 0.08);
  --line-strong: rgba(255, 255, 255, 0.18);

  --accent: #d4af37;
  --accent-bright: #ffd700;
  --accent-text: #d4af37;
  --accent-text-hover: #ffd700;
  --accent-ink: #0a0a0a;
  --accent-wash: rgba(212, 175, 55, 0.12);

  --secondary: #7c3aed;
  --secondary-fill: #7c3aed;
  --secondary-ink: #ffffff;
  --secondary-text: #dcd0ff;
  --secondary-text-hover: #f0e9ff;
  --secondary-wash: rgba(124, 58, 237, 0.16);
  --band-tint: rgba(124, 58, 237, 0.06);
  --band-tint: color-mix(in srgb, var(--secondary) 6%, transparent);

  --ok-text: #57d68a;
  --info-text: #9fb3c8;
  --danger: #ff8080;
  --danger-text: #ff8080;

  --shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
  --shadow-sm: 0 6px 18px rgba(0, 0, 0, 0.4);
}

/* 2. Reset and base -------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* Anchor links must not hide under the sticky header. */
  scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
svg {
  max-width: 100%;
}

/* The site is dark-only by design. Keep form controls and scrollbars dark. */
input,
select,
textarea,
button {
  font: inherit;
  color: inherit;
}

body.no-scroll {
  overflow: hidden;
}

/* 3. Typography ------------------------------------------------------------ */
h1,
h2,
h3,
h4 {
  margin: 0 0 0.5em;
  line-height: 1.1;
  color: var(--ink-strong);
  font-weight: 800;
  letter-spacing: -0.02em;
}

h1 {
  font-size: clamp(2rem, 5vw, 3.4rem);
}
h2 {
  font-size: clamp(1.5rem, 3.2vw, 2.2rem);
}
h3 {
  font-size: 1.2rem;
}
h4 {
  font-size: 1rem;
}

p {
  margin: 0 0 1em;
}

/* Gold says "this acts"; purple says "this is a link". Keeping the two apart
   means neither has to carry both jobs. */
a {
  color: var(--secondary-text);
  text-decoration: none;
}

a:hover {
  color: var(--secondary-text-hover);
}

/* The small uppercase label used throughout the design. These are the purple
   thread that runs down every page. */
.eyebrow {
  display: block;
  margin: 0 0 10px;
  color: var(--secondary-text);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.eyebrow--secondary {
  color: var(--secondary-text);
}

/* For the rarer label that should read gold instead. */
.eyebrow--accent {
  color: var(--accent-text);
}

.lede {
  max-width: 62ch;
  color: var(--ink-soft);
  font-size: 1.06rem;
}

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

.small {
  font-size: 0.85rem;
}

.tiny {
  font-size: 0.76rem;
}

.strong {
  color: var(--ink-strong);
  font-weight: 700;
}

.nowrap {
  white-space: nowrap;
}

.price {
  font-family: var(--font-num);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--ink-strong);
  letter-spacing: -0.02em;
}

.price--lg {
  font-size: 2.2rem;
}

/* 4. Layout primitives ----------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 20px;
}

.section {
  padding: 64px 0;
}

.section--tight {
  padding: 40px 0;
}

/* The band that alternates down the page. Nudged towards purple rather than a
   neutral tint, so the page breathes lavender rather than grey - at
   --band-tint strength, which muted text can still sit on. */
.section--alt {
  background: linear-gradient(180deg, transparent, var(--band-tint) 40%, transparent);
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 28px;
}

.section-head p {
  margin: 0;
}

.grid {
  display: grid;
  gap: var(--gap);
}

.grid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.grid--products {
  grid-template-columns: repeat(auto-fill, minmax(min(276px, 100%), 1fr));
}

.stack > * + * {
  margin-top: 12px;
}

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

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

.rule {
  height: 1px;
  margin: 32px 0;
  border: 0;
  background: var(--line);
}

/* 5. Buttons --------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 13px 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--ink-strong);
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform var(--transition), background var(--transition),
    border-color var(--transition), color var(--transition);
}

.btn:hover {
  transform: translateY(-1px);
}

.btn:active {
  transform: translateY(0);
}

.btn--primary {
  background: var(--accent);
  color: var(--accent-ink);
}

.btn--primary:hover {
  background: var(--accent-bright);
  color: var(--accent-ink);
}

/* Solid black, to pair with the gold primary button and to carry the brand's
   black into the page itself rather than only the header and footer. */
.btn--dark {
  background: var(--solid);
  color: var(--solid-ink);
}

.btn--dark:hover {
  background: var(--solid-hover);
  color: var(--solid-ink);
}

.btn--outline {
  background: transparent;
  border-color: var(--line-strong);
  color: var(--ink-strong);
}

.btn--outline:hover {
  border-color: var(--secondary);
  color: var(--secondary-text);
}

.btn--ghost {
  background: transparent;
  color: var(--ink-soft);
}

.btn--ghost:hover {
  color: var(--accent-text-hover);
}

.btn--block {
  width: 100%;
}

.btn--sm {
  padding: 9px 14px;
  font-size: 0.72rem;
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* A link that behaves like a button. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.link-arrow::after {
  content: "\2192";
  transition: transform var(--transition);
}

.link-arrow:hover::after {
  transform: translateX(3px);
}

/* 6. Badges, chips and pills ----------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px;
  border-radius: 5px;
  background: var(--secondary-fill);
  color: var(--secondary-ink);
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.badge--accent {
  background: var(--accent);
  color: var(--accent-ink);
}

.badge--outline {
  background: transparent;
  border: 1px solid var(--line-strong);
  color: var(--ink-soft);
}

.badge--legal {
  background: var(--secondary-wash);
  border: 1px solid var(--secondary);
  color: var(--secondary-text);
}

/* Fulfilment state, used on cards and product pages. There is no "in
   stock" state: nothing is held, so the only honest label is that the bike
   is ordered from the manufacturer. It is deliberately not green. */
.stock {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.78rem;
  font-weight: 700;
}

.stock::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

.stock--made-to-order {
  color: var(--accent-text);
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-soft);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color var(--transition), color var(--transition),
    background var(--transition);
}

.chip:hover {
  border-color: var(--secondary);
  color: var(--ink-strong);
}

.chip__count {
  color: var(--ink-muted);
  font-size: 0.72rem;
}


.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* 7. Header, navigation and mega menu -------------------------------------- */

/* The header is mounted into a wrapper div. A sticky element cannot escape its
   parent's box, so a wrapper exactly as tall as the header made `position:
   sticky` do nothing: the whole header scrolled away. Taking the wrapper out of
   the layout box is what lets the header pin to the viewport. */
#header-slot {
  display: contents;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--chrome-bg);
  border-bottom: 1px solid var(--line);
}

/* ------------------------------------------------------------------------
 * The black frame.
 *
 * The page is white, but the header, mega menu and footer stay black so that
 * the brand's black, gold and purple are all still on the page. Rather than
 * restyling every rule inside them, this block redefines the content tokens
 * within that scope - so the header and footer rules below render correctly on
 * black without needing to know anything about it.
 *
 * Two details are deliberate. Accent-as-text goes back to being gold here
 * (--accent rather than the dark bronze used on white), because gold on black
 * measures 8.9:1. And the shadow becomes a true black, since a shadow designed
 * for white paper is invisible against black.
 * ---------------------------------------------------------------------- */
.site-header,
.site-footer {
  --ink: #f2f1ed;
  --ink-strong: #ffffff;
  --ink-soft: rgba(255, 255, 255, 0.76);
  --ink-faint: rgba(255, 255, 255, 0.62);
  --ink-muted: rgba(255, 255, 255, 0.52);
  --ink-ghost: rgba(255, 255, 255, 0.24);

  --line: rgba(255, 255, 255, 0.14);
  --line-strong: rgba(255, 255, 255, 0.26);

  --surface: #16161a;
  --surface-2: #1e1e22;
  --surface-3: #27272c;

  --accent-text: var(--accent);
  --accent-text-hover: var(--accent);
  /* The second declaration wins wherever color-mix is supported, which is every
     current browser; the first is the fallback if it is not. */
  --accent-text-hover: color-mix(in srgb, var(--accent) 72%, #ffffff);
  /* The frame is black, so purple-as-text goes pale here for the same reason
     gold does - a readable-on-white violet would disappear against #0a0a0a. */
  --secondary-text: #d8c9ff;
  --secondary-text-hover: #ffffff;

  --shadow: 0 18px 42px rgba(0, 0, 0, 0.45);
}

/* ------------------------------------------------------------------------
 * The revolving promo bar.
 *
 * One claim at a time, centred, in gold. Only the active item is in the DOM's
 * accessibility tree - the others carry `hidden` - so a screen reader is told
 * the offer that is actually on screen rather than all three at once.
 * ---------------------------------------------------------------------- */
.promo-bar {
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.promo-bar .wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding-top: 5px;
  padding-bottom: 5px;
}

.promo-bar__list {
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: center;
}

.promo-bar__item {
  color: var(--accent-text);
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.promo-bar__item.is-active {
  animation: promo-in 420ms ease both;
}

@keyframes promo-in {
  from {
    opacity: 0;
    transform: translateY(-3px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .promo-bar__item.is-active {
    animation: none;
  }
}

.promo-bar a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.promo-bar a:hover {
  border-bottom-color: currentColor;
}

/* ------------------------------------------------------------------------
 * Two-row header: the lockup on its own centred row, the navigation below it.
 *
 * The grid is 1fr / auto / 1fr so the logo sits on the true centre of the
 * page whatever the width of the controls either side of it. Centring it with
 * flex and margins only works while the two sides happen to be the same
 * width, which they never are once the search box gets wide.
 * ---------------------------------------------------------------------- */
.header-top {
  display: grid;
  /* minmax(0, 1fr), not 1fr: a 1fr track will not shrink below its content,
     so a wide search box on the right pushed the logo off centre. */
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 18px;
  min-height: 74px;
  padding-top: 8px;
  padding-bottom: 8px;
}

.header-top .wordmark {
  justify-self: center;
}

.header-top .header-actions {
  justify-self: end;
}

.header-nav {
  border-top: 1px solid var(--line);
}

.header-nav__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  line-height: 1;
  color: var(--ink-strong);
}

/* The full lockup: DYNAMITE with the lit stick for the I, and ATHLETICS under
   it. Drawn art, not type, so it carries its own spacing and cannot be
   re-created with CSS - hence an image and a fixed aspect ratio.

   Sized by height and allowed to find its own width, because 780x224 is the
   artwork's own proportion and forcing a width would squash the wordmark. The
   clamp keeps it level with the nav on a laptop and stops it crowding the
   actions on a narrow screen. */
.wordmark__logo {
  display: block;
  height: clamp(36px, 4.4vw, 54px);
  width: auto;
}

.wordmark--footer .wordmark__logo {
  height: 52px;
}

.wordmark:hover {
  color: var(--ink-strong);
  opacity: 0.92;
}

.nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin: 0;
}

.nav__link {
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  background: none;
  border: 0;
  cursor: pointer;
  transition: color var(--transition), background var(--transition);
}

.nav__link:hover,
.nav__link[aria-expanded="true"] {
  background: var(--surface-2);
  color: var(--ink-strong);
}

.nav__link[aria-current="page"] {
  color: var(--accent-text);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

.icon-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-strong);
  cursor: pointer;
  transition: border-color var(--transition), color var(--transition);
}

.icon-btn:hover {
  border-color: var(--accent);
  color: var(--accent-text-hover);
}

.icon-btn__count {
  position: absolute;
  top: -7px;
  right: -7px;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--secondary-fill);
  color: var(--secondary-ink);
  font-size: 0.68rem;
  font-weight: 800;
  line-height: 20px;
  text-align: center;
}

.icon-btn__count[hidden] {
  display: none;
}

/* Mega menu: opens under the header on desktop, inline on mobile. */
.mega {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  display: none;
  padding: 26px 0 30px;
  background: var(--surface);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow);
}

.mega.is-open {
  display: block;
}

.mega__grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 36px;
}

.mega__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 18px 26px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mega__cat {
  color: var(--secondary-text);
  font-size: 0.86rem;
  font-weight: 800;
}

.mega__subs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}

.mega__subs a {
  color: var(--ink-faint);
  font-size: 0.8rem;
}

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

.mega__brands {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.mega__foot {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  color: var(--ink-faint);
  font-size: 0.8rem;
}

.header-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

.header-search input {
  width: 170px;
  padding: 11px 0;
  border: 0;
  background: transparent;
  color: var(--ink-strong);
  outline: none;
}

.header-search input::placeholder {
  color: var(--ink-muted);
}

/* Mobile menu button and drawer. */
.nav-toggle {
  display: none;
}

/* 8. Hero ------------------------------------------------------------------ */
.hero {
  position: relative;
  overflow: hidden;
  padding: 76px 0 64px;
  border-bottom: 1px solid var(--line);
}

.hero::after {
  content: "";
  position: absolute;
  top: -30%;
  right: -12%;
  width: 620px;
  height: 620px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--secondary-wash), transparent 68%);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  align-items: center;
  gap: 40px;
}

.hero h1 {
  max-width: 16ch;
}

.hero__actions {
  margin-top: 26px;
}

.hero__art {
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--surface), var(--bg));
}

.hero__facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  margin-top: 30px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}

.fact__value {
  color: var(--accent-text);
  font-family: var(--font-num);
  font-size: 1.5rem;
  font-weight: 700;
}

.fact__label {
  color: var(--ink-faint);
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* 9. Cards ----------------------------------------------------------------- */
.card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  transition: transform var(--transition), border-color var(--transition),
    box-shadow var(--transition);
}

.card:hover {
  border-color: var(--secondary);
  transform: translateY(-3px);
  box-shadow: var(--shadow-sm);
}

.card__media {
  position: relative;
  background: linear-gradient(170deg, var(--surface-2), var(--bg));
  border-bottom: 1px solid var(--line);
}

.card__badges {
  position: absolute;
  top: 12px;
  left: 12px;
  right: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: space-between;
  pointer-events: none;
}

.card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 8px;
  padding: 18px;
}

/* The maker's name is a brand mark, not a structural label, so it stays gold
   while the section labels above each block are purple. */
.card__brand {
  color: var(--accent-text);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.card__title {
  margin: 0;
  font-size: 1.12rem;
  line-height: 1.25;
}

.card__title a {
  color: var(--ink-strong);
}

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

.card__meta {
  color: var(--ink-faint);
  font-size: 0.82rem;
}

.card__specs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  color: var(--ink-soft);
  font-size: 0.78rem;
}

.card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 16px;
}

.bike-art {
  display: block;
  width: 100%;
  height: auto;
}

/* Small category and brand tiles. */
.tile {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  transition: border-color var(--transition), transform var(--transition),
    background var(--transition);
}

.tile:hover {
  border-color: var(--secondary);
  background: var(--surface-2);
  color: var(--ink);
  transform: translateY(-2px);
}

.tile__name {
  color: var(--ink-strong);
  font-size: 1.02rem;
  font-weight: 800;
}

.tile__count {
  color: var(--ink-muted);
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.tile--brand {
  align-items: center;
  justify-content: center;
  min-height: 96px;
  text-align: center;
}

/* 10. Shop: facets and results --------------------------------------------- */

/* ------------------------------------------------------------------------
 * Brand profile.
 *
 * Shown at the top of a single-brand listing: the brand's own panel on the
 * left, the story and the facts on the right. The dark tile is deliberate - it
 * is the same black-and-gold the header uses, so a brand page reads as part of
 * the shop rather than as a page on the manufacturer's site.
 * ---------------------------------------------------------------------- */
.brand-profile {
  display: grid;
  grid-template-columns: minmax(210px, 300px) 1fr;
  gap: 32px;
  align-items: start;
  margin: 0 0 30px;
  padding: 26px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.brand-profile__id {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 22px 20px;
  border-radius: var(--radius-sm);
  background: #0b0a0d;
  border: 1px solid rgba(255, 255, 255, 0.14);
}

/* The name set as a mark. It is typographic on purpose: see the note at the
   top of brands.js about not faking manufacturers' artwork. */
.brand-profile__mark {
  color: var(--accent);
  font-size: clamp(1.5rem, 3.2vw, 2.1rem);
  font-weight: 900;
  letter-spacing: 0.04em;
  line-height: 1;
}

.brand-profile__legal {
  color: rgba(255, 255, 255, 0.62);
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  line-height: 1.4;
}

.brand-profile__body {
  min-width: 0;
}

.brand-profile__body .lede {
  margin-top: 0;
}

.brand-profile__facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 24px;
  margin: 20px 0 22px;
  padding: 18px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.brand-profile__facts dt {
  color: var(--ink-muted);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 3px;
}

.brand-profile__facts dd {
  margin: 0;
  font-weight: 600;
}

.brand-profile__points {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 14px;
}

.brand-profile__points li {
  display: grid;
  gap: 3px;
}

.brand-profile__source {
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

.shop-layout {
  display: grid;
  grid-template-columns: 290px minmax(0, 1fr);
  align-items: start;
  gap: 34px;
}

.filters {
  position: sticky;
  top: calc(var(--header-h) + 18px);
  max-height: calc(100vh - var(--header-h) - 40px);
  overflow-y: auto;
  padding-right: 6px;
}

.facet {
  border-bottom: 1px solid var(--line);
  padding: 16px 0;
}

.facet:first-of-type {
  padding-top: 0;
}

.facet__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: var(--secondary-text);
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}

.facet__head::after {
  content: "\2212";
  color: var(--ink-muted);
  font-size: 1rem;
}

.facet[data-collapsed="true"] .facet__head::after {
  content: "+";
}

.facet[data-collapsed="true"] .facet__body {
  display: none;
}

.facet__body {
  margin-top: 12px;
}

.facet__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: 260px;
  overflow-y: auto;
}

.check {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  font-size: 0.88rem;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}

.check:hover {
  background: var(--surface-2);
  color: var(--ink-strong);
}

.check input {
  width: 17px;
  height: 17px;
  accent-color: var(--accent);
  flex: none;
}

.check__count {
  margin-left: auto;
  color: var(--ink-muted);
  font-size: 0.74rem;
}

.check--sub {
  padding-left: 22px;
  font-size: 0.84rem;
}

.range-field {
  display: block;
  margin-bottom: 14px;
}

.range-field__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 6px;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.range-field__value {
  color: var(--accent-text);
  font-family: var(--font-num);
  font-weight: 700;
}

input[type="range"] {
  width: 100%;
  height: 22px;
  background: transparent;
  accent-color: var(--accent);
  cursor: pointer;
}

.results-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 20px;
}

.select {
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--ink-strong);
  font-size: 0.85rem;
}

.active-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 18px;
}

/* An applied filter, with its own remove button. Purple to match the chip that
   is currently selected - they are two views of the same state. */
.filter-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 10px;
  border: 1px solid var(--secondary);
  border-radius: 999px;
  background: var(--secondary-wash);
  color: var(--secondary-text);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}

.filter-pill::after {
  content: "\00d7";
  font-size: 1rem;
  line-height: 1;
}

.filters-toggle {
  display: none;
}

.empty-state {
  padding: 56px 24px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  text-align: center;
}

.sample-note {
  display: flex;
  gap: 10px;
  padding: 12px 14px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--tint-overlay);
  color: var(--ink-faint);
  font-size: 0.8rem;
}

.sample-note strong {
  color: var(--ink-soft);
}

/* 11. Product detail ------------------------------------------------------- */
.breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 18px 0;
  color: var(--ink-muted);
  font-size: 0.8rem;
}

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

/* Breadcrumbs are navigation, so they hover purple like every other link. */
.breadcrumbs a:hover {
  color: var(--secondary-text-hover);
}

.breadcrumbs span[aria-hidden] {
  color: var(--line-strong);
}

.product-layout {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  align-items: start;
  gap: 40px;
}

.gallery__main {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: linear-gradient(165deg, var(--surface-2), var(--bg));
}

/* The manufacturer's photograph. `contain` rather than `cover`: cropping a
   bike shot cuts the wheels off, and a bike missing its wheels does not sell. */
.gallery__photo {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: contain;
  padding: 14px;
  border-radius: var(--radius-lg);
}

/* On a card the photo sits on the same tinted panel the illustration used, and
   the tile keeps its own proportions so a row of cards stays even. */
.card__photo {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  padding: 10px;
}

.gallery__thumbs {
  display: flex;
  gap: 10px;
  margin-top: 12px;
}

.thumb img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
}

.thumb {
  flex: 1;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
}

.thumb[aria-pressed="true"] {
  border-color: var(--secondary);
}

.buybox {
  position: sticky;
  top: calc(var(--header-h) + 18px);
  padding: 26px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.buybox__title {
  font-size: 1.9rem;
  line-height: 1.1;
}

.buybox__price-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 14px 0;
}

.size-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.size {
  min-width: 62px;
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--ink);
  font-size: 0.84rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}

.size:hover {
  border-color: var(--secondary);
}

/* The chosen frame size. Purple, like every other selection. */
.size[aria-pressed="true"] {
  border-color: var(--secondary);
  background: var(--secondary-wash);
  color: var(--secondary-text);
}

.size[data-stock="pre-order"] {
  color: var(--ink-faint);
}

.size__stock {
  display: block;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.spec-table th,
.spec-table td {
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

.spec-table th {
  width: 42%;
  color: var(--ink-faint);
  font-weight: 600;
}

.spec-table td {
  color: var(--ink);
}

.legal-panel {
  padding: 18px;
  border: 1px solid var(--secondary);
  border-radius: var(--radius);
  background: var(--secondary-wash);
}

.legal-panel h3 {
  font-size: 0.86rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.legal-panel ul {
  margin: 0;
  padding-left: 18px;
  font-size: 0.88rem;
  color: var(--secondary-text);
}

.trust-list {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.88rem;
}

.trust-list li {
  display: flex;
  gap: 10px;
  color: var(--ink-soft);
}

.trust-list li::before {
  content: "\2713";
  color: var(--secondary-text);
  font-weight: 800;
}

/* 12. Basket drawer -------------------------------------------------------- */
.drawer {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  width: min(420px, 100vw);
  height: 100%;
  background: var(--surface);
  border-left: 1px solid var(--line);
  box-shadow: var(--shadow);
  transform: translateX(102%);
  transition: transform 220ms cubic-bezier(0.2, 0.7, 0.3, 1);
  visibility: hidden;
}

.drawer.is-open {
  transform: translateX(0);
  visibility: visible;
}

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px;
  border-bottom: 1px solid var(--line);
}

.drawer__head h2 {
  margin: 0;
  font-size: 1rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.drawer__body {
  flex: 1;
  overflow-y: auto;
  padding: 18px 20px;
}

.drawer__foot {
  padding: 18px 20px;
  border-top: 1px solid var(--line);
  background: var(--bg);
}

.backdrop {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(0, 0, 0, 0.65);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--transition), visibility var(--transition);
}

.backdrop.is-open {
  opacity: 1;
  visibility: visible;
}

.basket-line {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr);
  gap: 14px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}

.basket-line__media {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg);
  overflow: hidden;
}

/* Same footprint as the drawing it replaces, so a basket row does not change
   height depending on whether the bike has a photograph. */
.basket-line__photo {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: contain;
}

.basket-line__name {
  color: var(--ink-strong);
  font-size: 0.92rem;
  font-weight: 700;
}

.basket-line__meta {
  color: var(--ink-muted);
  font-size: 0.78rem;
}

.basket-line__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 8px;
}

.qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.qty button {
  width: 30px;
  height: 30px;
  border: 0;
  background: var(--surface-2);
  color: var(--ink-strong);
  cursor: pointer;
}

.qty button:hover {
  background: var(--surface-3);
  color: var(--accent-text-hover);
}

.qty span {
  min-width: 32px;
  text-align: center;
  font-family: var(--font-num);
  font-size: 0.9rem;
}

.totals {
  display: grid;
  gap: 8px;
  margin-bottom: 14px;
  font-size: 0.9rem;
}

.totals__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  color: var(--ink-soft);
}

.totals__row--grand {
  padding-top: 10px;
  border-top: 1px solid var(--line);
  color: var(--ink-strong);
  font-size: 1.1rem;
  font-weight: 800;
}

/* 13. Forms ---------------------------------------------------------------- */
.field {
  display: block;
  margin-bottom: 16px;
}

.field__label {
  display: block;
  margin-bottom: 6px;
  color: var(--ink-soft);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.input,
.textarea,
.select--full {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--ink-strong);
  outline: none;
  transition: border-color var(--transition), box-shadow var(--transition);
}

.input:focus,
.textarea:focus,
.select--full:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
}

.textarea {
  min-height: 120px;
  resize: vertical;
}

.field__hint {
  margin-top: 6px;
  color: var(--ink-muted);
  font-size: 0.76rem;
}

.field__error {
  margin-top: 6px;
  color: var(--danger-text);
  font-size: 0.78rem;
  font-weight: 600;
}

.input[aria-invalid="true"],
.textarea[aria-invalid="true"] {
  border-color: var(--danger);
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 18px;
}

.radio-card {
  display: flex;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}

.radio-card:hover {
  border-color: var(--accent);
}

.radio-card:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-wash);
}

.radio-card input {
  margin-top: 4px;
  accent-color: var(--accent);
}

.checkbox-line {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 0.86rem;
  color: var(--ink-soft);
}

.checkbox-line input {
  margin-top: 4px;
  accent-color: var(--accent);
}

.form-note {
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--ink-faint);
  font-size: 0.82rem;
}

/* Checkout: the form beside the order summary. Kept in the stylesheet rather
   than set inline by the page script, so the responsive rule below can
   actually override it - an inline grid-template-columns cannot be undone by a
   media query, which is what used to push the summary off the side of a phone. */
.checkout-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  gap: 40px;
  align-items: start;
  padding-bottom: 64px;
}

/* 14. Content blocks ------------------------------------------------------- */
/* min(220px, 100%) rather than a bare 220px: a grid track will not shrink
   below its minimum, so a fixed minimum makes the page overflow on a very
   narrow screen instead of just getting cramped. */
.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 22px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.step {
  padding-top: 18px;
  border-top: 2px solid var(--line-strong);
}

.step::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  display: block;
  margin-bottom: 8px;
  color: var(--secondary-text);
  font-family: var(--font-num);
  font-size: 1.1rem;
  font-weight: 700;
}

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

.faq details {
  border-bottom: 1px solid var(--line);
}

.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 0;
  color: var(--ink-strong);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}

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

.faq summary::after {
  content: "+";
  color: var(--secondary-text);
  font-size: 1.3rem;
  font-weight: 400;
}

.faq details[open] summary::after {
  content: "\2212";
}

.faq__body {
  padding: 0 0 20px;
  max-width: 78ch;
  color: var(--ink-soft);
  font-size: 0.94rem;
}

.faq__body ul {
  padding-left: 20px;
}

.prose {
  max-width: 72ch;
}

.prose h2 {
  margin-top: 1.6em;
}

.prose h3 {
  margin-top: 1.3em;
}

.prose ul,
.prose ol {
  padding-left: 20px;
  color: var(--ink-soft);
}

.prose li {
  margin-bottom: 0.5em;
}

.prose .callout {
  padding: 16px 18px;
  border-left: 3px solid var(--secondary);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--surface-2);
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.anchor-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 32px;
}

.service-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.service-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 11px;
  background: var(--secondary-wash);
  color: var(--secondary-text);
  font-size: 1.2rem;
}

.plan {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.plan--featured {
  border-color: var(--accent);
  background: linear-gradient(180deg, var(--accent-wash), var(--surface) 55%);
}

.plan__price {
  font-family: var(--font-num);
  font-size: 1.9rem;
  font-weight: 700;
  color: var(--ink-strong);
}

.plan ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
  font-size: 0.88rem;
  color: var(--ink-soft);
}

.plan ul li::before {
  content: "\2713";
  margin-right: 9px;
  color: var(--accent-text);
}

/* A whole band tinted with the brand purple. Gold is reserved for the button
   inside it, so the two colours do not compete. */
.cta-band {
  padding: 44px;
  border: 1px solid var(--secondary);
  border-radius: var(--radius-lg);
  background: linear-gradient(120deg, var(--secondary-wash), var(--surface) 62%);
}

/* 15. Footer --------------------------------------------------------------- */
.site-footer {
  margin-top: 64px;
  padding: 52px 0 26px;
  border-top: 1px solid var(--line);
  background: var(--chrome-bg);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: 34px;
}

.footer-col h4 {
  margin-bottom: 14px;
  color: var(--secondary-text);
  font-size: 0.74rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.footer-col ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 9px;
}

.footer-col a,
.footer-col li {
  color: var(--ink-faint);
  font-size: 0.86rem;
}

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

.footer-legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 40px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  color: var(--ink-muted);
  font-size: 0.78rem;
}

.footer-legal p {
  margin: 0;
}

.footer-vat {
  font-family: var(--font-num);
}

/* 16. Prototype notice, toasts --------------------------------------------- */
.prototype-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 20px;
  background: var(--secondary-fill);
  color: var(--secondary-ink);
  font-size: 0.78rem;
}

.prototype-bar strong {
  flex: none;
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.28);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.prototype-bar button {
  margin-left: auto;
  border: 0;
  background: none;
  color: var(--secondary-ink);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
}

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

.toasts {
  position: fixed;
  left: 50%;
  bottom: 24px;
  z-index: 120;
  display: grid;
  gap: 10px;
  transform: translateX(-50%);
  width: min(420px, calc(100vw - 32px));
  pointer-events: none;
}

.toast {
  padding: 13px 16px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  box-shadow: var(--shadow);
  color: var(--ink-strong);
  font-size: 0.88rem;
  font-weight: 600;
}

.toast--error {
  border-color: var(--danger);
}

/* 17. Brand lab (dev only) ------------------------------------------------- */
.brandlab {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 130;
  width: min(330px, calc(100vw - 32px));
  padding: 18px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface-2);
  box-shadow: var(--shadow);
  font-size: 0.85rem;
}

.brandlab h3 {
  margin: 0 0 4px;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.brandlab__row {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

.brandlab__swatches {
  display: flex;
  gap: 6px;
  margin-top: 12px;
}

.brandlab__swatches span {
  width: 26px;
  height: 26px;
  border-radius: 6px;
  border: 1px solid var(--line-strong);
}

.brandlab select {
  width: 100%;
  margin-top: 10px;
}

.brandlab code {
  font-family: var(--font-num);
  font-size: 0.92em;
  color: inherit;
}

.brandlab kbd {
  padding: 1px 5px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: var(--surface);
  font-family: var(--font-num);
  font-size: 0.9em;
}

/* Live contrast readout, so a colour choice is never a guess. */
.brandlab__checks {
  display: grid;
  gap: 3px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}

.brandlab__check {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 0.74rem;
  color: var(--ink-muted);
}

.brandlab__check .is-ok,
.brandlab__check .is-warn {
  font-family: var(--font-num);
  font-weight: 700;
}

.brandlab__check .is-ok {
  color: var(--ok-text);
}

.brandlab__check .is-warn {
  color: var(--danger-text);
}

/* 18. Responsive ----------------------------------------------------------- */
@media (max-width: 620px) {
  /* There is room to give the name its old weight back once the nav and the
     search box have collapsed into the drawer. */
  /* The lockup is wider than the old two-line text on a phone, and would push
     into the buttons at the other end of the header. */
  .wordmark__logo {
    height: 34px;
  }
}

@media (max-width: 1200px) {
  /* A two-word wordmark takes about 200px that a seven-letter one did not, so
     the search box goes before the navigation does. The nav itself tightens
     up rather than spilling off the right-hand edge. */
  .header-search {
    display: none;
  }
  .nav {
    gap: 0;
    margin-left: 6px;
  }
  .nav__link {
    padding: 10px 9px;
  }
}

@media (max-width: 1080px) {
  .hero__inner {
    grid-template-columns: 1fr;
  }
  .shop-layout {
    grid-template-columns: 240px minmax(0, 1fr);
    gap: 24px;
  }
  .product-layout,
  .checkout-layout {
    grid-template-columns: 1fr;
    gap: 28px;
  }
  .buybox {
    position: static;
  }
  .footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 28px;
  }
  .header-search input {
    width: 130px;
  }
}

@media (max-width: 900px) {
  :root {
    --header-h: 96px;
  }

  /* Navigation collapses into a single drawer on small screens. */
  .nav-toggle {
    display: inline-flex;
  }

  .nav,
  .header-search {
    display: none;
  }

  /* The nav row exists only to hold the centred menu on a wide screen. On a
     phone the menu lives in the drawer, so the row goes to zero height - but
     it cannot be display:none, because the drawer panel is a child of it. */
  .header-nav {
    border-top: 0;
  }

  .header-nav__inner {
    min-height: 0;
  }

  .nav.is-open {
    display: flex;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
    margin: 0;
    padding: 14px 20px 26px;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow);
  }

  .nav.is-open .nav__link {
    padding: 14px 4px;
    font-size: 0.95rem;
    border-bottom: 1px solid var(--line);
    text-align: left;
  }

  .mega,
  .mega.is-open {
    position: static;
    display: none;
    padding: 14px 0 4px;
    border: 0;
    box-shadow: none;
    background: transparent;
  }

  .mega.is-open {
    display: block;
  }

  .mega__grid {
    grid-template-columns: 1fr;
    gap: 20px;
  }

  .shop-layout {
    grid-template-columns: 1fr;
  }

  .brand-profile {
    grid-template-columns: 1fr;
    gap: 20px;
    padding: 20px;
  }

  .filters {
    position: static;
    display: none;
    max-height: none;
    padding: 20px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
  }

  .filters.is-open {
    display: block;
  }

  .filters-toggle {
    display: inline-flex;
  }

  .form-grid,
  .grid--2,
  .grid--3,
  .grid--4 {
    grid-template-columns: 1fr;
  }

  .hero {
    padding: 44px 0 36px;
  }

  .cta-band {
    padding: 28px;
  }
}

@media (max-width: 620px) {
  .grid--products {
    grid-template-columns: 1fr;
  }
  .hero__facts {
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .footer-grid {
    grid-template-columns: 1fr;
  }
  .section {
    padding: 44px 0;
  }
  .promo-bar__item {
    font-size: 0.62rem;
    letter-spacing: 0.06em;
  }

  /* Two columns of facts on a phone gives each one about 140px, which turns a
     warranty sentence into a ladder of four-word lines. */
  .brand-profile__facts {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .header-actions .btn span.label {
    display: none;
  }
}

/* 19. Accessibility and motion --------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 2px;
}

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

.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 200;
  padding: 10px 16px;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 800;
  border-radius: var(--radius-sm);
  transition: top var(--transition);
}

.skip-link:focus {
  top: 12px;
}

/* Applied for a single frame by the brand lab (assets/js/devpanel.js) while it
   rewrites the palette variables. Re-skinning the site should land instantly
   rather than animating hundreds of elements at once - and without this, a
   transition whose duration itself comes from a custom property (see .btn)
   can hold the previous colour after the variables change. */
.no-transitions,
.no-transitions *,
.no-transitions *::before,
.no-transitions *::after {
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* 20. Home: departments, wide picture band and the company block ----------- */

/* Department tiles. All one size on purpose: the departments are given equal
   weight, so nothing implies a favourite. */
.tile--dept {
  gap: 8px;
  min-height: 168px;
}

.tile__go {
  margin-top: auto;
  color: var(--accent-text);
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.02em;
}

.tile--soon {
  border-style: dashed;
  background: transparent;
}

.tile--soon .tile__go {
  color: var(--secondary-text);
}

/* Brand tiles: the photograph is the evidence that we actually stock the
   brand, so it sits above the name rather than beside it. */
.tile--brand {
  gap: 8px;
  padding: 14px 18px 18px;
}

.tile__media {
  display: block;
  width: 100%;
}

.tile__photo {
  display: block;
  width: 100%;
  height: 148px;
  object-fit: contain;
}

/* The full-width band. The drawing fills the section and a left-to-right wash
   of the page background keeps the copy readable against it in all three
   themes without needing a colour that only works in one of them. */
.band {
  position: relative;
  overflow: hidden;
  min-height: 440px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.band__art-slot {
  position: absolute;
  inset: 0;
}

.band__art-slot svg {
  display: block;
  width: 100%;
  height: 100%;
}

.band__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--bg) 6%, transparent 78%);
}

.band__inner {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  min-height: 440px;
  padding-top: 56px;
  padding-bottom: 56px;
}

.band__copy {
  max-width: 34rem;
}

.band__copy h2 {
  margin-bottom: 10px;
}

.band__copy p {
  margin: 0;
  color: var(--ink);
}

/* The company block. */
.company__media {
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--surface), var(--bg));
}

.company__art,
.company__photo {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
}

.company__photo {
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.company__facts {
  display: grid;
  gap: 10px 22px;
  margin: 22px 0;
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
}

.company__facts dt {
  color: var(--secondary-text);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.company__facts dd {
  margin: 2px 0 0;
  color: var(--ink-strong);
  font-weight: 700;
}

.company__lists {
  gap: 34px 44px;
  margin-top: 40px;
}

.company__block h3 {
  margin-bottom: 14px;
  font-size: 1.12rem;
}

.company__points {
  display: grid;
  gap: 18px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.company__points li {
  display: grid;
  gap: 4px;
  padding-left: 18px;
  border-left: 3px solid var(--accent);
}

.company__points strong {
  color: var(--ink-strong);
}

/* Outstanding details. Deliberately not styled to look like a warning banner -
   it is a build note for whoever finishes the site, not a customer message. */
.pending-note {
  margin-top: 40px;
  padding: 20px 22px;
  border: 1px dashed var(--secondary);
  border-radius: var(--radius);
  background: var(--secondary-wash);
  color: var(--ink);
}

.pending-note > strong {
  display: block;
  margin-bottom: 8px;
  color: var(--ink-strong);
}

.pending-note ul {
  margin: 0;
  padding-left: 20px;
}

@media (max-width: 760px) {
  .band {
    min-height: 460px;
  }

  .band__inner {
    min-height: 460px;
  }

  .band__scrim {
    background: linear-gradient(180deg, var(--bg) 14%, transparent 92%);
  }

  .band__copy {
    max-width: none;
  }
}
