/* SNS Driven — shared stylesheet.
   Extracted from index.html on 2026-08-27 so the public marketing page and the
   unlisted booking page cannot drift apart. Both pages link this file; edit it
   here and nowhere else. The .bq-* rules only apply on the booking page now —
   they are kept here rather than moved because they are written against
   Booqable's runtime markup and were hard-won (see BOOQABLE-INTEGRATION.md). */

:root {
  /* Brand palette — taken verbatim from the SNS brand guidelines, v1.0 */
  --jet: #090909;
  --graphite: #2B2B2B;
  --slate: #686868;
  --pure: #F7F7F7;
  --gold: #B59A63;
  --silver: #A8A8A8;

  /* Surface layering: base -> elevated -> floating */
  --surface-base: #090909;
  --surface-elevated: #101010;
  --surface-floating: #161616;
  --hairline: rgba(247, 247, 247, 0.10);
  --hairline-soft: rgba(247, 247, 247, 0.06);

  /* Spacing scale — used consistently, no ad-hoc steps */
  --s-1: 0.5rem;
  --s-2: 1rem;
  --s-3: 1.5rem;
  --s-4: 2.5rem;
  --s-5: 4rem;
  --s-6: 6rem;
  --s-7: 9rem;

  --frame-inset: 1.25rem;
  --ease-spring: cubic-bezier(0.16, 1, 0.3, 1);
}

html {
  scroll-behavior: smooth;
}

body {
  background-color: var(--surface-base);
  color: var(--pure);
  font-family: Inter, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Ambient depth: layered radial washes + film grain, kept near-invisible.
 The brand photography spec is low saturation / strong contrast, so this
 stays as atmosphere rather than decoration. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(80rem 50rem at 78% -10%, rgba(181, 154, 99, 0.09), transparent 62%),
    radial-gradient(60rem 40rem at 5% 12%, rgba(168, 168, 168, 0.05), transparent 60%),
    radial-gradient(70rem 60rem at 50% 108%, rgba(181, 154, 99, 0.05), transparent 65%);
}

body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

.layer {
  position: relative;
  z-index: 2;
}

/* ---- Type roles ---- */
.u-display {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 0.92;
}

.u-label {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 500;
  font-size: 0.6875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.u-body {
  font-size: 1rem;
  line-height: 1.7;
  color: var(--silver);
}

/* ---- Signature: the guidelines' own page furniture, carried onto the web.
 Every spread in the brand deck is framed by a hairline with the SNS mark
 bottom-left and the section number bottom-right. The index below tracks
 the reader's real position, so it carries information rather than decorating. ---- */
.doc-frame {
  position: fixed;
  inset: var(--frame-inset);
  border: 1px solid var(--hairline-soft);
  pointer-events: none;
  z-index: 40;
}

.doc-frame__mark,
.doc-frame__index {
  position: absolute;
  bottom: -0.5rem;
  background: var(--surface-base);
  padding: 0 0.75rem;
  color: var(--slate);
}

.doc-frame__mark {
  left: 1.5rem;
}

.doc-frame__index {
  right: 1.5rem;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 767px) {
  .doc-frame {
    display: none;
  }
}

/* ---- Logo: the supplied asset is a 500x500 plate in which the wordmark
 occupies only 123x39px. sns-logo-mark.png is that mark trimmed out and
 made transparent, so it can be sized honestly. Aspect ratio 3.15:1. ---- */
.logo-mark {
  display: block;
  width: auto;
}

/* ---- Buttons ---- */
.btn {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 500;
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  transition: transform 0.4s var(--ease-spring),
    background-color 0.3s var(--ease-spring),
    color 0.3s var(--ease-spring),
    border-color 0.3s var(--ease-spring),
    box-shadow 0.4s var(--ease-spring),
    opacity 0.3s var(--ease-spring);
}

.btn:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: 3px;
}

.btn-primary {
  background: var(--gold);
  color: var(--jet);
  padding: 1.125rem 2rem;
  /* Layered, colour-tinted shadow rather than a flat drop */
  box-shadow:
    0 1px 1px rgba(9, 9, 9, 0.5),
    0 8px 20px -8px rgba(181, 154, 99, 0.35),
    0 20px 48px -20px rgba(181, 154, 99, 0.28);
}

.btn-primary:hover {
  background: #C7AE78;
  transform: translateY(-2px);
  box-shadow:
    0 1px 1px rgba(9, 9, 9, 0.5),
    0 12px 26px -8px rgba(181, 154, 99, 0.45),
    0 28px 60px -22px rgba(181, 154, 99, 0.35);
}

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

.btn-ghost {
  border: 1px solid var(--hairline);
  color: var(--pure);
  padding: 0.75rem 1.5rem;
}

.btn-ghost:hover {
  border-color: var(--gold);
  color: var(--gold);
}

/* ---- Social pills (footer) ---- */
.social-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1.1rem;
  border-radius: 9999px;
  border: 1px solid var(--hairline);
  background: var(--surface-floating);
  color: var(--pure);
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 500;
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  text-transform: none;
  transition: border-color 0.3s var(--ease-spring), color 0.3s var(--ease-spring),
    transform 0.3s var(--ease-spring);
}

.social-pill:hover,
.social-pill:focus-visible {
  border-color: var(--gold);
  color: var(--gold);
  transform: translateY(-2px);
}

.social-pill svg {
  flex-shrink: 0;
}

.social-pill--lg {
  padding: 0.6rem 1.15rem;
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 0.9375rem;
  letter-spacing: -0.02em;
}

.social-pill--lg svg {
  width: 17px;
  height: 17px;
}

.btn-ghost:active {
  transform: scale(0.98);
}

/* ---- Nav links ---- */
.nav-link {
  position: relative;
  color: var(--silver);
  transition: color 0.3s var(--ease-spring);
}

.nav-link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -0.4rem;
  width: 100%;
  height: 1px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s var(--ease-spring);
}

.nav-link:hover,
.nav-link:focus-visible {
  color: var(--pure);
}

.nav-link:hover::after,
.nav-link:focus-visible::after {
  transform: scaleX(1);
}

.nav-link:focus-visible {
  outline: none;
  color: var(--gold);
}

/* ---- Media treatment: gradient scrim + colour layer, per brand photography ---- */
.media {
  position: relative;
  overflow: hidden;
  background: var(--surface-elevated);
}

.media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.55) contrast(1.12);
  transition: transform 0.9s var(--ease-spring);
}

.media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(9, 9, 9, 0.75), rgba(9, 9, 9, 0.05) 55%);
  pointer-events: none;
}

.media__tint {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, rgba(181, 154, 99, 0.16), rgba(43, 43, 43, 0.6));
  mix-blend-mode: multiply;
  pointer-events: none;
  z-index: 1;
}

/* ---- Real photography, shown as supplied: no desaturation/contrast
   filter, no gradient scrim, no colour tint. ---- */
.media--plain img {
  filter: none;
}

.media--plain::after {
  display: none;
}

.fleet-card:hover .media img,
.fleet-card:focus-within .media img {
  transform: scale(1.04);
}

/* Column layout so the booking button sits on the card's baseline rather
   than wherever the description happens to end — the three CTAs have to
   line up across the row. */
.fleet-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--hairline-soft);
  background: var(--surface-elevated);
  transition: border-color 0.4s var(--ease-spring),
    transform 0.5s var(--ease-spring),
    box-shadow 0.5s var(--ease-spring);
}

.fleet-card:hover,
.fleet-card:focus-within {
  border-color: rgba(181, 154, 99, 0.35);
  transform: translateY(-4px);
  box-shadow:
    0 1px 1px rgba(9, 9, 9, 0.6),
    0 18px 40px -18px rgba(0, 0, 0, 0.8),
    0 40px 80px -40px rgba(181, 154, 99, 0.22);
}

/* ---- Trophy feature — the G63 ----
   Deliberately not a fourth card in the three-up grid. It is the only vehicle
   that is not in Booqable, so it has no rate to publish and no eligibility
   route to send anyone down; its only honest call to action is a conversation.
   A full-width band, one step higher in the surface layering than the cards
   above it, ending in the site's single solid-gold panel. ---- */
.trophy {
  position: relative;
  overflow: hidden;
  background: var(--surface-floating);
  border: 1px solid rgba(181, 154, 99, 0.26);
  box-shadow:
    0 1px 1px rgba(9, 9, 9, 0.6),
    0 26px 60px -26px rgba(0, 0, 0, 0.85),
    0 60px 120px -56px rgba(181, 154, 99, 0.26);
  transition: border-color 0.5s var(--ease-spring),
    box-shadow 0.6s var(--ease-spring);
}

.trophy:hover,
.trophy:focus-within {
  border-color: rgba(181, 154, 99, 0.45);
  box-shadow:
    0 1px 1px rgba(9, 9, 9, 0.6),
    0 30px 70px -26px rgba(0, 0, 0, 0.9),
    0 70px 140px -56px rgba(181, 154, 99, 0.36);
}

/* Gold wash behind the copy side. Carries the elevation without adding
   another hairline, and keeps the photograph itself untinted. */
.trophy::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(46rem 34rem at 92% 4%, rgba(181, 154, 99, 0.15), transparent 64%);
}

.trophy > * {
  position: relative;
  z-index: 1;
}

.trophy .media img {
  transition: transform 1.1s var(--ease-spring);
}

.trophy:hover .media img,
.trophy:focus-within .media img {
  transform: scale(1.03);
}

/* Hairline between photograph and copy — vertical once they sit side by side. */
.trophy__divide {
  border-top: 1px solid var(--hairline-soft);
}

@media (min-width: 1280px) {
  .trophy__divide {
    border-top: 0;
    border-left: 1px solid var(--hairline-soft);
  }
}

.trophy__rule {
  width: 2.5rem;
  height: 1px;
  background: var(--gold);
}

/* ---- The gold card ----
   Solid gold is the loudest surface on a near-black site, so it is used
   exactly once: the G63 enquiry. Sending people to WhatsApp rather than the
   eligibility form is the point of it. ---- */
.gold-card {
  background:
    linear-gradient(148deg, #CDB47D 0%, var(--gold) 52%, #9F8550 100%);
  color: var(--jet);
  padding: 1.5rem;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    0 1px 1px rgba(9, 9, 9, 0.5),
    0 14px 34px -14px rgba(181, 154, 99, 0.4),
    0 34px 70px -30px rgba(181, 154, 99, 0.3);
}

@media (min-width: 768px) {
  .gold-card {
    padding: 1.75rem;
  }
}

.gold-card__title {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.375rem;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--jet);
}

.gold-card__note {
  color: rgba(9, 9, 9, 0.72);
  font-size: 0.875rem;
  line-height: 1.6;
}

/* Jet button, only ever used on the gold card — btn-primary would be
   gold on gold. */
.btn-jet {
  background: var(--jet);
  color: var(--pure);
  padding: 1.125rem clamp(1rem, 4vw, 2rem);
  box-shadow:
    0 1px 1px rgba(9, 9, 9, 0.4),
    0 10px 24px -10px rgba(9, 9, 9, 0.6);
}

.btn-jet:hover {
  background: var(--graphite);
  color: var(--gold);
  transform: translateY(-2px);
  box-shadow:
    0 1px 1px rgba(9, 9, 9, 0.4),
    0 16px 32px -12px rgba(9, 9, 9, 0.7);
}

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

.btn-jet:focus-visible {
  outline: 1px solid var(--jet);
  outline-offset: 3px;
}

/* Smallest phones: "Enquire on WhatsApp" is the longest button label on the
   site and wraps below ~360px at the default tracking. Tighten the card and
   the button rather than shortening the label. */
@media (max-width: 380px) {
  .gold-card {
    padding: 1.25rem;
  }

  .btn-jet {
    padding: 1rem 0.75rem;
    font-size: 0.625rem;
    letter-spacing: 0.12em;
    gap: 0.5rem;
  }

  /* Below 360px even that is 5px short. The label already says WhatsApp,
     so the glyph is the thing to drop, not a word. */
  .btn-jet svg {
    display: none;
  }
}

/* ---- Form ---- */
.field {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  padding: 0.875rem 0;
  color: var(--pure);
  font-family: Inter, system-ui, sans-serif;
  font-size: 0.9375rem;
  transition: border-color 0.35s var(--ease-spring);
}

.field::placeholder {
  color: var(--slate);
}

.field:hover {
  border-color: rgba(247, 247, 247, 0.24);
}

.field:focus {
  outline: none;
  border-color: var(--gold);
}

/* ---- Booqable store components ----
 The embedded widgets ship with their own light-theme styling and their
 internal class names are build-hashed, so they are not safe to target.
 Everything below works structurally instead: each embed sits inside a
 .bq-slot, and the overrides reach it through element selectors that
 Booqable's markup cannot rename out from under us.

 Icon fonts are deliberately exempt from the font-family override —
 Booqable draws its chevrons and spinners with Font Awesome glyphs, and
 re-pointing their font-family renders them as tofu. ---- */
.bq-slot {
  color-scheme: dark;
  font-family: Inter, system-ui, sans-serif;
  color: var(--pure);
}

.bq-slot :where(h1, h2, h3, h4, p, span, div, label, li, td, th) {
  color: var(--pure);
}

.bq-slot :where(input, select, textarea) {
  background: var(--surface-elevated);
  color: var(--pure);
  border: 1px solid var(--hairline);
  border-radius: 0;
  font-family: Inter, system-ui, sans-serif;
}

.bq-slot :where(input, select, textarea):focus {
  outline: none;
  border-color: var(--gold);
}

/* The date picker is the one widget with real chrome of its own; give it a
   floating surface so it reads as part of the page's layering system. */
/* The floating panel a booking component sits in. `.panel` is the neutral name
   — the public page uses it for a plain panel with no Booqable inside. */
.panel,
.bq-slot--panel {
  background: var(--surface-floating);
  border: 1px solid var(--hairline-soft);
  padding: var(--s-3);
}

/* Booqable wraps its components in its own light-theme containers. Clear
   those back to the card surface rather than letting white blocks punch
   holes in the layout. */
.bq-slot :where(div, form, ul, li) {
  background: transparent;
}

/* ---- Date picker trigger ----
   Booqable renders a single button that opens its rental-period modal.
   Reads as one of our own fields rather than a stray white bar. */
.bq-slot .bq-date-picker-button-wrapper {
  width: 100%;
  text-align: left;
  background: var(--surface-elevated);
  border: 1px solid var(--hairline);
  border-radius: 0;
  padding: 1rem 1.25rem;
  cursor: pointer;
  transition: border-color 0.35s var(--ease-spring);
}

.bq-slot .bq-date-picker-button-wrapper:hover {
  border-color: var(--gold);
}

.bq-slot .bq-date-picker-button-wrapper:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: 3px;
}

.bq-slot .bq-date-picker-button-text {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 500;
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pure);
}

/* Booqable appends "; View prices and availability" to its own label. The
   surrounding copy already says that, and the semicolon reads badly in
   caps, so the suffix goes. */
.bq-slot .bq-date-picker-button-expanded-title {
  display: none;
}

/* ---- Product button ----
   Booqable's price line is the live one: it re-reads for whichever period
   is selected, and this fleet is priced non-linearly, so a week is not
   seven day-rates. It is therefore the only price the cards quote. */
.bq-book .bq-actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 1rem;
}

.bq-book .bq-price-details {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.bq-book .bq-duration {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 500;
  font-size: 0.6875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--slate);
}

.bq-book .bq-price {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: -0.02em;
  color: var(--gold);
}

.bq-book .bq-control {
  display: flex;
  align-items: center;
}

/* There is one of each vehicle, so a quantity field can only ever produce
   an order that cannot be fulfilled. Hidden by its stable form name — the
   surrounding class names are build-hashed and will change. */
.bq-book .bq-control>div:has(input[name="quantity"]),
.bq-book .bq-control>div:has(input[name="quantity"])+div {
  display: none;
}

/* The per-vehicle availability calendar is a custom element with a closed
   look: its internals live in a shadow root this stylesheet cannot select.
   Inherited properties still cross the boundary, so the type and colour are
   set on the host and inherit inwards. Anything non-inherited — the
   underline, spacing inside the widget — stays Booqable's. */
.bq-book bq-product-availability-calendar {
  display: block;
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--silver);
}

/* Booqable's wrapper is inline-block, which shrink-wraps the button to its
   label. Block it out so the CTA fills the card. */
.bq-book .booqable-product-button-wrapper {
  display: block;
  width: 100%;
}

.bq-book .bq-control>span {
  display: block;
  flex: 1;
}

/* Add-to-cart button, restyled to .btn-primary.
   !important is load-bearing here, not laziness: the button is a
   styled-component, so its rules are injected into <head> at runtime and
   land after this stylesheet. At equal specificity the later sheet wins,
   which is why padding, font and colour silently reverted to Booqable's
   Roboto/6px-radius defaults while background and box-shadow took. Only the
   properties that actually lose the tie are forced. */
.bq-book .bq-button {
  width: 100%;
  height: auto !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  background: var(--gold);
  color: var(--jet) !important;
  border: 0;
  border-radius: 0 !important;
  padding: 1.0625rem 1.75rem !important;
  cursor: pointer;
  box-shadow:
    0 1px 1px rgba(9, 9, 9, 0.5),
    0 8px 20px -8px rgba(181, 154, 99, 0.35),
    0 20px 48px -20px rgba(181, 154, 99, 0.28);
  transition: transform 0.4s var(--ease-spring),
    background-color 0.3s var(--ease-spring),
    box-shadow 0.4s var(--ease-spring);
}

/* The label is its own styled-component, so the type has to be set on the
   span rather than inherited from the button. */
.bq-book .bq-button,
.bq-book .bq-button span {
  font-family: 'Space Grotesk', system-ui, sans-serif !important;
  font-weight: 500 !important;
  font-size: 0.6875rem !important;
  letter-spacing: 0.18em !important;
  text-transform: uppercase;
  color: var(--jet) !important;
}

.bq-book .bq-button:hover {
  background: #C7AE78;
  transform: translateY(-2px);
  box-shadow:
    0 1px 1px rgba(9, 9, 9, 0.5),
    0 12px 26px -8px rgba(181, 154, 99, 0.45),
    0 28px 60px -22px rgba(181, 154, 99, 0.35);
}

.bq-book .bq-button:active {
  transform: translateY(0);
}

.bq-book .bq-button:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: 3px;
}

/* Fallback: revealed by script only when the store bundle fails to arrive,
   so a CDN outage costs the customer a click rather than the booking. */
.bq-fallback,
.bq-fallback-note {
  display: none;
}

.bq-unavailable .bq-slot {
  display: none;
}

.bq-unavailable .bq-fallback {
  display: inline-flex;
}

.bq-unavailable .bq-fallback-note {
  display: block;
}

/* ---- Entrance: one orchestrated load sequence, then scroll reveals ---- */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.8s var(--ease-spring), transform 0.8s var(--ease-spring);
}

.reveal.is-in {
  opacity: 1;
  transform: translateY(0);
}

.hero-line {
  display: block;
  overflow: hidden;
}

.hero-line>span {
  display: block;
  transform: translateY(100%);
  transition: transform 1.1s var(--ease-spring);
}

.is-loaded .hero-line>span {
  transform: translateY(0);
}

.is-loaded .hero-line:nth-child(2)>span {
  transition-delay: 0.08s;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }

  .reveal {
    opacity: 1;
    transform: none;
  }

  .hero-line>span {
    transform: none;
  }
}

/* ---- Cookie consent banner ----
   Added 2026-09-03 from Workstreams/04-legal-and-consent/consent-banner-proposal.md §3.2.
   Uses the existing brand tokens. Sits above the doc-frame but is not a modal: the page
   stays readable and scrollable behind it. No cookie wall. */
.cookie-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  background: var(--surface-floating);
  border-top: 1px solid var(--hairline);
  box-shadow: 0 -1px 1px rgba(9, 9, 9, 0.5),
              0 -20px 48px -24px rgba(9, 9, 9, 0.9);
  transform: translateY(100%);
  transition: transform 0.5s var(--ease-spring);
}

.cookie-banner.is-open { transform: translateY(0); }

.cookie-banner__inner {
  max-width: 88rem;
  margin: 0 auto;
  padding: var(--s-3) 1.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}

@media (min-width: 768px) {
  .cookie-banner__inner { padding: var(--s-3) 3rem; }
}

.cookie-banner__copy { flex: 1 1 22rem; min-width: 0; }

.cookie-banner__link {
  color: var(--gold);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  transition: color 0.3s var(--ease-spring);
}

.cookie-banner__link:hover { color: var(--pure); }

.cookie-banner__actions {
  display: flex;
  gap: 0.75rem;
  flex: 0 0 auto;
}

/* Both buttons identical. Reject must be no harder to find or press than Accept — that is a
   compliance property, not a style choice. Do not make one of these btn-primary. */
.cookie-btn {
  border: 1px solid var(--hairline);
  color: var(--pure);
  background: transparent;
  padding: 0.875rem 1.75rem;
  min-width: 8rem;
  cursor: pointer;
}

.cookie-btn:hover {
  border-color: var(--gold);
  color: var(--gold);
}

@media (max-width: 30rem) {
  .cookie-banner__actions { width: 100%; }
  .cookie-btn { flex: 1 1 0; min-width: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .cookie-banner { transition: none; }
}

/* ---- Policy pages (/cookies/, and the privacy policy when it lands).
 Long-form legal prose is a different typographic problem from the marketing
 page: it is read in sequence rather than scanned, so it wants a narrow measure,
 generous leading and real hierarchy between a section and its body. Scoped
 under .policy so none of it can leak into the landing page. ---- */
.policy {
  max-width: 46rem;
}

.policy h2 {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-size: 1.5rem;
  line-height: 1.2;
  color: var(--pure);
  margin: var(--s-5) 0 var(--s-2);
}

.policy h3 {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 500;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
  color: var(--pure);
  margin: var(--s-4) 0 var(--s-1);
}

.policy p,
.policy li {
  font-size: 1rem;
  line-height: 1.75;
  color: var(--silver);
}

.policy p {
  margin-bottom: var(--s-2);
}

.policy ul {
  list-style: none;
  margin: 0 0 var(--s-2);
  padding: 0;
}

.policy li {
  position: relative;
  padding-left: 1.25rem;
  margin-bottom: 0.5rem;
}

/* A hairline dash rather than a bullet — the brand deck uses rules, not dots. */
.policy li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.85em;
  width: 0.5rem;
  height: 1px;
  background: var(--gold);
}

.policy strong {
  color: var(--pure);
  font-weight: 500;
}

.policy a {
  color: var(--gold);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: opacity 0.3s var(--ease-spring);
}

.policy a:hover {
  opacity: 0.7;
}

.policy code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.875em;
  color: var(--pure);
  background: var(--surface-floating);
  border: 1px solid var(--hairline-soft);
  border-radius: 3px;
  padding: 0.1em 0.35em;
}

/* Tables carry the actual substance on a cookie policy, so they must stay
 readable on a phone. The wrapper scrolls; the page never does. */
.policy-table-wrap {
  overflow-x: auto;
  margin-bottom: var(--s-3);
  border: 1px solid var(--hairline-soft);
}

.policy table {
  width: 100%;
  min-width: 34rem;
  border-collapse: collapse;
}

.policy th,
.policy td {
  text-align: left;
  padding: 0.875rem 1rem;
  font-size: 0.9375rem;
  line-height: 1.6;
  border-bottom: 1px solid var(--hairline-soft);
  vertical-align: top;
}

.policy th {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 500;
  font-size: 0.6875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--slate);
  background: var(--surface-elevated);
}

.policy td {
  color: var(--silver);
}

.policy tr:last-child td {
  border-bottom: 0;
}

/* A stated fact the reader should not skim past — used for the two places this
 policy says something most cookie policies quietly avoid saying. */
.policy-note {
  border-left: 1px solid var(--gold);
  padding: 0.25rem 0 0.25rem var(--s-2);
  margin: var(--s-3) 0;
}

.policy-note p:last-child {
  margin-bottom: 0;
}
