/* SunX — base + components. Depends on tokens.css. */

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* Guards every section against a stray wide child pushing the page sideways. */
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

/* Pictures are not draggable. The `draggable="false"` attribute covers the
   drag itself; this covers the ghost image Safari and older WebKit still
   render while the pointer moves, which is the part that makes a blocked drag
   look broken rather than refused.

   Scoped to img, and to the one property. There is deliberately no blanket
   `user-select: none` here: the SKU, the order number, the address and every
   line of body copy have to stay selectable and copyable. */
img { -webkit-user-drag: none; user-drag: none; }

/* iOS shows a save/copy sheet on a long press. Withholding it on the
   photographs only — never on links, never on the gallery's own controls, and
   never on anything inside a form — leaves swipe, pinch, scroll and tap
   behaving exactly as they did. */
[data-protect] { -webkit-touch-callout: none; }
a { color: inherit; text-decoration: none; }
button, input, select { font: inherit; color: inherit; }
ul { list-style: none; padding: 0; }

:focus-visible {
  outline: 2px solid var(--yellow);
  outline-offset: 3px;
  border-radius: 4px;
}

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

/* ------------------------------------------------------------- typography */

h1, h2, h3, .display {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: .98;
  letter-spacing: -.02em;
  text-wrap: balance;
}

.eyebrow {
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--yellow);
}

.section-head { max-width: 62ch; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.section-head h2 { font-size: var(--fs-h2); margin: 1rem 0 .9rem; }
.section-head.is-centered { text-align: center; margin-inline: auto; }
.section-head.is-centered .eyebrow { justify-content: center; }
.lead { font-size: var(--fs-lead); color: var(--text-2); text-wrap: pretty; }

.fineprint {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-top: 1rem;
  font-size: var(--fs-xs);
  color: var(--text-3);
}

/* Every inline icon shares one size contract. Without it an SVG with no
   intrinsic dimensions stretches to the flex line and wraps its own label. */
.ico { width: 18px; height: 18px; flex: none; }
.eyebrow .ico { width: 15px; height: 15px; }

/* ----------------------------------------------------------------- layout */

.shell { width: 100%; max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); }
.shell-wide { max-width: var(--shell-wide); }
/* A single column of prose and one action — the order confirmation. */
.shell-narrow { max-width: 62ch; }
.section { padding-block: var(--section); position: relative; }
/* Alternating band so long pages keep a rhythm without extra dividers. */
.section.is-raised { background: var(--surface-1); border-block: 1px solid var(--line); }

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

.btn {
  --btn-bg: var(--surface-3);
  --btn-fg: var(--text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  min-height: 52px;
  padding: 0 1.6rem;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-weight: 700;
  font-size: var(--fs-sm);
  letter-spacing: .01em;
  cursor: pointer;
  transition: transform .18s var(--ease), background .18s, box-shadow .25s, border-color .18s;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; }

.btn-primary {
  --btn-bg: var(--yellow);
  --btn-fg: #0B0B06;
  font-weight: 800;
}
.btn-primary:hover { --btn-bg: #FFF95C; box-shadow: var(--glow-yellow); }

.btn-ghost { --btn-bg: transparent; border-color: var(--line-strong); }
.btn-ghost:hover { border-color: var(--yellow); color: var(--yellow); }

.btn-lg { min-height: 60px; padding: 0 2.2rem; font-size: 1rem; }
.btn-block { width: 100%; }

/* ----------------------------------------------------------------- header */

/* The free-shipping bar stays put.
   It used to scroll away with the page and then be covered outright by the
   mobile drawer, so the one line telling you shipping is free disappeared at
   exactly the moment you went looking for the shop. Sticky above the header,
   and the drawer starts below it. Its height is measured in app.js into
   --announce-h, because the line wraps to two rows under about 380px and a
   hard-coded offset would clip the header there. */
.announce {
  position: sticky;
  top: 0;
  z-index: 260;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .1rem .45rem;
  background: linear-gradient(90deg, var(--surface-2), var(--surface-1));
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-xs);
  color: var(--text-2);
  text-align: center;
  padding: .6rem var(--gutter);
}
.announce strong { color: var(--yellow); font-weight: 700; }
.announce .ico { width: 14px; height: 14px; color: var(--yellow); }

.header {
  position: sticky;
  top: var(--announce-h, 0px);
  z-index: 100;
  border-bottom: 1px solid transparent;
  transition: background .3s, border-color .3s, backdrop-filter .3s;
}

/* A lit seam under the header. Brightest in the middle and gone before either
   end, so it reads as light spilling from the bar rather than as a rule drawn
   across the page — the same idea as the filament on the consent module, which
   is the one place this site is allowed to glow. */
.header::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(254, 245, 24, .12) 18%,
    rgba(254, 245, 24, .75) 50%,
    rgba(254, 245, 24, .12) 82%,
    transparent 100%);
  box-shadow: 0 0 18px rgba(254, 245, 24, .3);
  opacity: .55;
  transition: opacity .3s;
}
/* Once the page has moved the header has a real edge, and the seam sits on it
   at full strength. */
.header.is-stuck::after { opacity: 1; }
/* Only frosts once the page has moved, so the hero stays uninterrupted. */
.header.is-stuck {
  background: rgba(8, 10, 13, .78);
  backdrop-filter: blur(18px) saturate(140%);
  border-bottom-color: var(--line);
}
.header-inner {
  display: flex;
  align-items: center;
  gap: clamp(.75rem, 2.2vw, 2rem);
  min-height: 88px;
}
.logo img { height: clamp(42px, 4.6vw, 64px); width: auto; }

.nav { display: flex; gap: clamp(.65rem, 1.5vw, 1.5rem); margin-inline-start: auto; }
.nav a {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-2);
  padding-block: .5rem;
  white-space: nowrap;
  transition: color .2s;
}
.nav a .ico { width: 16px; height: 16px; color: var(--text-3); transition: color .2s; }
.nav a:hover { color: var(--text); }
.nav a:hover .ico { color: var(--yellow); }
.nav a::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--yellow);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .3s var(--ease);
}
.nav a:hover::after { transform: scaleX(1); }

.header-actions { display: flex; align-items: center; gap: .5rem; }
.header-actions .btn { white-space: nowrap; }

/* ------------------------------------------------------ language switcher */

.flag { width: 22px; height: 22px; flex: none; border-radius: 50%; }

.lang { position: relative; }
.lang > summary {
  display: flex;
  align-items: center;
  gap: .4rem;
  height: 44px;
  padding: 0 .55rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  cursor: pointer;
  list-style: none;
  transition: border-color .2s;
}
.lang > summary::-webkit-details-marker { display: none; }
.lang > summary:hover { border-color: var(--line-strong); }
.lang-code { font-size: var(--fs-xs); font-weight: 800; letter-spacing: .06em; }
.lang-chev { width: 14px; height: 14px; color: var(--text-3); transition: transform .2s; }
.lang[open] .lang-chev { transform: rotate(180deg); }

.lang-menu {
  position: absolute;
  top: calc(100% + .5rem);
  inset-inline-end: 0;
  z-index: 120;
  min-width: 190px;
  padding: .4rem;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
}
.lang-menu a {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .55rem .6rem;
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-2);
  transition: background .15s, color .15s;
}
.lang-menu a:hover { background: var(--surface-3); color: var(--text); }
.lang-menu a.is-active { color: var(--yellow); background: var(--yellow-wash); }

/* Footer / drawer variant: flags only, laid out in a row. */
.lang-row { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.4rem; }
.lang-row a {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  border: 1px solid var(--line);
  border-radius: 50%;
  transition: border-color .2s, transform .2s var(--ease);
}
.lang-row a:hover { border-color: var(--yellow); transform: translateY(-2px); }
.lang-row a.is-active { border-color: var(--yellow); box-shadow: 0 0 0 3px var(--yellow-wash); }
.lang-row a span {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.icon-btn {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: transparent;
  cursor: pointer;
  transition: border-color .2s, color .2s;
}
.icon-btn:hover { border-color: var(--line-strong); color: var(--yellow); }
.icon-btn svg { width: 19px; height: 19px; }

.burger { display: none; }

/* ------------------------------------------------------------------- hero */

.hero {
  position: relative;
  min-height: min(78vh, 740px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-top: clamp(2rem, 5vw, 3.5rem);
  padding-bottom: clamp(1.5rem, 4vw, 3rem);
  overflow: hidden;
  isolation: isolate;
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
/* The banner is a wide composition (car · bulbs · road). At desktop widths the
   hero box is close to its native 2.33:1, so centring keeps all three visible;
   narrower boxes crop inward and we bias toward the product. */
.hero-media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; }
@media (max-width: 1200px) { .hero-media img { object-position: 62% 50%; } }
/* Two stacked scrims: vertical for text legibility, horizontal so the product
   stays readable on the right while the copy sits on solid ground. */
.hero-media::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(8,10,13,.88) 0%, rgba(8,10,13,.2) 30%, rgba(8,10,13,.94) 88%),
    linear-gradient(90deg, rgba(8,10,13,.94) 0%, rgba(8,10,13,.8) 26%, rgba(8,10,13,.34) 58%, transparent 82%);
}

.hero-copy { max-width: 72ch; }
.hero h1 {
  max-width: 14ch;
  font-size: var(--fs-hero);
  font-weight: 800;
  margin: 1rem 0 1.1rem;
}
.hero h1 em {
  display: block;
  font-style: normal;
  color: var(--yellow);
}
.hero .lead { max-width: 60ch; }

.hero-bullets {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .45rem;
  margin-top: 1.2rem;
}
.hero-bullets li {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .36rem .72rem .36rem .58rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: rgba(16,19,24,.72);
  backdrop-filter: blur(10px);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--text-2);
}
.hero-bullets .ico { width: 14px; height: 14px; color: var(--yellow); }

/* --------------------------------------------------------- vehicle finder */

.finder {
  margin-top: clamp(1.75rem, 3.5vw, 2.75rem);
  background: linear-gradient(160deg, rgba(23,27,33,.96), rgba(16,19,24,.96));
  border: 1px solid var(--line-strong);
  border-radius: var(--r-2xl);
  box-shadow: var(--shadow-lg);
  backdrop-filter: blur(20px);
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
.finder-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .75rem 1.25rem; margin-bottom: 1.4rem; }
.finder-head h2 { font-size: clamp(1.15rem, 2vw, 1.5rem); }
.finder-head p { font-size: var(--fs-sm); color: var(--text-2); }

.finder-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  gap: .85rem;
}
.field { position: relative; display: flex; flex-direction: column; gap: .45rem; }
.field > label {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-3);
}
.select-wrap { position: relative; }
.select-wrap select {
  appearance: none;
  width: 100%;
  min-height: 58px;
  padding: 0 3rem 0 1.15rem;
  background: var(--surface-1);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: border-color .2s, background .2s;
}
.select-wrap select:hover:not(:disabled) { border-color: #3C434F; }
.select-wrap select:focus { border-color: var(--yellow); outline: none; }
.select-wrap select:disabled { opacity: .45; cursor: not-allowed; }
.select-wrap::after {
  content: '';
  position: absolute;
  right: 1.15rem; top: 50%;
  width: 9px; height: 9px;
  border-right: 2px solid var(--text-2);
  border-bottom: 2px solid var(--text-2);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}
.select-wrap.is-loading::after {
  width: 14px; height: 14px;
  border: 2px solid var(--line-strong);
  border-top-color: var(--yellow);
  border-radius: 50%;
  transform: translateY(-50%) rotate(0);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: translateY(-50%) rotate(360deg); } }

.finder-submit { display: flex; align-items: flex-end; }
.finder-note {
  margin-top: 1.1rem;
  font-size: var(--fs-sm);
  color: var(--text-3);
  display: flex;
  align-items: center;
  gap: .5rem;
}
.finder-note svg { width: 16px; height: 16px; color: var(--yellow); flex: none; }

.finder-result { margin-top: 1.25rem; font-size: var(--fs-sm); }
.finder-result:empty { display: none; }
.finder-result .ok   { color: var(--ok); font-weight: 700; }
.finder-result .warn { color: var(--warn); font-weight: 700; }

/* Fired when a "find my bulbs" CTA sends the visitor here, so it is obvious
   what the page wants from them next. */
.finder.is-pulsing { animation: finder-pulse 1.1s var(--ease) 2; }
@keyframes finder-pulse {
  0%, 100% { border-color: var(--line-strong); box-shadow: var(--shadow-lg); }
  45%      { border-color: var(--yellow);      box-shadow: var(--shadow-lg), 0 0 0 6px var(--yellow-wash), var(--glow-yellow); }
}
@media (prefers-reduced-motion: reduce) {
  .finder.is-pulsing { animation: none; border-color: var(--yellow); }
}

/* ------------------------------------------------------------ trust strip */

.trust {
  border-block: 1px solid var(--line);
  background: var(--surface-1);
}
.trust ul {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}
.trust li {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: 1.75rem clamp(.75rem, 2vw, 1.5rem);
  border-inline-start: 1px solid var(--line);
}
.trust li:first-child { border-inline-start: 0; }
.trust svg { width: 26px; height: 26px; color: var(--yellow); flex: none; }
.trust b { display: block; font-size: var(--fs-sm); font-weight: 800; line-height: 1.25; }
.trust span { font-size: var(--fs-xs); color: var(--text-3); }

/* --------------------------------------------------------------- products */

.grid-products {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 268px), 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  overflow: hidden;
  transition: border-color .3s, transform .3s var(--ease), box-shadow .3s;
}
.card:hover {
  transform: translateY(-4px);
  border-color: rgba(254,245,24,.45);
  box-shadow: var(--shadow-md), var(--glow-yellow);
}
/* --------------------------------------------- one frame for every product

   The home page, the range, the related strip and the finder's results all
   draw their photograph through this one block, so a product looks the same
   wherever it is shown. Edge to edge: the photographs are shot on their own
   white sweep, so a dark card with 12% padding around them read as a small
   picture floating in a box rather than as a product. Filling the frame also
   makes a row of cards line up at the same visual weight, which `contain`
   never does with mixed crops. */
.pmedia {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  background: #FFFFFF;
  overflow: hidden;
}
.pmedia img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .5s var(--ease);
}
.card:hover .pmedia img,
.tile:hover .pmedia img,
.related:hover .pmedia img,
.fit-card:hover .pmedia img { transform: scale(1.07); }

@media (prefers-reduced-motion: reduce) {
  .pmedia img { transition: none; }
  .card:hover .pmedia img,
  .tile:hover .pmedia img,
  .related:hover .pmedia img,
  .fit-card:hover .pmedia img { transform: none; }
}

/* The lighting position, in its own colour.

   `z-index` is the whole reason this rule has one: on hover the photograph
   gets a transform, which puts it in the same painting layer as this
   absolutely positioned badge — and being later in the markup it painted over
   it, so the badge appeared to vanish under the mouse. Raising the badge one
   step keeps it where it was.

   The colour comes from --pos, set per position below. Everything else about
   the badge is identical across positions so a row of mixed cards still reads
   as one set. */
.ptag {
  position: absolute;
  top: .7rem; left: .7rem;
  z-index: 2;
  display: inline-flex; align-items: center; gap: .35rem;
  max-width: calc(100% - 1.4rem);
  padding: .3rem .6rem;
  border-radius: var(--r-pill);
  background: rgba(8,10,13,.82);
  border: 1px solid color-mix(in srgb, var(--pos, #9aa3ad) 55%, transparent);
  box-shadow: 0 2px 10px rgba(0,0,0,.45);
  backdrop-filter: blur(8px);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  color: var(--pos, var(--text-2));
}
.ptag .ico { width: 13px; height: 13px; flex: none; color: currentColor; }

/* Beam colours, chosen to read on the white sweep behind them and to stay
   distinguishable from each other rather than to be literal: the indicators
   are the amber they really are, the headlight pair splits cold blue (low)
   from the brand yellow (high). */
.ptag[data-pos="low_beam"]        { --pos: #5AA9FF; }
.ptag[data-pos="high_beam"]       { --pos: #FEF518; }
.ptag[data-pos="fog_light"]       { --pos: #34D399; }
.ptag[data-pos="drl"]             { --pos: #C084FC; }
.ptag[data-pos="parking_light"]   { --pos: #2DD4BF; }
.ptag[data-pos="reverse_light"]   { --pos: #E8EDF5; }
.ptag[data-pos="indicator_front"] { --pos: #FB923C; }
.ptag[data-pos="indicator_rear"]  { --pos: #F87171; }
.ptag[data-pos="interior"]        { --pos: #F472B6; }
.ptag[data-pos="license_plate"]   { --pos: #A5B4FC; }

.card-body { display: flex; flex-direction: column; gap: .85rem; padding: 1.25rem; flex: 1; }
.card-title { font-family: var(--font-display); font-size: 1.25rem; font-weight: 700; letter-spacing: -.01em; }
.card-sub { font-size: var(--fs-xs); color: var(--text-3); margin-top: -.5rem; }

.spec-row { display: flex; flex-wrap: wrap; gap: .4rem; }
.spec {
  padding: .3rem .55rem;
  border-radius: var(--r-sm);
  background: var(--surface-3);
  font-size: .75rem;
  font-weight: 600;
  color: var(--text-2);
}
.spec.is-key { color: var(--yellow); background: var(--yellow-wash); }

.card-foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: .75rem; }
.card-foot .btn { white-space: nowrap; padding: 0 1rem; min-height: 46px; }
.price { font-family: var(--font-display); font-size: 1.4rem; font-weight: 700; }
.price small { font-size: .8rem; color: var(--text-3); font-weight: 600; }

/* ----------------------------------------------------------- why / values */

.grid-why { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr)); gap: 1.25rem; }
.why {
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  transition: border-color .3s, background .3s;
}
.why:hover { border-color: var(--line-strong); background: var(--surface-2); }
.why-icon {
  display: grid; place-items: center;
  width: 52px; height: 52px;
  margin-bottom: 1.25rem;
  border-radius: var(--r-md);
  background: var(--yellow-wash);
  color: var(--yellow);
}
.why-icon svg { width: 26px; height: 26px; }
.why h3 { font-size: 1.2rem; margin-bottom: .6rem; }
.why p { font-size: var(--fs-sm); color: var(--text-2); }

/* -------------------------------------------------------------- split rows */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: clamp(2rem, 5vw, 5rem);
}
.split + .split { margin-top: var(--section); }
.split.is-flipped .split-media { order: -1; }
.split-media {
  border-radius: var(--r-2xl);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
}
.split-media img { width: 100%; }
.split-copy h2 { font-size: var(--fs-h2); margin: 1rem 0 1.1rem; }
.split-copy p { color: var(--text-2); font-size: var(--fs-lead); }
.split-list { margin-top: 1.75rem; display: grid; gap: .85rem; }
.split-list li { display: flex; gap: .75rem; align-items: flex-start; font-size: var(--fs-sm); color: var(--text-2); }
.split-list svg { width: 18px; height: 18px; color: var(--yellow); flex: none; margin-top: .22rem; }

/* ---------------------------------------------------------- before/after */

.compare {
  position: relative;
  border-radius: var(--r-2xl);
  overflow: hidden;
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-lg);
  aspect-ratio: 3 / 2;
  cursor: ew-resize;
  user-select: none;
  touch-action: pan-y;
}
.compare img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* The "after" layer is clipped by a CSS variable the drag handler updates. */
.compare .after { clip-path: inset(0 0 0 var(--split, 50%)); }
.compare-handle {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--split, 50%);
  width: 2px;
  background: var(--yellow);
  box-shadow: 0 0 22px rgba(254,245,24,.75);
  pointer-events: none;
}
.compare-handle::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 52px; height: 52px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--yellow);
  box-shadow: 0 6px 26px rgba(0,0,0,.6);
}
.compare-label {
  position: absolute;
  top: 1.1rem;
  padding: .4rem .85rem;
  border-radius: var(--r-pill);
  background: rgba(8,10,13,.78);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line-strong);
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.compare-label.left  { left: 1.1rem; color: var(--text-2); }
.compare-label.right { right: 1.1rem; color: var(--yellow); }

/* ------------------------------------------------------------------ steps */

.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: 1.25rem; counter-reset: step; }
.step {
  position: relative;
  padding: 2.25rem 1.5rem 1.75rem;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
}
.step::before {
  counter-increment: step;
  content: '0' counter(step);
  position: absolute;
  top: 1.1rem; right: 1.25rem;
  font-family: var(--font-display);
  font-size: 2.6rem;
  font-weight: 800;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--line-strong);
}
.step h3 { font-size: 1.05rem; margin-bottom: .5rem; }
.step p { font-size: var(--fs-sm); color: var(--text-2); }

/* ------------------------------------------------------------------- CANBUS */

.tech {
  position: relative;
  border-radius: var(--r-2xl);
  overflow: hidden;
  border: 1px solid var(--line);
  background:
    radial-gradient(ellipse at 78% 50%, var(--blue-wash), transparent 62%),
    var(--surface-1);
}
.tech-inner { display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: clamp(2rem, 4vw, 4rem); padding: clamp(2rem, 5vw, 4.5rem); }
.tech-inner img { border-radius: var(--r-lg); }
.tech-title { font-size: var(--fs-h2); margin: 1rem 0 1.1rem; }

/* --------------------------------------------------------------------- FAQ */

/* The accordion used to be a centred 860px column inside a full-width
   section, which gave the page a fourth left edge. It now shares the section
   with its heading: heading on the left, questions filling the rest, both
   landing exactly on the container. */
.faq { max-width: 860px; margin-inline: auto; }

@media (min-width: 900px) {
  .faq-layout {
    display: grid;
    grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
    gap: clamp(2.5rem, 6vw, 6rem);
    align-items: start;
  }
  .faq-layout .section-head { margin-bottom: 0; position: sticky; top: 7rem; }
  .faq-layout .faq { max-width: none; margin-inline: 0; }
}
.faq details {
  border-bottom: 1px solid var(--line);
}
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.5rem 0;
  font-family: var(--font-display);
  font-size: clamp(1rem, 1.7vw, 1.2rem);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  transition: color .2s;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--yellow); }
.faq summary::after {
  content: '';
  flex: none;
  width: 13px; height: 13px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-3px);
  transition: transform .3s var(--ease);
}
.faq details[open] summary { color: var(--yellow); }
.faq details[open] summary::after { transform: rotate(225deg) translateY(-3px); }
.faq-body { padding-bottom: 1.6rem; color: var(--text-2); font-size: var(--fs-sm); max-width: 68ch; }

/* ------------------------------------------------------------------ CTA band */

.cta-band {
  position: relative;
  border-radius: var(--r-2xl);
  padding: clamp(2.5rem, 6vw, 5rem);
  background:
    radial-gradient(ellipse at 15% 20%, rgba(254,245,24,.13), transparent 58%),
    linear-gradient(140deg, var(--surface-2), var(--surface-1));
  border: 1px solid var(--line-strong);
  overflow: hidden;
}
.cta-title { font-size: var(--fs-h2); margin: 1rem 0 1rem; max-width: 18ch; }
.cta-lead { max-width: 52ch; }
.cta-actions { display: flex; flex-wrap: wrap; gap: .85rem; margin-top: 2rem; }

/* ------------------------------------------------------------- B2B enquiry */

/* One form in two settings: folded under the buy button on a product page, and
   standing on its own as a band on the home page. Everything shared lives here
   once; only the surroundings differ below. */

.b2b-form { display: grid; gap: .55rem; }
.b2b-row { display: flex; flex-wrap: wrap; gap: .5rem; }
.b2b-input {
  flex: 1 1 14rem; min-width: 0; min-height: 46px; padding: 0 .9rem;
  background: var(--surface-1); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); color: var(--text);
}
.b2b-input::placeholder { color: var(--text-3); }
.b2b-input:focus-visible { border-color: var(--yellow); outline: none; }
.b2b-form .btn { min-height: 46px; flex: none; }
.b2b-note { display: flex; gap: .5rem; font-size: var(--fs-xs); color: var(--text-3); }
.b2b-note .ico { width: 14px; height: 14px; margin-top: .15rem; flex: none; }
.b2b-msg { font-size: var(--fs-sm); color: #7BD88F; }
.b2b-msg.is-bad { color: #E8705F; }
/* Sent: there is nothing left to type, and a filled-in field beside a thank-you
   reads as "did that go?" and invites a second press. Hidden, not removed, so
   a later failure can bring the field straight back. */
.b2b-form.is-done .b2b-row,
.b2b-form.is-done .b2b-note { display: none; }

/* --- folded into the product page */

.b2b-inline { margin-top: .4rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.b2b-toggle {
  display: flex; align-items: center; gap: .55rem;
  font-size: var(--fs-sm); font-weight: 600; color: var(--text-2);
  cursor: pointer; list-style: none; transition: color .2s;
}
.b2b-toggle::-webkit-details-marker { display: none; }
.b2b-toggle:hover { color: var(--yellow); }
.b2b-toggle .ico { width: 16px; height: 16px; flex: none; }
.b2b-toggle .ico:first-child { color: var(--yellow); }
.b2b-toggle .ico:last-child { margin-left: auto; transition: transform .3s var(--ease); }
.b2b-inline[open] .b2b-toggle { color: var(--yellow); }
.b2b-inline[open] .b2b-toggle .ico:last-child { transform: rotate(180deg); }
.b2b-lead { margin: .8rem 0 .7rem; font-size: var(--fs-xs); color: var(--text-2); }

/* --- the band on the home page */

.b2b-band {
  display: grid; gap: 1.4rem; align-items: center;
  /* minmax(0,1fr), not the implicit auto track: the eyebrow is a whole question
     here rather than the two or three words it is in a section head, and an
     auto track sized to a nowrap string that long pushes the whole column wider
     than the card on a phone. */
  grid-template-columns: minmax(0, 1fr);
  padding: clamp(1.8rem, 4vw, 3rem);
  border: 1px solid var(--line-strong); border-radius: var(--r-2xl);
  background: linear-gradient(140deg, var(--surface-2), var(--surface-1));
}
/* Same reason: let this one wrap. German asks it in five words. */
.b2b-band .eyebrow { white-space: normal; }
@media (min-width: 860px) {
  .b2b-band { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 4rem); }
}
.b2b-band h2 { font-size: clamp(1.4rem, 2.8vw, 2rem); margin: .7rem 0 .6rem; max-width: 20ch; }
.b2b-band .b2b-head p { font-size: var(--fs-sm); color: var(--text-2); max-width: 46ch; }

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

.footer { border-top: 1px solid var(--line); background: var(--surface-1); padding-block: clamp(3rem, 6vw, 5rem) 2rem; }
.footer-grid { display: grid; grid-template-columns: 1.6fr repeat(3, 1fr); gap: clamp(2rem, 4vw, 3.5rem); }
.footer-brand img { height: 44px; width: auto; margin-bottom: 1.1rem; }
.footer-brand p { font-size: var(--fs-sm); color: var(--text-3); max-width: 34ch; }
.footer h4 {
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text);
  margin-bottom: 1.1rem;
}
.footer li + li { margin-top: .65rem; }
.footer ul a {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-size: var(--fs-sm);
  color: var(--text-2);
  transition: color .2s;
}
.footer ul a .ico { width: 16px; height: 16px; color: var(--text-3); transition: color .2s, transform .2s var(--ease); }
.footer ul a:hover { color: var(--yellow); }
.footer ul a:hover .ico { color: var(--yellow); transform: translateX(2px); }
.footer-bottom {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  font-size: var(--fs-xs);
  color: var(--text-3);
}
.footer-credit {
  margin-top: .9rem;
  font-size: var(--fs-xs);
  color: var(--text-3);
}
.footer-credit a {
  color: var(--text-2);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color .2s;
}
.footer-credit a:hover { color: var(--yellow); }

/* ------------------------------------------------------------ scroll reveal */

.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}

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

@media (max-width: 1080px) {
  .trust ul { grid-template-columns: repeat(3, 1fr); }
  .trust li:nth-child(3n+1) { border-inline-start: 0; }
  .trust li:nth-child(n+4) { border-top: 1px solid var(--line); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 1100px) {
  .nav, .header-actions .btn { display: none; }
  .burger { display: grid; }
  .header-actions { margin-inline-start: auto; }
}

@media (max-width: 900px) {
  .finder-row { grid-template-columns: 1fr 1fr; }
  .finder-submit { grid-column: 1 / -1; }
  .split, .tech-inner { grid-template-columns: 1fr; }
  .split.is-flipped .split-media { order: 0; }
}

@media (max-width: 620px) {
  .header-inner { min-height: 72px; }
  /* Search has no destination yet on small screens and the row is tight. */
  .header-actions > .icon-btn:not(.burger):first-of-type { display: none; }
  .lang > summary { padding: 0 .4rem; }
  .lang-code { display: none; }
  .hero { min-height: auto; padding-bottom: 2.5rem; padding-top: 3rem; }
  .hero-copy { max-width: none; }
  /* The copy spans the full width here, so a side scrim only hides the
     product. Legibility comes from the vertical pass alone. */
  .hero-media img { object-position: 50% 42%; }
  .hero-media::after {
    background: linear-gradient(180deg, rgba(8,10,13,.62) 0%, rgba(8,10,13,.84) 38%, rgba(8,10,13,.96) 78%);
  }
  .finder-row { grid-template-columns: 1fr; }
  .trust ul { grid-template-columns: repeat(2, 1fr); }
  .trust li { border-inline-start: 0; border-top: 1px solid var(--line); padding: 1.35rem 1rem; }
  .trust li:nth-child(-n+2) { border-top: 0; }
  .grid-products { grid-template-columns: 1fr 1fr; gap: .75rem; }
  .card-body { padding: .9rem; gap: .6rem; }
  .card-title { font-size: 1.05rem; }
  .price { font-size: 1.15rem; }
  .card-foot { flex-direction: column; align-items: stretch; }
  /* Two cards per row leaves ~170px; longer locales need the label to breathe. */
  .card-foot .btn { padding: .6rem .7rem; font-size: .8125rem; line-height: 1.2; text-align: center; }
  .compare { aspect-ratio: 4 / 3; }
  .footer-grid { grid-template-columns: 1fr; }
}

/* Mobile nav sheet */
.mobile-nav {
  position: fixed;
  inset: var(--announce-h, 0px) 0 0 0;
  z-index: 200;
  background: rgba(8,10,13,.98);
  backdrop-filter: blur(20px);
  padding: 1.25rem 0 max(2rem, env(safe-area-inset-bottom));
  display: none;
  flex-direction: column;
  gap: 1.25rem;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.mobile-nav.is-open { display: flex; }
.mobile-nav-head { display: flex; align-items: center; justify-content: space-between; min-height: 64px; }
.mobile-nav-head img { height: 40px; width: auto; }
.mobile-nav-links a {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: 1.05rem 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 600;
}
.mobile-nav-links a .ico { width: 20px; height: 20px; color: var(--yellow); }
.mobile-nav-foot { margin-top: auto; padding-top: 1.5rem; }
.mobile-nav-foot .btn { width: 100%; }
.mobile-nav-foot .lang-row { justify-content: center; }

/* ------------------------------------------------------------- back to top */

.to-top {
  position: fixed;
  right: var(--edge);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 150;
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: rgba(16,19,24,.9);
  backdrop-filter: blur(12px);
  color: var(--text-2);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: opacity .3s, transform .3s var(--ease), visibility .3s, border-color .2s, color .2s;
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { border-color: var(--yellow); color: var(--yellow); }
.to-top .ico { width: 20px; height: 20px; }

/* The finder button must never wrap its label onto a second line. */
.finder-submit .btn { white-space: nowrap; }
/* ------------------------------------------------------------------ consent
 *
 * A module that floats above the page rather than a strip welded to the
 * bottom of the window. It reads as a piece of hardware resting on the dark:
 * machined edge, deep shadow, and a single filament of SunX yellow along the
 * top — the one place this component is allowed to be loud, and the one that
 * is literally the product.
 *
 * It only exists once the head stub has decided there is no stored choice.
 * With JavaScript off it never appears, which is correct: with JavaScript off
 * nothing here can write non-essential storage either.
 *
 * Accept and Reject share one class and one set of rules. No variant, no
 * override, no extra weight on the one we would prefer you clicked. The only
 * difference between those two buttons is the text inside them.
 */

[hidden] { display: none !important; }

/*
 * LAYER ORDER. One ladder for the whole site, declared in one place, because
 * the failure it fixes was invisible in any single rule: the cart drawer and
 * the consent bar both sat at 300, so DOM order decided, and the drawer — last
 * in the body — painted over the "Reject non-essential" button. Consent cannot
 * be a matter of who happens to be written last.
 *
 *    100  header          260  announce bar
 *    150  back to top     290  drawer scrim
 *    200  mobile nav      300  cart drawer, search overlay
 *   1000  consent bar     — above everything, unconditionally
 *
 * The preferences dialog is a modal <dialog>: the top layer puts it above all
 * of this without a number.
 */

.cbar { display: none; }
html[data-consent="pending"] .cbar {
  display: block;
  position: fixed;
  inset: auto 0 0 0;
  z-index: 1000;
  /* Same gutter as every .shell on the page, so the card's edge is the
     container's edge and not a fourth one. */
  padding: 0 var(--edge) calc(var(--gutter) + env(safe-area-inset-bottom));
  /* The frame is only a positioning device; the page behind its margins stays
     clickable. */
  pointer-events: none;
}

.cbar-inner {
  pointer-events: auto;
  position: relative;
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.15rem clamp(1.25rem, 2.4vw, 2.25rem);
  padding: clamp(1.1rem, 2.2vw, 1.6rem) clamp(1.15rem, 2.4vw, 2rem);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-2xl);
  background: linear-gradient(180deg, rgba(23, 27, 33, .96), rgba(13, 16, 20, .96));
  backdrop-filter: blur(20px) saturate(140%);
  /* Two shadows and one inset hairline: the drop separates it from the page,
     the glow gives it a little warmth, the inset catches light on the edge. */
  box-shadow:
    0 32px 70px -24px rgba(0, 0, 0, .9),
    0 2px 10px -4px rgba(0, 0, 0, .7),
    inset 0 1px 0 rgba(255, 255, 255, .07);
  animation: cbar-rise .42s var(--ease) both;
}

/* The filament: a lit strip along the top edge, brightest above the mark and
   spent by the halfway point. One accent, and it is the product itself. */
.cbar-inner::before {
  content: '';
  position: absolute;
  inset: -1px auto auto 5%;
  width: 52%;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg,
    rgba(254, 245, 24, 0) 0%,
    rgba(254, 245, 24, .95) 20%,
    rgba(254, 245, 24, .45) 58%,
    rgba(254, 245, 24, 0) 100%);
  box-shadow: 0 0 12px rgba(254, 245, 24, .32);
}

@keyframes cbar-rise {
  from { opacity: 0; transform: translateY(1.5rem); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .cbar-inner { animation: none; }
}

/* Basis kept small enough that the copy and the actions still share a row at
   desktop widths; the copy grows into whatever is left over. */
.cbar-copy { flex: 1 1 22rem; min-width: 0; }

.cbar-copy h2 {
  display: flex;
  align-items: center;
  gap: .7rem;
  margin: 0 0 .45rem;
  font-family: var(--font-body);
  font-size: 1.125rem;
  font-weight: 800;
  letter-spacing: -.015em;
  color: var(--text);
}

/* The icon gets its own lit disc — the only filled shape in the bar. */
.cbar-mark {
  display: grid;
  place-items: center;
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 38%, rgba(254, 245, 24, .3), rgba(254, 245, 24, .05) 72%);
  box-shadow: inset 0 0 0 1px rgba(254, 245, 24, .3), 0 0 24px -9px rgba(254, 245, 24, .95);
  color: var(--yellow);
}
.cbar-mark .ico { width: 17px; height: 17px; }

/* --text-2, not --text-3: the paler grey measures under 4.5:1 on this
   surface, and legal copy is the last place to spend contrast. */
.cbar-copy p {
  margin: 0;
  max-width: 62ch;
  font-size: .9rem;
  line-height: 1.65;
  color: var(--text-2);
}
.cbar-copy a { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.cbar-copy a:hover { color: var(--yellow); }

.cbar-gpc {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  margin-top: .75rem !important;
  padding: .6rem .8rem;
  border: 1px solid rgba(0, 144, 255, .3);
  border-radius: var(--r-md);
  background: var(--blue-wash);
  color: var(--text-2);
  font-size: .8125rem;
  line-height: 1.55;
}
.cbar-gpc .ico { color: var(--blue); margin-top: .2rem; flex: none; }

/* Two equal tracks plus one that sizes to its text. Equal `fr` tracks in an
   auto-width grid both resolve to the wider label, so Accept and Reject come
   out exactly the same size in every language without a magic number. */
.cbar-actions {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  align-items: center;
  gap: .6rem;
  flex: 0 1 auto;
}

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

/* Both decision buttons. Equal weight by construction, not by eye. */
.cbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 52px;
  min-width: 10.5rem;
  padding: 0 1.5rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, rgba(46, 52, 62, .9), rgba(30, 35, 43, .9));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
  color: var(--text);
  font: inherit;
  font-size: .9375rem;
  font-weight: 700;
  letter-spacing: -.005em;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color .2s, color .2s, transform .2s var(--ease), box-shadow .2s;
}
.cbtn:hover {
  border-color: var(--yellow);
  color: var(--yellow);
  transform: translateY(-2px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 10px 24px -14px rgba(254, 245, 24, .8);
}

/* On the first layer both decisions are brand yellow. They are yellow
   *together*: the moment only one of them is, the styling starts making the
   choice for the visitor, which is the asymmetry regulators fine. Inside the
   dialog they stay neutral, because there the primary action is Save. */
.cbar .cbtn {
  background: var(--yellow);
  border-color: var(--yellow);
  color: #0A0A0A;
  box-shadow: none;
}
.cbar .cbtn:hover {
  background: #FFF95C;
  border-color: #FFF95C;
  color: #0A0A0A;
  box-shadow: var(--glow-yellow);
}
.cbtn:active { transform: translateY(0); }
.cbtn .ico { width: 17px; height: 17px; }
@media (prefers-reduced-motion: reduce) {
  .cbtn, .cbtn:hover { transform: none; transition: border-color .2s, color .2s; }
}

/* Save confirms whatever the switches already say, and competes with nothing
   on the first layer — it only exists inside a dialog you chose to open. */
.cbtn-save {
  background: var(--yellow);
  border-color: var(--yellow);
  color: #000;
  box-shadow: none;
}
.cbtn-save:hover {
  background: #FFF95C;
  border-color: #FFF95C;
  color: #000;
  box-shadow: var(--glow-yellow);
}

.clink {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  min-height: 52px;
  padding: 0 .85rem;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  color: var(--text-2);
  font: inherit;
  font-size: .9375rem;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  white-space: nowrap;
  cursor: pointer;
  transition: color .2s;
}
.clink:hover { color: var(--yellow); }
.clink .ico { width: 16px; height: 16px; }

/* ----------------------------------------------------------------- dialog */

.cdlg {
  position: fixed;
  inset: 0;
  /* Centred explicitly: the UA's margin:auto only centres vertically when the
     height is definite, and this dialog is content-sized. */
  margin: auto;
  width: min(660px, calc(100vw - 2rem));
  height: fit-content;
  max-height: min(84vh, 860px);
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-2xl);
  background: var(--surface-1);
  color: var(--text);
  box-shadow: 0 40px 100px -30px rgba(0, 0, 0, .95), inset 0 1px 0 rgba(255, 255, 255, .06);
  overflow: hidden;
}
.cdlg[open] { display: flex; flex-direction: column; }
.cdlg::backdrop { background: rgba(8, 10, 13, .8); backdrop-filter: blur(6px); }

.cdlg-grip { display: none; }

.cdlg-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.25rem clamp(1.15rem, 3vw, 1.75rem) 1.1rem;
  border-bottom: 1px solid var(--line);
}
.cdlg-head h2 {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.1875rem;
  font-weight: 800;
  letter-spacing: -.02em;
}

.cdlg-intro,
.cdlg .cbar-gpc {
  margin: 1.1rem clamp(1.15rem, 3vw, 1.75rem) 0;
  font-size: .875rem;
  line-height: 1.65;
  color: var(--text-2);
}

.cdlg-body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 1.1rem clamp(1.15rem, 3vw, 1.75rem) 1.35rem;
}

/* One panel with hairline rules, not four identical cards stacked. The rules
   say "these are four rows of the same list"; four cards would say "these are
   four unrelated things". */
.ccats {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  overflow: hidden;
}
.ccat { padding: 1.05rem clamp(.9rem, 2.4vw, 1.15rem); }
.ccat + .ccat { border-top: 1px solid var(--line); }

.ccat-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1.25rem; }
.ccat-text h3 {
  margin: 0 0 .3rem;
  font-family: var(--font-body);
  font-size: .9375rem;
  font-weight: 800;
  letter-spacing: -.01em;
}
.ccat-text p { margin: 0; font-size: .8125rem; line-height: 1.6; color: var(--text-2); }
.ccat-control { flex: none; padding-top: .1rem; }

.ccat-locked {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .32rem .7rem;
  border-radius: var(--r-pill);
  background: var(--surface-3);
  box-shadow: inset 0 0 0 1px var(--line-strong);
  color: var(--text-2);
  font-size: .75rem;
  font-weight: 700;
  white-space: nowrap;
}
.ccat-locked .ico { width: 14px; height: 14px; }

/* A real checkbox, visually restyled — so it keeps its role, its label and
   its keyboard behaviour instead of a div pretending to be a switch. */
.cswitch { display: inline-flex; align-items: center; cursor: pointer; }
.cswitch input,
.cswitch-label {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
}
.cswitch-ui {
  display: block;
  position: relative;
  width: 50px; height: 28px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--bg);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .6);
  transition: background .22s, border-color .22s;
}
.cswitch-ui::after {
  content: '';
  position: absolute;
  top: 3px; left: 3px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--text-2);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .6);
  transition: transform .22s var(--ease), background .22s;
}
.cswitch input:checked + .cswitch-ui {
  background: var(--yellow);
  border-color: var(--yellow);
  box-shadow: 0 0 20px -6px rgba(254, 245, 24, .7);
}
.cswitch input:checked + .cswitch-ui::after { transform: translateX(22px); background: #0A0A0A; }
.cswitch input:focus-visible + .cswitch-ui { outline: 2px solid var(--yellow); outline-offset: 3px; }
.cswitch:hover .cswitch-ui { border-color: var(--yellow); }
@media (prefers-reduced-motion: reduce) {
  .cswitch-ui, .cswitch-ui::after { transition: none; }
}

.ccat-details { margin-top: .85rem; border-top: 1px solid var(--line); padding-top: .7rem; }
/* The default marker is dropped for a chevron that turns, so the row still
   announces itself as something that opens. Without one this reads as a
   caption and nobody finds the cookie table. */
.ccat-details summary {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  cursor: pointer;
  font-size: .8125rem;
  font-weight: 700;
  color: var(--text-2);
  transition: color .2s;
  list-style: none;
}
.ccat-details summary::-webkit-details-marker { display: none; }
.ccat-details summary::after {
  content: '';
  width: 6px; height: 6px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  border-radius: 1px;
  transform: translateY(-2px) rotate(45deg);
  transition: transform .22s var(--ease);
}
.ccat-details[open] summary::after { transform: translateY(1px) rotate(-135deg); }
.ccat-details summary:hover { color: var(--yellow); }
@media (prefers-reduced-motion: reduce) {
  .ccat-details summary::after { transition: none; }
}
.ccat-empty { margin: .65rem 0 0; font-size: .8125rem; color: var(--text-2); }

.ctable-wrap {
  overflow-x: auto;
  margin-top: .7rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.ctable { width: 100%; min-width: 32rem; border-collapse: collapse; font-size: .75rem; }
.ctable th, .ctable td { padding: .55rem .65rem; text-align: left; vertical-align: top; }
.ctable thead th { background: var(--surface-3); color: var(--text); font-weight: 700; white-space: nowrap; }
.ctable tbody tr + tr td { border-top: 1px solid var(--line); }
.ctable td { color: var(--text-2); }
.ctable code { color: var(--text); font-size: .75rem; }
.ctable tr.is-inactive td { opacity: .62; }
.ctag {
  display: inline-block;
  padding: .06rem .4rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  font-size: .625rem;
  letter-spacing: .02em;
}

.cdlg-foot {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  padding: 1.1rem clamp(1.15rem, 3vw, 1.75rem) calc(1.1rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  background: var(--surface-1);
}
.cdlg-foot .cbtn { flex: 1 1 10rem; min-width: 0; }

/* Placeholder standing in for a third-party embed until its category is
   allowed. Nothing uses it yet; it ships so the first embed has somewhere
   correct to go. */
.cembed {
  display: grid;
  place-items: center;
  gap: .75rem;
  min-height: 12rem;
  padding: 1.5rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  color: var(--text-2);
  text-align: center;
  font-size: .875rem;
}
.cembed.is-loaded { display: block; min-height: 0; padding: 0; border: 0; background: none; }
.cembed.is-loaded > .cembed-note { display: none; }

.footer-consent {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-2);
  font: inherit;
  font-size: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: color .2s;
}
.footer-consent:hover { color: var(--yellow); }
.footer-consent .ico { width: 16px; height: 16px; }

/* The module owns the bottom of the screen while it is up. */
html[data-consent="pending"] .to-top { bottom: clamp(13rem, 32vh, 17rem); }

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

/* Copy and actions stop fitting on one line: actions move under the copy and
   keep the two decisions side by side. */
@media (max-width: 1079px) {
  .cbar-copy { flex: 1 1 100%; }
  .cbar-actions { display: flex; flex-wrap: wrap; width: 100%; justify-content: flex-start; }
  .cbtn { flex: 1 1 14rem; min-width: 0; }
  .clink { margin-left: auto; }
}

/* Tablet and large phones: the two decisions share a row, Manage sits under
   them across the full width so it never looks like a third option. */
@media (max-width: 759px) {
  .cbar-actions { gap: .55rem; }
  .cbtn { flex: 1 1 calc(50% - .3rem); min-width: 0; padding: 0 1rem; }
  .clink { flex: 1 1 100%; margin-left: 0; justify-content: center; min-height: 44px; }
}

/* Phones: one column, full-width targets, and the dialog becomes a sheet that
   rises from the bottom edge. */
@media (max-width: 619px) {
  .cbar-inner {
    max-height: 76vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    border-radius: 26px;
    padding: 1.15rem 1.1rem 1.25rem;
    gap: 1rem;
  }
  .cbar-copy h2 { font-size: 1rem; }
  .cbar-copy p { font-size: .8438rem; }
  .cbtn { flex: 1 1 100%; }
  html[data-consent="pending"] .to-top { display: none; }

  .cdlg {
    inset: auto 0 0 0;
    margin: 0;
    width: 100%;
    max-width: 100%;
    height: auto;
    max-height: 92dvh;
    border-width: 1px 0 0;
    border-radius: 26px 26px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
    animation: cdlg-sheet .32s var(--ease) both;
  }
  @keyframes cdlg-sheet { from { transform: translateY(100%); } to { transform: none; } }
  .cdlg-grip {
    display: block;
    width: 38px; height: 4px;
    margin: .6rem auto -.2rem;
    border-radius: var(--r-pill);
    background: var(--line-strong);
  }
  .cdlg-head { padding-top: .9rem; }
  .ccat-head { flex-direction: column; gap: .7rem; }
  .cdlg-foot .cbtn { flex: 1 1 100%; }

  /* A five-column table on a phone is a sideways scroll nobody performs.
     Each row becomes a labelled stack instead. */
  .ctable-wrap { overflow-x: visible; border: 0; border-radius: 0; }
  .ctable { min-width: 0; }
  .ctable thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .ctable tr {
    display: block;
    margin-top: .6rem;
    padding: .7rem .8rem;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--surface-1);
  }
  .ctable tbody tr + tr td { border-top: 0; }
  .ctable td { display: flex; gap: .75rem; padding: .22rem 0; }
  .ctable td::before {
    content: attr(data-th);
    flex: none;
    width: 5.5rem;
    color: var(--text);
    font-weight: 700;
  }
}

/* Reject and Accept share the sheet's first row; Save takes the one below, so
   the footer costs two rows instead of three. */
@media (min-width: 400px) and (max-width: 619px) {
  .cdlg-foot .cbtn { flex: 1 1 calc(50% - .3rem); }
  .cdlg-foot .cbtn-save { flex: 1 1 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .cdlg { animation: none; }
}

/* Smallest phones still in use: trim the padding, not the tap targets. */
@media (max-width: 379px) {
  .cbar-inner { padding: 1rem .9rem 1.1rem; border-radius: 22px; }
  .cbar-copy h2 { gap: .55rem; font-size: .9375rem; }
  .cbar-mark { width: 30px; height: 30px; }
  .cbar-copy p { font-size: .8125rem; line-height: 1.6; }
  .cbtn { font-size: .9rem; padding: 0 .85rem; }
}

/* Below 360px the hero headline is wide enough to overflow its own box —
   "CONFIDENCE." at 36.8px does not fit 280px of content width. Scoped to the
   widths that actually break so 360 and up keep the size they were designed at. */
@media (max-width: 359px) {
  .hero h1 { font-size: clamp(1.9rem, 9.6vw, 2.3rem); }
}

/* ---------------------------------------------------------------- contact */

/* Three cards: how to reach us, what to send when you ask about a car, and
   the statutory identification. The last one is the imprint — it has to be
   readable, so it gets --text-2 rather than the --text-3 that the earlier
   audit measured at 3.9:1 against this surface. */

.contact-grid {
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem);
  grid-template-columns: 1fr;
}
@media (min-width: 760px)  { .contact-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .contact-grid { grid-template-columns: repeat(3, 1fr); } }

.contact-card {
  display: flex;
  flex-direction: column;
  gap: .85rem;
  padding: clamp(1.4rem, 2.6vw, 2rem);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  color: var(--text-2);
  transition: border-color .3s, transform .3s var(--ease);
}
.contact-card:hover { border-color: var(--line-strong); transform: translateY(-3px); }
.contact-card h3 {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-size: 1.15rem;
  color: var(--text);
}
.contact-card h3 .ico { color: var(--yellow); }
.contact-card .contact-sub { margin-top: .6rem; scroll-margin-top: calc(var(--announce-h, 0px) + 110px); }
.contact-card .btn { align-self: flex-start; }

.contact-mails { display: grid; gap: .55rem; }
.contact-mail {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .75rem .9rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-1);
  transition: border-color .2s, background .2s;
}
.contact-mail:hover { border-color: var(--yellow); background: var(--surface-3); }
.contact-mail .ico { color: var(--yellow); }
.contact-mail span { display: grid; min-width: 0; }
.contact-mail strong {
  font-size: var(--fs-sm);
  color: var(--text);
  overflow-wrap: anywhere;
}
.contact-mail small { font-size: var(--fs-xs); color: var(--text-2); }

.contact-dl { display: grid; gap: .1rem; }
.contact-dl > div {
  display: grid;
  grid-template-columns: 1fr;
  gap: .1rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--line);
}
.contact-dl > div:last-child { border-bottom: 0; }
.contact-dl dt {
  font-size: var(--fs-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-2);
}
.contact-dl dd { color: var(--text); overflow-wrap: anywhere; }
@media (min-width: 460px) and (max-width: 759px) {
  .contact-dl > div { grid-template-columns: 13rem 1fr; align-items: baseline; gap: 1rem; }
}

.contact-note {
  display: flex;
  gap: .5rem;
  font-size: var(--fs-xs);
  color: var(--text-2);
}
.contact-note .ico { width: 14px; height: 14px; margin-top: .22rem; color: var(--text-2); }

/* The anchors the footer links land on sit inside a card, so they need the
   sticky chrome cleared or the heading lands underneath the header. */
#contact, #delivery, #warranty {
  scroll-margin-top: calc(var(--announce-h, 0px) + 100px);
}

/* ------------------------------------------------- listing and products */

.section-top { padding-top: clamp(1.5rem, 3vw, 2.5rem); }

.crumbs { margin-bottom: clamp(1.25rem, 3vw, 2rem); font-size: var(--fs-xs); color: var(--text-2); }
.crumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; list-style: none; padding: 0; }
.crumbs li + li::before { content: '/'; margin-inline-end: .4rem; color: var(--text-3); }
.crumbs a:hover { color: var(--yellow); }
/* 18px of text is 18px of target, and WCAG 2.2 §2.5.8 wants 24. The standard
   exempts a link sitting inside a sentence, where the line height and not the
   author decides its size — but a breadcrumb is not a sentence: the "/" between
   these is a ::before on the <li>, so each link stands alone in its own box.
   Padding grows the box a thumb can hit; the matching negative margin takes the
   growth back out of the layout, so nothing on the page moves. */
.crumbs a { padding-block: .3rem; margin-block: -.3rem; }

.listing-head { max-width: 70ch; }

.listing-tools {
  display: grid;
  gap: 1.1rem;
  padding: clamp(1rem, 2vw, 1.5rem);
  margin-bottom: 1.25rem;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
}
.filter-group { display: grid; gap: .6rem; }
.filter-label {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-2);
}
.filter-label .ico { width: 15px; height: 15px; color: var(--yellow); }
.chips { display: flex; flex-wrap: wrap; gap: .45rem; }
.chip {
  display: inline-flex; align-items: center; gap: .4rem;
  min-height: 40px; padding: 0 .95rem;
  border: 1px solid var(--line-strong); border-radius: 999px;
  background: transparent; color: var(--text-2);
  font-size: var(--fs-sm); font-weight: 600; cursor: pointer;
  transition: border-color .2s, color .2s, background .2s;
}
.chip:hover { border-color: var(--yellow); color: var(--text); }
.chip[aria-pressed="true"] {
  background: var(--yellow); border-color: var(--yellow);
  color: #0B0B06; font-weight: 800;
}
.chip-n { font-size: var(--fs-xs); opacity: .7; }
.filter-sort { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.filter-sort label {
  font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-2);
}
.listing-count { margin-bottom: 1.25rem; font-size: var(--fs-sm); color: var(--text-2); }

.tiles {
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem);
  /* Wider tiles, fewer per row: the photograph is what people shop by, and a
     260px tile reduced a 1600px product shot to a thumbnail. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr));
}
.tile {
  display: flex; flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  overflow: hidden;
  transition: border-color .3s, transform .3s var(--ease), box-shadow .3s;
}
.tile:hover { border-color: var(--line-strong); transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.tile[hidden] { display: none; }
.tile-body { display: flex; flex-direction: column; gap: .5rem; padding: 1.1rem; flex: 1; }
.tile-title { font-size: 1.05rem; line-height: 1.2; }
/* Same 24px floor as the breadcrumbs, same trick: hit area out, layout unchanged. */
.tile-title a { padding-block: .25rem; margin-block: -.25rem; }
.tile-title a:hover { color: var(--yellow); }
.tile-sub { font-size: var(--fs-xs); color: var(--text-2); }
.tile-specs { display: flex; flex-wrap: wrap; gap: .35rem; }
.tile-specs li {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .25rem .55rem; border: 1px solid var(--line); border-radius: 6px;
  font-size: var(--fs-xs); color: var(--text-2);
}
.tile-specs .ico { width: 13px; height: 13px; color: var(--text-3); }
.tile-specs .is-key { border-color: rgba(254,245,24,.35); color: var(--yellow); }
.tile-specs .is-key .ico { color: var(--yellow); }
.tile-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; margin-top: auto; padding-top: .75rem;
}
.tile-foot .btn { min-height: 44px; padding: 0 1rem; font-size: var(--fs-xs); }

.listing-empty { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; padding: 2.5rem 0; color: var(--text-2); }
.linklike {
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--yellow); font-weight: 700; text-decoration: underline;
  text-underline-offset: 3px;
  display: inline-flex; align-items: center; gap: .4rem;
}
.listing-finder {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 1rem; margin-top: clamp(2rem, 4vw, 3rem);
  padding: clamp(1.2rem, 2.5vw, 1.8rem);
  background: var(--surface-1); border: 1px solid var(--line); border-radius: var(--r-xl);
}
.listing-finder p { display: flex; align-items: center; gap: .6rem; color: var(--text-2); }
.listing-finder .ico { color: var(--yellow); }

/* -------------------------------------------------------- product page */

.product { display: grid; gap: clamp(1.5rem, 4vw, 3rem); }
/* The photograph gets the larger share of the row. It is the only thing on the
   page that shows what actually arrives in the box. */
@media (min-width: 900px) { .product { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); align-items: start; } }

.product-stage {
  background: #FFFFFF; border: 1px solid var(--line);
  border-radius: var(--r-xl); aspect-ratio: 1; overflow: hidden;
}
.product-stage img { width: 100%; height: 100%; object-fit: cover; }
.product-shots { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: .75rem; }
.shot {
  width: 104px; height: 104px; padding: 0; cursor: pointer; overflow: hidden;
  background: #FFFFFF; border: 1px solid var(--line);
  border-radius: var(--r-md); transition: border-color .2s;
}
.shot img { width: 100%; height: 100%; object-fit: cover; }
.shot:hover { border-color: var(--line-strong); }
.shot.is-active { border-color: var(--yellow); }

.product-info { display: flex; flex-direction: column; gap: .9rem; }
.product-info h1 { font-size: clamp(1.9rem, 4vw, 3rem); }
.product-sub { font-size: var(--fs-sm); color: var(--text-2); }
.product-keys { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: .6rem; }
.product-keys li {
  display: grid; gap: .1rem; padding: .8rem;
  background: var(--surface-1); border: 1px solid var(--line); border-radius: var(--r-md);
}
.product-keys .ico { color: var(--yellow); }
.product-keys strong { font-family: var(--font-display); font-size: 1.05rem; }
.product-keys span { font-size: var(--fs-xs); color: var(--text-2); }
.product-keys .is-key { border-color: rgba(254,245,24,.35); }

.product-buy {
  display: grid; gap: .85rem; margin-top: .4rem;
  padding: clamp(1.1rem, 2.4vw, 1.6rem);
  background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: var(--r-xl);
}
.product-price { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem; }
.price-lg { font-family: var(--font-display); font-size: clamp(1.7rem, 3.4vw, 2.3rem); color: var(--yellow); }
.product-avail { display: inline-flex; align-items: center; gap: .4rem; font-size: var(--fs-xs); font-weight: 700; }
.product-avail.is-in { color: #7BD88F; }
.product-avail.is-in .ico { color: #7BD88F; }
.product-avail.is-out { color: var(--text-3); }

.qty { display: inline-flex; align-items: center; gap: .25rem; align-self: start; }
.qty-btn {
  width: 46px; height: 46px; display: grid; place-items: center; cursor: pointer;
  background: var(--surface-3); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  transition: border-color .2s, background .2s;
}
.qty-btn:hover { border-color: var(--yellow); color: var(--yellow); }
/* The field is a display for the two buttons beside it, so it carries no
   spinner of its own. `type=number` draws one anyway in every engine, and the
   reserved gutter for it pushes the digit off the centre of the box — which is
   what you actually notice. The input is `type=text inputmode=numeric` now, so
   phones still raise the number pad; these rules cover the rendered spinner in
   case the type ever changes back. */
.qty-input {
  width: 68px; height: 46px; text-align: center; font-weight: 700;
  background: var(--surface-1); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  -moz-appearance: textfield;
  appearance: textfield;
}
.qty-input::-webkit-outer-spin-button,
.qty-input::-webkit-inner-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
.qty-input:focus-visible { border-color: var(--yellow); outline: none; }
.product-pending {
  display: flex; gap: .5rem; font-size: var(--fs-xs); color: var(--text-2);
}
.product-pending .ico { width: 14px; height: 14px; margin-top: .2rem; flex: none; }
.product-assurance { display: grid; gap: .4rem; font-size: var(--fs-xs); color: var(--text-2); }
.product-assurance li { display: flex; gap: .5rem; }
.product-assurance .ico { width: 15px; height: 15px; margin-top: .15rem; color: var(--yellow); }

.product-detail { display: grid; gap: clamp(1.5rem, 4vw, 3rem); }
@media (min-width: 900px) { .product-detail { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); align-items: start; } }
.product-copy { display: grid; gap: .9rem; color: var(--text-2); }
.product-copy h2 { display: flex; align-items: center; gap: .6rem; font-size: clamp(1.3rem, 2.6vw, 1.8rem); color: var(--text); }
.product-copy h2 .ico { color: var(--yellow); }
.product-fit-title { margin-top: 1rem; }
.product-copy .btn { justify-self: start; }

.product-specs h2 { display: flex; align-items: center; gap: .6rem; margin-bottom: 1rem; font-size: clamp(1.3rem, 2.6vw, 1.8rem); }
.product-specs h2 .ico { color: var(--yellow); }
.speclist { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-xl); overflow: hidden; }
.speclist > div {
  display: grid; grid-template-columns: 1fr auto; gap: 1rem; align-items: baseline;
  padding: .85rem clamp(.9rem, 2vw, 1.3rem); border-bottom: 1px solid var(--line);
}
.speclist > div:last-child { border-bottom: 0; }
.speclist dt { display: flex; align-items: center; gap: .5rem; font-size: var(--fs-sm); color: var(--text-2); }
.speclist dt .ico { width: 15px; height: 15px; color: var(--text-3); }
.speclist dd { font-weight: 700; text-align: end; }

.tiles-related { grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr)); }
.related {
  display: flex; flex-direction: column;
  background: var(--surface-1); border: 1px solid var(--line); border-radius: var(--r-xl);
  overflow: hidden;
  transition: border-color .25s, transform .25s var(--ease);
}
.related:hover { border-color: var(--yellow); transform: translateY(-3px); }
.related-body { display: grid; gap: .3rem; padding: .9rem 1rem 1rem; }
.related strong { font-family: var(--font-display); font-size: .98rem; line-height: 1.2; }

/* ------------------------------------------------- drawer, cart, search */

/* The cart drawer and the search overlay shipped as markup with no stylesheet
   behind them, so both rendered as a plain block at the foot of every page —
   "Your cart is empty" sitting under the footer. Off-canvas by default now,
   and `hidden` on the scrim is honoured because [hidden] is !important above. */

.drawer-scrim {
  position: fixed;
  inset: 0;
  z-index: 290;
  background: rgba(4, 5, 7, .62);
  backdrop-filter: blur(3px);
  animation: scrim-in .25s var(--ease);
}
@keyframes scrim-in { from { opacity: 0; } to { opacity: 1; } }

.cart-drawer {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: 300;
  width: min(420px, 100vw);
  display: flex;
  flex-direction: column;
  background: var(--surface-1);
  border-inline-start: 1px solid var(--line);
  box-shadow: -24px 0 60px rgba(0, 0, 0, .5);
  transform: translateX(101%);
  transition: transform .32s var(--ease);
  padding-bottom: env(safe-area-inset-bottom);
}
.cart-drawer.is-open { transform: none; }
/* Off-screen is not enough on its own: a translated panel still holds focus
   and is still read out. Hidden from the tree until it is actually open. */
.cart-drawer[aria-hidden="true"] { visibility: hidden; }
.cart-drawer.is-open { visibility: visible; }

.cart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.1rem var(--gutter);
  border-bottom: 1px solid var(--line);
}
.cart-head h2 { display: flex; align-items: center; gap: .6rem; font-size: 1.2rem; }
.cart-head .ico { color: var(--yellow); }

.cart-body { flex: 1; overflow-y: auto; padding: 1.25rem var(--gutter); }
.cart-empty { color: var(--text-2); }
.cart-empty a { color: var(--yellow); text-decoration: underline; text-underline-offset: 3px; }

.cart-foot { display: grid; gap: .7rem; padding: 1.1rem var(--gutter) 1.4rem; border-top: 1px solid var(--line); }

/* Being *under* the consent bar is the same failure as being over it: the
   checkout button would sit behind the card and never be clickable. While
   consent is pending every overlay keeps the bar's measured height clear at
   its foot. --cbar-h is set by app.js and observed for changes, because the
   card grows to three rows on a narrow phone and in the longer translations. */
html[data-consent="pending"] .cart-foot { padding-bottom: calc(1.4rem + var(--cbar-h, 0px)); }
html[data-consent="pending"] .search-overlay { padding-bottom: calc(var(--gutter) + var(--cbar-h, 0px)); }
html[data-consent="pending"] .mobile-nav { padding-bottom: calc(var(--gutter) + var(--cbar-h, 0px)); }
html[data-consent="pending"] .to-top { bottom: calc(clamp(1rem, 3vw, 2rem) + var(--cbar-h, 0px)); }
.cart-line { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.cart-line strong { font-family: var(--font-display); font-size: 1.3rem; color: var(--yellow); }
.cart-ship, .cart-vat { font-size: var(--fs-xs); color: var(--text-2); }

.cart-count {
  position: absolute;
  inset: -4px -4px auto auto;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--yellow);
  color: #0B0B06;
  font-size: 11px;
  font-weight: 800;
}
.cart-btn { position: relative; }

/* ------------------------------------------------------------- search */

.search-overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  align-content: start;
  justify-items: center;
  padding: clamp(1rem, 8vh, 6rem) var(--gutter) var(--gutter);
  background: rgba(6, 8, 11, .9);
  backdrop-filter: blur(16px);
  overflow-y: auto;
  animation: scrim-in .2s var(--ease);
}
.search-panel { width: 100%; max-width: 680px; display: grid; gap: 1rem; }
.search-field { position: relative; display: flex; align-items: center; gap: .75rem; }
/* Direct child only. As a descendant selector this also caught the X inside
   the close button and pinned it 1.1rem from that button's own left edge —
   an off-centre icon with a dead-looking third of hit area beside it. */
.search-field > .ico { position: absolute; inset-inline-start: 1.1rem; color: var(--text-3); }
.search-input {
  width: 100%;
  min-height: 64px;
  padding: 0 3.6rem;
  background: var(--surface-1);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-xl);
  font-size: 1.1rem;
}
.search-input:focus { border-color: var(--yellow); outline: none; }
.search-close {
  position: absolute;
  inset-inline-end: .8rem;
  display: grid;
  place-items: center;
  /* The whole 44px square closes the overlay, not just the glyph. */
  width: 44px;
  height: 44px;
}
.search-hint, .search-none { font-size: var(--fs-sm); color: var(--text-2); }
.search-results { display: grid; gap: .5rem; max-height: 60vh; overflow-y: auto; }
.search-hit {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .75rem .9rem;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: border-color .18s, background .18s;
}
.search-hit:hover, .search-hit:focus-visible { border-color: var(--yellow); background: var(--surface-2); }
.search-hit .ico { color: var(--yellow); }
.search-shot { width: 44px; height: 44px; flex: none; border-radius: var(--r-sm); background: #FFFFFF; object-fit: cover; }
.search-hit span { display: grid; min-width: 0; }
.search-hit strong { font-size: var(--fs-sm); }
.search-hit small { font-size: var(--fs-xs); color: var(--text-2); }
.search-hit .price { margin-inline-start: auto; white-space: nowrap; }

/* The longer product copy: tagline, sub-headings, bullet list. */
.product-tagline { font-size: var(--fs-lead); color: var(--text-2); text-wrap: pretty; }
.product-h3 {
  display: flex; align-items: center; gap: .6rem;
  margin-top: 1.6rem; font-family: var(--font-display);
  font-size: clamp(1.05rem, 2vw, 1.25rem); color: var(--text);
}
.product-h3 .ico { color: var(--yellow); }
.product-bullets { display: grid; gap: .5rem; }
.product-bullets li { display: flex; gap: .6rem; align-items: baseline; }
.product-bullets .ico { width: 15px; height: 15px; margin-top: .25rem; flex: none; color: var(--yellow); }

/* ------------------------------------------------- basket lines and checkout */

/* The drawer's contents. A line is a thumbnail, the name with its unit price,
   a stepper, a line total, and a way out — in that reading order, because the
   question a basket answers is "what did I put in and what does it cost". */

.cart-items { display: grid; gap: .9rem; list-style: none; padding: 0; }
.cart-item {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) 32px;
  gap: .75rem;
  padding-bottom: .9rem;
  border-bottom: 1px solid var(--line);
}
.cart-item:last-child { border-bottom: 0; padding-bottom: 0; }
.cart-thumb {
  width: 64px; height: 64px; overflow: hidden;
  background: #FFFFFF; border: 1px solid var(--line); border-radius: var(--r-md);
}
.cart-thumb img { width: 100%; height: 100%; object-fit: cover; }
.cart-item-main { display: grid; gap: .35rem; min-width: 0; align-content: start; }
.cart-item-name { font-size: var(--fs-sm); font-weight: 700; line-height: 1.25; }
.cart-item-name:hover { color: var(--yellow); }
.cart-item-unit { font-size: var(--fs-xs); color: var(--text-2); }
.cart-item-row { display: flex; align-items: center; justify-content: space-between; gap: .6rem; }
.cart-item-total { font-family: var(--font-display); font-size: 1rem; white-space: nowrap; }
.cart-item-x {
  width: 32px; height: 32px; display: grid; place-items: center; cursor: pointer;
  align-self: start; background: none; border: 0; color: var(--text-3);
  transition: color .2s;
}
.cart-item-x:hover { color: var(--yellow); }
.cart-item-x .ico { width: 16px; height: 16px; }

/* Something the server changed about the basket after we asked it to price —
   a quantity clamped to the shelf, a line that sold out. Stated, not silent. */
.cart-note {
  display: block; margin-bottom: .9rem; padding: .6rem .75rem;
  background: rgba(254, 245, 24, .08); border: 1px solid rgba(254, 245, 24, .3);
  border-radius: var(--r-md); font-size: var(--fs-xs); color: var(--text);
}

/* The stepper inside a basket line. Same control as the product page, sized to
   sit in a 420px drawer beside a price. */
.qty-sm .qty-btn { width: 32px; height: 32px; border-radius: 10px; }
.qty-sm .qty-btn .ico { width: 14px; height: 14px; }
.qty-sm .qty-input { width: 44px; height: 32px; font-size: var(--fs-xs); border-radius: 10px; }
.qty-btn:disabled { opacity: .35; cursor: not-allowed; }
.qty-btn:disabled:hover { border-color: var(--line-strong); color: inherit; }

/* Quick-add from a listing tile. Price, then the action, then the way to read
   more — the tile's foot wraps to two rows before it squeezes the buttons. */
.tile-foot { flex-wrap: wrap; }
.tile-add { flex: 1 1 auto; }
.tile-view { flex: 0 0 auto; }
/* The confirmation lives on the button that was pressed. It lasts about a
   second and a half, which is long enough to read and short enough that it
   never becomes the button's resting label. */
.btn.is-added { background: #7BD88F; border-color: #7BD88F; color: #07120A; }

/* ------------------------------------------------------------- checkout */

/* Every one of these is a single-column grid, and a grid column that is not
   declared is `auto`, which has a *min-content* minimum — so each of them
   silently refused to go narrower than its widest descendant and passed that
   width up to the next one. On a 320px screen the chain ran
   .co-promo-row's text input → .co-promo (301px) → .co-aside → .checkout-grid,
   and the document came out 358px wide: 38px of sideways scroll on the page
   where a customer types their card details. `minmax(0, 1fr)` is what lets a
   single-column grid actually be as narrow as the box it is in. */
.checkout-grid {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem); align-items: start;
}
.checkout-grid > * { min-width: 0; }
@media (min-width: 900px) {
  .checkout-grid { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); }
  /* The summary follows the form down the page: on a four-step checkout the
     total is the one figure a person keeps checking back against. */
  .co-aside { position: sticky; top: calc(var(--header-h, 72px) + 1rem); }
}

.co-form { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(1rem, 2vw, 1.5rem); }
.co-step {
  display: grid; gap: .85rem; margin: 0; padding: clamp(1.1rem, 2.4vw, 1.6rem);
  background: var(--surface-1); border: 1px solid var(--line); border-radius: var(--r-xl);
  /* A fieldset's UA default is min-inline-size: min-content, so these refused
     to shrink past the widest legend and pushed 38px of horizontal scroll onto
     checkout at 320px. Grid children need the same release to stay inside. */
  min-inline-size: 0;
}
.co-step > * { min-width: 0; }
.co-step legend {
  display: flex; align-items: center; gap: .6rem; padding: 0;
  font-family: var(--font-display); font-size: clamp(1.05rem, 2vw, 1.25rem);
}
.co-step-n {
  display: grid; place-items: center; width: 26px; height: 26px; flex: none;
  border-radius: 999px; background: var(--yellow); color: #0B0B06;
  font-size: var(--fs-xs); font-weight: 800;
}
.co-lead { font-size: var(--fs-sm); color: var(--text-2); }

.co-row { display: grid; gap: .85rem; }
@media (min-width: 620px) { .co-row { grid-template-columns: 1fr 1fr; } }
.co-row[hidden] { display: none; }
.co-field { display: grid; gap: .35rem; min-width: 0; }
.co-label { font-size: var(--fs-xs); font-weight: 700; color: var(--text-2); }
.co-field.is-required .co-label::after { content: ' *'; color: var(--yellow); }
.co-field input {
  min-height: 48px; padding: 0 .9rem;
  background: var(--surface-2); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); color: var(--text); font-size: 1rem;
}
.co-field input:focus { border-color: var(--yellow); outline: none; }
.co-field input:user-invalid { border-color: #E8705F; }
.co-field small { font-size: var(--fs-xs); color: var(--text-3); }
.co-field .select-wrap select { min-height: 48px; }

.co-choices { display: grid; gap: .6rem; }
.co-choice {
  display: flex; align-items: start; gap: .75rem; cursor: pointer;
  padding: .85rem 1rem;
  background: var(--surface-2); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); transition: border-color .2s, background .2s;
}
.co-choice:hover { border-color: var(--line-strong); background: var(--surface-3); }
.co-choice input { margin-top: .2rem; accent-color: var(--yellow); width: 18px; height: 18px; flex: none; }
.co-choice span { display: grid; gap: .2rem; }
.co-choice strong { font-size: var(--fs-sm); }
.co-choice small { font-size: var(--fs-xs); color: var(--text-2); }
.co-choice:has(input:checked) { border-color: var(--yellow); background: var(--surface-3); }
.co-choice.is-off { opacity: .5; cursor: not-allowed; }

/* --- the card step
   Almost nothing here styles a card field: those are Stripe's iframes, dressed
   through the appearance object in cart.js. What is left is the furniture
   around them. */

.co-pay { display: grid; gap: .9rem; }
/* Reserved before the wallet buttons arrive, so the step does not jump when
   Apple Pay resolves a beat after the page settles. Hidden outright where the
   browser has no wallet at all — an empty gap is worse than no row. */
.co-express { min-height: 46px; }
.co-express[hidden] { display: none; }

/* A rule with a word sitting in it. The gradient fades the line out at both
   ends so it reads as a divider rather than as the top of a box. */
.co-or {
  display: flex; align-items: center; gap: .9rem;
  font-size: var(--fs-xs); color: var(--text-3); text-transform: lowercase;
}
.co-or::before, .co-or::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-strong), transparent);
}
.co-or[hidden] { display: none; }

/* Stripe's iframe reports its own height and grows as the shopper switches
   between tabs, so this only holds the space until it has loaded. */
.co-element { min-height: 120px; }
.co-loading {
  display: flex; align-items: center; gap: .5rem;
  font-size: var(--fs-sm); color: var(--text-3);
}
.co-loading .ico { width: 15px; height: 15px; flex: none; }
.co-loading.is-bad { color: #E8705F; }

/* Reuses the choice-row shape rather than inventing a second one: to the eye
   it is the same kind of control, one step further down the form. */
.co-save {
  display: flex; gap: .7rem; align-items: flex-start;
  padding: .75rem .9rem; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-2);
}
.co-save input { margin-top: .15rem; accent-color: var(--yellow); width: 18px; height: 18px; flex: none; }
.co-save span { display: grid; gap: .2rem; }
.co-save strong { font-size: var(--fs-sm); }
.co-save small { font-size: var(--fs-xs); color: var(--text-2); }
/* No email in step 1, nowhere to save the card to. Dimmed rather than removed,
   because it comes back the moment an address is typed. */
.co-save.is-off { opacity: .45; pointer-events: none; }

.co-secure {
  display: flex; gap: .5rem; align-items: flex-start;
  font-size: var(--fs-xs); color: var(--text-3);
}
.co-secure .ico { width: 14px; height: 14px; margin-top: .15rem; flex: none; color: var(--yellow); }

.co-withdrawal, .co-terms { font-size: var(--fs-xs); color: var(--text-2); }
.co-withdrawal { display: flex; gap: .5rem; }
.co-withdrawal .ico { width: 15px; height: 15px; margin-top: .15rem; flex: none; color: var(--yellow); }

.co-error {
  padding: .8rem 1rem; border-radius: var(--r-md);
  background: rgba(232, 112, 95, .12); border: 1px solid rgba(232, 112, 95, .45);
  color: #F3B4AA; font-size: var(--fs-sm);
}

.co-aside {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 1rem; padding: clamp(1.1rem, 2.4vw, 1.6rem);
  background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: var(--r-xl);
}
.co-aside h2 { display: flex; align-items: center; gap: .6rem; font-size: 1.15rem; }
.co-aside h2 .ico { color: var(--yellow); }

.co-lines { display: grid; gap: .55rem; list-style: none; padding: 0; }
/* Picture, quantity, name, money. The picture column collapses to nothing on
   a line that has no photograph, so a mixed basket still lines up. */
.co-lines li { display: grid; grid-template-columns: auto auto minmax(0, 1fr) auto; gap: .6rem; align-items: center; font-size: var(--fs-sm); }
.co-lines li > .co-qty:first-child { grid-column: 2; }
.co-shot { width: 48px; height: 48px; border-radius: var(--r-sm); background: #FFFFFF; object-fit: cover; }
.co-lines a:hover { color: var(--yellow); }
.co-qty { font-weight: 800; color: var(--text-2); }
.co-lines strong { white-space: nowrap; }

.co-totals { display: grid; gap: .45rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.co-totals > div { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; font-size: var(--fs-sm); }
.co-totals dt { color: var(--text-2); }
.co-totals .is-off dd { color: #7BD88F; }
.co-grand { padding-top: .5rem; border-top: 1px solid var(--line); }
.co-grand dt { font-weight: 700; color: var(--text); }
.co-grand dd { font-family: var(--font-display); font-size: 1.35rem; color: var(--yellow); }
.co-vat { font-size: var(--fs-xs); color: var(--text-3); }

.co-promo {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: .4rem; padding-top: .9rem; border-top: 1px solid var(--line);
}
.co-promo-row { display: flex; gap: .5rem; }
.co-promo-row input {
  flex: 1; min-width: 0; min-height: 44px; padding: 0 .8rem;
  background: var(--surface-1); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); color: var(--text); text-transform: uppercase;
}
.co-promo-row input:focus { border-color: var(--yellow); outline: none; }
.co-promo-row .btn { min-height: 44px; padding: 0 1rem; font-size: var(--fs-xs); }
.co-promo-msg { font-size: var(--fs-xs); color: #7BD88F; }
.co-promo-msg.is-bad { color: #E8705F; }

.co-back { display: inline-flex; align-items: center; gap: .5rem; font-size: var(--fs-sm); color: var(--text-2); }
.co-back:hover { color: var(--yellow); }
.co-back .ico { width: 15px; height: 15px; transform: rotate(180deg); }

/* --------------------------------------------------------- order placed */

.thanks { display: grid; justify-items: start; gap: 1rem; }
.thanks-mark {
  display: grid; place-items: center; width: 56px; height: 56px;
  border-radius: 999px; background: rgba(123, 216, 143, .14);
  border: 1px solid rgba(123, 216, 143, .45);
}
.thanks-mark .ico { width: 26px; height: 26px; color: #7BD88F; }
.thanks h1 { font-size: clamp(1.8rem, 4vw, 2.8rem); }
.thanks h1 [data-order-number] { color: var(--yellow); white-space: nowrap; }
.thanks-lead { font-size: var(--fs-lead); color: var(--text-2); max-width: 60ch; }
.thanks-keep { display: flex; gap: .5rem; font-size: var(--fs-sm); color: var(--text-2); }
.thanks-keep .ico { width: 16px; height: 16px; margin-top: .15rem; flex: none; color: var(--yellow); }
.thanks-summary {
  width: 100%; display: grid; gap: .9rem; padding: clamp(1rem, 2.4vw, 1.5rem);
  background: var(--surface-1); border: 1px solid var(--line); border-radius: var(--r-xl);
}
.thanks h2 { font-size: 1.2rem; margin-top: .5rem; }
.thanks-steps { display: grid; gap: .5rem; padding-inline-start: 1.2rem; color: var(--text-2); }
.thanks-steps li { padding-inline-start: .3rem; }
/* Arrived without an order — the confirmation is hidden rather than shown with
   blanks where the number should be. */
.thanks.is-bare h1, .thanks.is-bare .thanks-keep, .thanks.is-bare .thanks-mark { display: none; }

/* ---------------------------------------------------- bulbs for your car */

.fit { display: grid; gap: clamp(1.25rem, 3vw, 2rem); }
.fit-head { display: grid; gap: .6rem; max-width: 70ch; }
/* The heading carries a whole car in it — make, model, generation and the
   years — so it is set smaller and given a wider measure than a display
   headline would normally get, to keep it to two lines rather than four. */
.fit-head h1 { font-size: clamp(1.6rem, 3.2vw, 2.35rem); max-width: 26ch; text-wrap: balance; }
.fit-lead { font-size: var(--fs-lead); color: var(--text-2); }
.fit-status { display: flex; align-items: center; gap: .5rem; font-size: var(--fs-sm); color: var(--text-2); }
.fit-status.is-warn { color: var(--yellow); }

.fit-groups { display: grid; gap: clamp(1.25rem, 3vw, 2rem); }
.fit-group { display: grid; gap: .9rem; }
/* The position is the heading, because the question being answered is
   "which bulb goes where" — not "which products match". */
.fit-group h2 {
  display: flex; align-items: center; gap: .6rem;
  padding-bottom: .5rem; border-bottom: 1px solid var(--line);
  font-size: clamp(1.15rem, 2.4vw, 1.5rem);
}
/* Most positions have exactly one bulb, so the card is laid out wide rather
   than as a tile: a lone 230px tile in a 1200px row reads as a page that
   failed to load the rest. Two per row at desk width, one below that. */
.fit-cards { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 430px), 1fr)); }
.fit-card {
  display: grid; gap: .3rem 1.1rem; padding: 1rem;
  grid-template-columns: clamp(120px, 26vw, 190px) minmax(0, 1fr);
  align-content: center;
  background: var(--surface-1); border: 1px solid var(--line); border-radius: var(--r-xl);
  transition: border-color .25s, transform .25s var(--ease);
}
.fit-card:hover { border-color: var(--line-strong); transform: translateY(-3px); }
/* The frame is the shared one; only its place in the card's grid is local. */
.fit-card .pmedia { grid-row: 1 / 3; align-self: center; border-radius: var(--r-md); }
.fit-card-body { display: grid; gap: .25rem; align-self: end; }
/* A grid item, so unlike the breadcrumbs the padding would really make the card
   taller — the negative margin is what keeps every fitment card the height it
   was drawn at while the link itself clears 24px. */
.fit-card-name {
  font-size: var(--fs-base); font-weight: 700; line-height: 1.25;
  padding-block: .25rem; margin-block: -.25rem;
}
.fit-card-name:hover { color: var(--yellow); }
.fit-card-sku { font-size: var(--fs-xs); color: var(--text-3); }
.fit-card .price { font-family: var(--font-display); font-size: 1.35rem; color: var(--yellow); }
.fit-card .btn { min-height: 44px; margin-top: .55rem; align-self: start; }

.fit-again {
  display: grid; justify-items: start; gap: .7rem;
  padding: clamp(1.2rem, 2.5vw, 1.8rem);
  background: var(--surface-1); border: 1px solid var(--line); border-radius: var(--r-xl);
}
.fit-again h2 { display: flex; align-items: center; gap: .6rem; font-size: 1.2rem; }
.fit-again h2 .ico { color: var(--yellow); }
.fit-again p { color: var(--text-2); }
.fit-again .btn { min-height: 46px; }
@media (min-width: 620px) {
  .fit-again { grid-template-columns: auto auto; }
  .fit-again h2, .fit-again p { grid-column: 1 / -1; }
}

/* ------------------------------------------------------ the quiet notice */

/* One line, bottom centre, for about two seconds after a withheld right-click.
   It sits above the page but takes no pointer events, so nothing underneath it
   stops working while it is up — and it is raised clear of the consent bar,
   which is fixed to the same edge.

   z-index is below the consent bar and the drawers on purpose: a passing note
   should never cover a control somebody is trying to use. */
.protect-note {
  position: fixed;
  left: 50%;
  bottom: calc(var(--cbar-h, 0px) + 1.25rem);
  z-index: 60;
  transform: translate(-50%, .5rem);
  max-width: min(90vw, 26rem);
  padding: .55rem 1rem;
  border-radius: var(--r-pill);
  background: rgba(8, 10, 13, .92);
  border: 1px solid var(--line-strong);
  color: var(--text-2);
  font-size: var(--fs-sm);
  text-align: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity .2s var(--ease), transform .2s var(--ease);
}
.protect-note.is-on { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  .protect-note { transition: opacity .2s linear; transform: translate(-50%, 0); }
}
