/*
 * site/assets/site.css — shared design system for bimmertracker.com.
 *
 * The site is the marketing home of the Bimmer Tracker apps, and it wears the
 * app's 1.1.0 look: "Glass". Dark only — the app has no light mode, so a site
 * that flipped white in daylight would read as a different product. Every hex
 * below is a literal transcription of ios/BimmerTracker/Theme/AppTheme.swift;
 * when a value changes there, change it here.
 *
 * THE BACKGROUND IS A VIEW, NOT A COLOUR (GlassBackground): a 165deg gradient
 * plus two off-frame radial glows. `--ground` is only the darkest stop — the
 * value <meta theme-color> and any opaque backing must use so nothing flashes
 * a different black.
 *
 * A card is glass: a white 9% fill, a white 12% hairline, a lit top edge
 * (inset white 20%) and a 20px backdrop blur. The lit edge is what makes it
 * read as a pane rather than a hole; do not drop it. Everything quieter — a
 * build sheet, a breakdown list — uses the second tier (`--quiet`), which has
 * no border at all. Two tiers, never three.
 *
 * Type: the system stack, one face. Barlow Semi Condensed retired with the
 * Signal theme, and with it the Google Fonts request — this site now talks to
 * exactly one third party, Cloudflare's cookieless analytics beacon, and
 * privacy.html says so. Tabular figures on every quantity; monospace only for
 * identifiers someone might read aloud or paste (VIN, production number,
 * status code).
 *
 * Class vocabulary is shared across generated pages: the marketing home, the
 * legal/support prose pages, the model hubs and their year/trim segment pages.
 * Bar-chart / tile / card classes are load-bearing for scripts/build-site.js's
 * renderers — rename nothing here without renaming it there. `model-card` in
 * particular is the string .github/workflows/deploy-site.yml fingerprints
 * index.html on; renaming it fails the deploy.
 */

/* ---------------------------------------------------------------------
 * tokens
 * ------------------------------------------------------------------- */
:root {
  /* AppTheme palette, verbatim */
  --ground: #0A1122;
  --panel: #16233A;
  --hair: #2A3A54;
  --ink: #EAF1FA;
  --ink-2: #AAB8CC;   /* AppTheme.muted */
  --ink-3: #7E8CA0;   /* AppTheme.dimmed */
  --accent: #8FC5FF;
  --accent-deep: #3E8EE0;  /* accent FILLS only; never foreground text */
  --accent-soft: rgba(143, 197, 255, .14);
  --good: #5EC990;   /* AppTheme.success */
  --warm: #E0B15C;   /* the "rarest pick" call-out, the one colour outside AppTheme */

  /* glass + quiet surfaces */
  --glass: rgba(255, 255, 255, .09);
  --glass-edge: rgba(255, 255, 255, .12);
  --glass-lit: inset 0 1px 0 rgba(255, 255, 255, .20);
  --quiet: rgba(255, 255, 255, .045);
  --divider: rgba(255, 255, 255, .07);
  --track: rgba(255, 255, 255, .10);
  --lift: rgba(255, 255, 255, .05);
  --shadow: 0 18px 44px rgba(0, 0, 0, .38);

  /* Exactly two radii, same rule as the app: cards get one, controls the
     other. A third value is always someone eyeballing a corner. */
  --radius: 22px;
  --radius-ctl: 17px;

  /* The hero car's paint, used to tint the home page's top glow. One place,
     one value: Tanzanite Blue II Metallic on the 2027 X5 (G65), sampled as
     the median of a lit door panel in the shipped render (the method and the
     other panel medians are in scripts/site-assets/hero-x5-g65-source.json).
     Not the swatch colour — the chips in the lists come from
     models/swatches.json, read off BMW's own colour chips, so every swatch on
     the site has one source. */
  --hero-paint: #242E3D;

  --mono: ui-monospace, "SF Mono", "Cascadia Code", "JetBrains Mono", Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --display: var(--sans);
}

/* ---------------------------------------------------------------------
 * base
 * ------------------------------------------------------------------- */
* { box-sizing: border-box; }

/* The gradient lives on <html> so it paints the canvas: that leaves a
   z-index:-1 pseudo-element (the home page's paint-tinted glow) free to sit
   above it without a stacking-context fight. */
html {
  overflow-x: hidden;
  color-scheme: dark;
  background:
    radial-gradient(760px 760px at 88% -8%, rgba(62, 142, 224, .36), rgba(62, 142, 224, 0) 70%),
    radial-gradient(720px 720px at -6% 46%, rgba(41, 90, 160, .30), rgba(41, 90, 160, 0) 70%),
    linear-gradient(165deg, #10203A 0%, #0C1830 42%, #0A1122 100%) var(--ground);
  background-attachment: fixed, fixed, fixed;
}
body {
  margin: 0;
  overflow-x: hidden;
  background: transparent;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); }
a:hover { color: #B7D9FF; }
img { max-width: 100%; }

/* One focus treatment for the whole site. */
a:focus-visible,
summary:focus-visible,
details > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

.wrap {
  position: relative;
  min-height: 100vh;
  padding: clamp(18px, 4vw, 34px) clamp(16px, 4vw, 40px) 0;
}
.page { max-width: 940px; margin: 0 auto; }
/* the marketing home breathes wider than a data page */
.page-home { max-width: 1040px; }
/* legal + support read as documents, so they get a measure, not a grid */
.page-prose { max-width: 720px; }

/* On the home page the top glow leans toward the hero car's paint. The paint
   itself is a dark navy, so it is mixed with the accent fill rather than used
   neat: a glow has to lift the corner, not punch a hole in it. The first
   declaration is the pre-color-mix fallback, already mixed by hand. */
.page-home::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(760px 760px at 88% -8%, #325F8E, transparent 68%);
  background: radial-gradient(760px 760px at 88% -8%, color-mix(in srgb, var(--hero-paint) 55%, var(--accent-deep)), transparent 68%);
  opacity: .55;
}

/* The rubric: 12px, 600, uppercase, 1.2px tracking, muted. Used only where
   the app uses it — to LABEL a section (STATUS, THE BUILD, SIMILAR BUILDS,
   THE FLEET). Headings and nav links are sentence case. */
.section-label,
.eyebrow,
.tile .k,
.footer-head,
.scope-banner-label,
.model-card .mc-k,
.segment-card .sg-k,
.route-name {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--ink-2);
}

/* Every quantity on the site is tabular. */
.tile .v, .val, .mc-v, .sg-n, .price-figure, .label-figure,
.rr-pct, .pl-pct, .pl-n, .bs-price, .rung-date, .fleet-meta,
.rarity-head, .jc-steps { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------
 * shared chrome: header nav + footer, on every generated page
 * ------------------------------------------------------------------- */
/* @site-header:start  (build-site.js lifts this block into the model
   dashboards, which do not load site.css, so the header is one source) */
.site-header {
  max-width: 1040px;
  margin: 0 auto 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
  flex-wrap: wrap;
}
.brand {
  display: inline-flex; align-items: center; gap: 12px;
  text-decoration: none; color: var(--ink);
}
.brand img {
  width: 32px; height: 32px; border-radius: 8px; display: block;
  box-shadow: inset 0 0 0 1px var(--glass-edge);
}
.brand-name { font-size: 17px; font-weight: 600; letter-spacing: -.2px; line-height: 1; }

/* align-items matters: the "All models" trigger is a <details>, and under the
   flex default (stretch) it grows to the row height while its <summary> stays
   pinned to the top of that box. Centring makes the details box hug it. */
.site-nav { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.site-nav a,
.site-nav .bt-menu > summary {
  font-size: 15px; font-weight: 500; letter-spacing: 0;
  color: var(--ink-2); text-decoration: none;
  padding: 8px 14px; border-radius: var(--radius-ctl);
  border: 1px solid transparent;
  transition: color .15s ease, background-color .15s ease;
}
/* Block, not flex: the anchors are blockified flex items, so a block summary
   gets the same line box and lands on the same baseline. */
.site-nav .bt-menu > summary { display: block; list-style: none; cursor: pointer; user-select: none; }
.site-nav a:hover,
.site-nav .bt-menu > summary:hover,
.site-nav .bt-menu[open] > summary { color: var(--ink); background: var(--glass); }
.site-nav a[aria-current="page"] { color: var(--ink); background: var(--glass); }

/* The one filled control on the page. accentDeep is an accent FILL, so the
   label on it is the ground colour, never ink. */
.site-nav a.get-app,
a.get-app {
  margin-left: 8px;
  color: var(--ground); background: var(--accent);
  font-weight: 600; border-color: transparent;
}
.site-nav a.get-app:hover { color: var(--ground); background: #B7D9FF; }
@media (max-width: 560px) {
  .site-nav { gap: 2px; }
  .site-nav a, .site-nav .bt-menu > summary { padding: 7px 10px; font-size: 14px; }
  .site-nav a.get-app { margin-left: 2px; }
}
/* @site-header:end */

.site-footer {
  max-width: 1040px;
  margin: 90px auto 0;
  padding: 26px 0 46px;
  border-top: 1px solid var(--divider);
  display: grid;
  gap: 18px 40px;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  align-items: start;
}
.footer-head { margin: 0 0 10px; color: var(--ink-3); }
.site-footer .disclaimer { margin: 0; font-size: 13.5px; color: var(--ink-2); max-width: 52ch; line-height: 1.55; }
.footer-links { display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 0; padding: 0; list-style: none; }
.footer-links a { color: var(--ink-2); text-decoration: none; font-size: 13.5px; }
.footer-links a:hover { color: var(--accent); }
.footer-legal { grid-column: 1 / -1; margin: 0; font-size: 12px; color: var(--ink-3); }

/* ---------------------------------------------------------------------
 * headings + lede
 * ------------------------------------------------------------------- */
.crumbs {
  font-family: var(--mono); font-size: 12px; color: var(--ink-3);
  margin: 0 0 20px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
.crumbs a { color: var(--ink-2); text-decoration: none; }
.crumbs a:hover { color: var(--accent); }

.eyebrow { display: flex; align-items: center; gap: 10px; margin: 0 0 16px; }
.eyebrow::before { content: ""; width: 22px; height: 2px; border-radius: 1px; background: var(--accent-deep); }

h1 {
  font-weight: 700;
  font-size: clamp(34px, 5.4vw, 54px);
  line-height: 1.05; letter-spacing: -1.2px;
  margin: 0 0 18px; text-wrap: balance; max-width: 20ch;
}
.lede { font-size: clamp(16px, 2.2vw, 20px); color: var(--ink-2); max-width: 62ch; margin: 0 0 8px; line-height: 1.45; }
.lede b { color: var(--ink); font-weight: 600; }

/* ---------------------------------------------------------------------
 * glass + quiet surfaces
 * ------------------------------------------------------------------- */
.glass {
  background: var(--glass);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lit);
  border-radius: var(--radius);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}
.quiet { background: var(--quiet); border-radius: var(--radius); }

/* Reduce Transparency: the blur goes, an opaque panel takes its place. */
@media (prefers-reduced-transparency: reduce) {
  .glass, .hero-card, .status-card, .rarity-card, .tile, .model-card, .callout, .prose .note, .notif {
    backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--panel);
  }
  .quiet, .build-sheet { background: rgba(22, 35, 58, .8); }
}

/* ---------------------------------------------------------------------
 * home: hero — one glass card, copy left, a phone tilted off the edge right
 *
 * The card is the frame: `overflow: hidden` on a 22px radius is what crops the
 * phone, so the tilt reads as a device running off the corner rather than a
 * floating rectangle. Everything the reader has to be able to finish (h1,
 * pitch, badges, the sample car's facts) lives inside the card's padding, in
 * the left column; the phone is decoration and is allowed to leave.
 * ------------------------------------------------------------------- */
.hero-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 55%) minmax(0, 45%);
  align-items: start;
  min-height: 560px;
  background: var(--glass);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lit);
  border-radius: var(--radius);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  overflow: hidden;
}
.hero-copy { padding: clamp(26px, 3.4vw, 40px); }
.hero-card h1 { margin: 0 0 14px; max-width: 16ch; }
.hero-pitch { font-size: clamp(17px, 2vw, 20px); color: var(--ink-2); margin: 0 0 22px; line-height: 1.45; max-width: 46ch; }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.hero-note { font-size: 13.5px; color: var(--ink-3); margin: 10px 0 0; }

.hero-sample { margin: 4px 0 0; font-size: 13px; color: var(--ink-3); line-height: 1.5; }

/* ---------------------------------------------------------------------
 * home: the phone, drawn in CSS — no vendor bezel artwork anywhere
 * ------------------------------------------------------------------- */
.hero-stage { position: absolute; top: 0; right: 0; width: 45%; height: 100%; pointer-events: none; }
.phone {
  position: absolute; top: 58px; left: 12%;
  width: 300px; padding: 10px;
  background: rgba(10, 17, 34, .92);
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 44px;
  box-shadow: 0 30px 60px rgba(0, 0, 0, .45);
  /* Tilted back as well as turned: the top-right corner recedes and the
     near edge comes forward, the way a phone lies when set down at an angle.
     Only on desktop; the phone view below stands the device upright. */
  transform: perspective(1400px) rotateX(14deg) rotateY(-28deg) rotate(24deg) translate(88px, 18px);
  transform-origin: 50% 50%;
  /* Promote the phone to its own layer and keep it rasterised at device
     resolution; without these Chrome may draw a transformed layer at a lower
     scale and the screen's text goes soft. */
  will-change: transform;
  backface-visibility: hidden;
}
.phone > img { display: block; width: 100%; height: auto; border-radius: 34px; backface-visibility: hidden; }

/* The two store badges, each at its official 3:1 proportion and drawn on the
   same 120x40 artboard so they render at an identical height side by side.
   Neither is a button — a link wrapping the artwork, so it never picks up our
   own button styling. */
.appstore-badge, .playstore-badge { display: inline-block; line-height: 0; border-radius: 8px; }
.appstore-badge svg, .playstore-badge svg { display: block; height: 54px; width: auto; }
.appstore-badge:focus-visible,
.playstore-badge:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
/* phones: both badges on one row (44px tall = 132px wide each) so the hero
   card does not grow a second badge row under the pitch */
@media (max-width: 560px) {
  .hero-actions { flex-wrap: nowrap; }
  .appstore-badge svg, .playstore-badge svg { height: 44px; }
}


/* Round paint/interior chips, as in the app. `.swatch` (square) stays for the
   bar lists the model pages generate. */
.chip-swatch { display: inline-block; width: 16px; height: 16px; border-radius: 50%; flex: none; }
.chip-swatch.chip-border { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .35); }
.chip-swatch.swatch-none {
  background-image: repeating-linear-gradient(135deg, var(--ink-3) 0 2px, transparent 2px 6px);
  background-color: var(--panel);
}

/* ---------------------------------------------------------------------
 * home: the section label row (label left, figure right)
 * ------------------------------------------------------------------- */
.label-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin: 40px 0 12px;
}
.label-figure { font-family: var(--mono); font-size: 14px; color: var(--ink-2); }

/* ---------------------------------------------------------------------
 * home: the status card
 * ------------------------------------------------------------------- */
.status-card {
  background: var(--glass);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lit);
  border-radius: var(--radius);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  padding: 24px clamp(18px, 3vw, 28px) 20px;
}

/* The six-chapter route strip: a 2px track behind the nodes, success behind
   the car and white 12% ahead of it. */
.route { position: relative; }
.route-track {
  position: absolute; left: 8%; right: 8%; top: 12px; height: 2px; border-radius: 1px;
}
.route-nodes { display: flex; align-items: flex-start; }
.route-node {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  flex: 1 1 0; position: relative; z-index: 1; text-align: center;
}
.route-node svg { display: block; }
.route-node.is-now .route-name { color: var(--accent); }
.route-node.is-next .route-name { color: var(--ink-3); }

.stage-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px; margin-top: 26px; }
.stage-now { font-size: clamp(24px, 3.4vw, 32px); font-weight: 700; letter-spacing: -.4px; margin: 0; }
.stage-code { font-family: var(--mono); font-size: 15px; color: var(--ink-3); }
.day-chip {
  margin-left: auto; font-size: 14px; font-weight: 600; color: var(--accent);
  background: var(--accent-soft); border: 1px solid rgba(143, 197, 255, .35);
  padding: 5px 12px; border-radius: 999px; white-space: nowrap;
}
.stage-line { font-size: 17px; color: var(--ink-2); margin: 6px 0 18px; }

.rung {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 0; border-top: 1px solid var(--divider);
}
.rung svg { flex: none; }
.rung-name { font-size: 17px; font-weight: 500; color: var(--ink); }
.rung-code { font-family: var(--mono); font-size: 13px; color: var(--ink-3); }
.rung-date { margin-left: auto; font-size: 15px; color: var(--ink-2); white-space: nowrap; }
.rung.is-now .rung-name { color: var(--accent); }
.rung.is-next .rung-name { color: var(--ink-2); }
.rung.is-next .rung-date { color: var(--ink-3); }

.status-foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px 16px; padding-top: 16px; border-top: 1px solid var(--divider);
}
.live-dot { display: flex; align-items: center; gap: 8px; font-size: 15px; color: var(--good); }
.live-dot::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--good); flex: none; }
.status-foot a { font-size: 15px; font-weight: 600; text-decoration: none; }

/* ---------------------------------------------------------------------
 * home: the journey rail (six chapters down one continuous 2px line)
 * ------------------------------------------------------------------- */
.journey { margin-top: 12px; }
.journey-intro { font-size: 17px; color: var(--ink-2); margin: 0 0 22px; max-width: 62ch; }
.jc { display: flex; gap: 22px; }
.jc-rail { display: flex; flex-direction: column; align-items: center; width: 24px; flex: none; }
.jc-rail svg { display: block; }
.jc-line { width: 2px; flex: 1 1 auto; margin-top: 6px; border-radius: 1px; background: var(--track); }
.jc.is-done .jc-line { background: rgba(94, 201, 144, .55); }
.jc.is-now .jc-line { background: linear-gradient(180deg, var(--accent) 0%, rgba(255, 255, 255, .12) 100%); }
.jc-body { flex: 1 1 auto; padding: 0 0 26px; }
.jc-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px; }
.jc-name { font-size: 22px; font-weight: 600; letter-spacing: -.2px; margin: 0; }
.jc.is-next .jc-name { color: var(--ink-2); }
.jc-steps { font-size: 13px; color: var(--ink-3); }
.jc-quote { font-size: 16px; color: var(--ink-2); margin: 6px 0 0; max-width: 62ch; line-height: 1.5; }

/* ---------------------------------------------------------------------
 * home: two-column feature blocks
 * ------------------------------------------------------------------- */
.split {
  display: grid; grid-template-columns: minmax(0, 40fr) minmax(0, 60fr);
  gap: clamp(24px, 4vw, 48px); align-items: start; margin-top: clamp(44px, 6vw, 72px);
}
.split-even { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.split h2 { margin: 10px 0 12px; }
.split-copy p { font-size: 16px; color: var(--ink-2); margin: 0 0 12px; max-width: 52ch; line-height: 1.55; }
.split-copy p:last-child { margin-bottom: 0; }
.split-side { display: flex; flex-direction: column; gap: 12px; }

h2 { font-size: clamp(24px, 3vw, 34px); font-weight: 700; letter-spacing: -.5px; margin: 0; }

/* ---------------------------------------------------------------------
 * home: the Similar Builds card
 * ------------------------------------------------------------------- */
.rarity-card {
  background: var(--glass);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lit);
  border-radius: var(--radius);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  padding: 24px clamp(18px, 3vw, 28px);
}
.rarity-head { font-size: clamp(22px, 3vw, 28px); font-weight: 700; letter-spacing: -.4px; margin: 0; }
.rarity-sub { font-size: 16px; color: var(--ink-2); margin: 4px 0 14px; }
.rr { padding: 12px 0 10px; border-top: 1px solid var(--divider); }
.rr-line { display: flex; align-items: center; gap: 12px; }
.rr-k { font-size: 12px; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase; color: var(--ink-3); width: 74px; flex: none; }
.rr-name { font-size: 16px; font-weight: 500; display: flex; align-items: center; gap: 10px; min-width: 0; }
.rr-pct { margin-left: auto; font-size: 17px; font-weight: 600; }
.rr-note { font-size: 13px; color: var(--ink-3); width: 104px; text-align: right; flex: none; }
.rr.is-rare .rr-pct { color: var(--warm); }
.rr.is-rare .rr-note { color: var(--warm); }
.rr-bar { margin-top: 9px; height: 4px; border-radius: 2px; background: var(--track); overflow: hidden; }
.rr-bar span { display: block; height: 100%; border-radius: 2px; background: var(--accent); min-width: 2px; }
.rr.is-rare .rr-bar span { background: var(--warm); }
.rarity-foot { font-size: 14px; color: var(--ink-3); margin: 14px 0 0; line-height: 1.5; }

/* ---------------------------------------------------------------------
 * home: the build sheet (quiet tier) + gallery tiles
 * ------------------------------------------------------------------- */
.build-sheet { background: var(--quiet); border-radius: var(--radius); padding: 4px clamp(16px, 2.5vw, 24px); }
.bs-row { display: flex; align-items: center; gap: 14px; padding: 15px 0; border-top: 1px solid var(--divider); }
.bs-row:first-child { border-top: none; }
.bs-k { font-size: 14px; color: var(--ink-3); width: 92px; flex: none; }
.bs-v { font-size: 16px; font-weight: 500; min-width: 0; }
.bs-sub { display: block; font-size: 13.5px; font-weight: 400; color: var(--ink-3); margin-top: 2px; }
.bs-price { margin-left: auto; font-size: 15px; color: var(--ink-2); white-space: nowrap; }
.bs-wheel { width: 54px; height: 54px; border-radius: 12px; display: block; flex: none; background: var(--lift); }

.gallery-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-top: 14px; }
.gt {
  background: var(--quiet); border-radius: var(--radius-ctl);
  aspect-ratio: 4 / 3; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px;
  font-size: 13px; color: var(--ink-3); overflow: hidden; text-align: center; padding: 8px;
}
.gt img { width: 68%; height: auto; display: block; }
/* A real brochure frame fills its tile; a labelled tile stays a label. */
.gt-photo { padding: 0; }
.gt-photo img { width: 100%; height: 100%; object-fit: cover; }

/* ---------------------------------------------------------------------
 * home: notification cards
 * ------------------------------------------------------------------- */
.notif-stack { display: flex; flex-direction: column; gap: 12px; }
.notif {
  display: flex; gap: 12px; align-items: flex-start;
  background: rgba(22, 35, 58, .92); border: 1px solid rgba(255, 255, 255, .10);
  border-radius: 18px; padding: 14px 16px; box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
}
.notif img { width: 36px; height: 36px; border-radius: 9px; display: block; flex: none; }
.notif-text { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.notif-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.notif-app { font-size: 13px; color: var(--ink-2); }
.notif-when { font-size: 12px; color: var(--ink-3); }
.notif-title { font-size: 16px; font-weight: 600; }
.notif-body { font-size: 14px; color: var(--ink-2); }
/* The two older ones sit back, so the newest reads first. */
.notif-2 { opacity: .8; transform: scale(.97); }
.notif-3 { opacity: .6; transform: scale(.94); }

/* ---------------------------------------------------------------------
 * home: the fleet paint list
 * ------------------------------------------------------------------- */
.fleet-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 10px 24px; margin: 0 0 20px;
}
.fleet-head h2 { margin-top: 8px; }
.fleet-meta { font-size: 15px; color: var(--ink-2); }
.paint-list { margin: 0; }
.pl-row { display: flex; align-items: center; gap: 12px; padding: 13px 0; border-top: 1px solid var(--divider); }
.pl-row:first-child { border-top: none; }
.pl-name { font-size: 16px; font-weight: 500; min-width: 0; }
.pl-yours {
  font-size: 12px; font-weight: 600; color: var(--accent);
  background: var(--accent-soft); padding: 2px 9px; border-radius: 999px; flex: none;
}
.pl-bar { margin-left: auto; width: 110px; height: 4px; border-radius: 2px; background: var(--track); position: relative; flex: none; }
.pl-bar span { position: absolute; inset: 0 auto 0 0; border-radius: 2px; background: var(--accent); min-width: 2px; }
.pl-pct { width: 42px; text-align: right; font-size: 16px; font-weight: 600; flex: none; }
.pl-n { width: 46px; text-align: right; font-size: 14px; color: var(--ink-3); flex: none; }
.fleet-note { font-size: 14px; color: var(--ink-3); margin: 18px 0 0; }

/* ---------------------------------------------------------------------
 * home: price / honesty strip — statements, not cards
 * ------------------------------------------------------------------- */
.price-strip {
  margin-top: clamp(44px, 6vw, 72px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 24px clamp(24px, 4vw, 44px);
  padding: 28px 0;
  border-top: 1px solid var(--divider);
  border-bottom: 1px solid var(--divider);
}
.price-item h3 { font-size: 22px; font-weight: 700; margin: 0 0 6px; letter-spacing: -.2px; }
.price-item p { margin: 0; font-size: 15px; color: var(--ink-2); line-height: 1.5; }
.price-item .price-figure { color: var(--good); }
/* Hairline dividers between the statements, not around them. */
.price-strip .price-item + .price-item { border-left: 1px solid var(--divider); padding-left: clamp(20px, 3vw, 36px); }

/* ---------------------------------------------------------------------
 * stat tiles (model hubs + segment pages)
 * ------------------------------------------------------------------- */
.tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px; margin: 34px 0 10px;
}
.tile {
  background: var(--glass); border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lit);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border-radius: var(--radius); padding: 20px 22px 18px;
}
.tile .k { margin: 0 0 10px; color: var(--ink-3); }
.tile .v { font-size: 32px; font-weight: 700; letter-spacing: -.5px; line-height: 1; }
.tile .s { font-size: 13px; color: var(--ink-2); margin-top: 8px; }
.tile .v .u { font-size: 16px; font-weight: 600; color: var(--ink-2); margin-left: 2px; }

/* ---------------------------------------------------------------------
 * data sections + bar chart
 * ------------------------------------------------------------------- */
section { margin-top: 48px; }
.sec-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 6px; padding-bottom: 14px; border-bottom: 1px solid var(--divider);
}
.sec-head h2 { font-size: 24px; letter-spacing: -.3px; }
.sec-note { font-size: 12.5px; color: var(--ink-3); text-align: right; }

.chart { margin-top: 22px; display: flex; flex-direction: column; gap: 11px; }
.row { display: grid; grid-template-columns: 190px 1fr; gap: 16px; align-items: center; }
.row .label { font-size: 13.5px; color: var(--ink); text-align: right; line-height: 1.25; }
.row .label .sub { display: block; font-family: var(--mono); font-size: 11px; color: var(--ink-3); margin-top: 2px; }
.track { position: relative; height: 30px; background: var(--quiet); border-radius: 10px; overflow: hidden; }
.fill { position: absolute; inset: 0 auto 0 0; height: 100%; background: var(--accent-deep); border-radius: 10px; min-width: 3px; }
.fill.swatch-none {
  background-image: repeating-linear-gradient(135deg, var(--ink-3) 0 2px, transparent 2px 9px);
  background-color: var(--panel); opacity: .55;
}
.val {
  position: absolute; top: 50%; transform: translateY(-50%);
  font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap;
}
/* A label sitting on the fill has no idea what colour is underneath it: the
   accent on a take-rate bar, or any paint BMW sells on a colour bar — Alpine
   White and Black Sapphire both reach the far end. White plus a dark halo is
   the one pair that survives all of them. */
.val.val-inside { color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .8); }
.val .pct { font-weight: 700; }
.val .n { color: var(--ink-3); font-weight: 500; margin-left: 7px; font-family: var(--mono); font-size: 12px; }
.val-inside .n { color: rgba(255, 255, 255, .8); }

.callout {
  background: var(--glass); border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lit);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border-radius: var(--radius);
  padding: 18px 20px; margin-top: 22px;
  display: flex; gap: 14px; align-items: flex-start;
}
.callout .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); margin-top: 7px; flex: none; }
.callout p { margin: 0; font-size: 14px; color: var(--ink-2); }
.callout b { color: var(--ink); font-weight: 600; }

.tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.tag {
  font-size: 12.5px; color: var(--ink-2);
  background: var(--quiet); border: 1px solid var(--glass-edge);
  border-radius: 999px; padding: 7px 14px; display: inline-flex; align-items: center;
}
.tag::before {
  content: ""; display: inline-block; width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent-deep); margin-right: 8px; flex: none;
}

details.detail { margin-top: 20px; }
details.detail > summary {
  font-size: 14px; font-weight: 600; color: var(--accent); cursor: pointer;
  list-style: none; display: inline-flex; align-items: center; gap: 8px; padding: 8px 0;
}
details.detail > summary::-webkit-details-marker { display: none; }
details.detail > summary::before { content: "+"; font-size: 15px; }
details.detail[open] > summary::before { content: "\2013"; }

.scroll-x { width: 100%; overflow-x: auto; }

/* the per-page data note that closes model + segment pages */
footer.data-note {
  margin-top: 56px; padding-top: 22px; border-top: 1px solid var(--divider);
  font-size: 12.5px; color: var(--ink-3); line-height: 1.75;
}
footer.data-note b { color: var(--ink-2); }
footer.data-note a { color: var(--ink-2); }

/* ---------------------------------------------------------------------
 * model cards (home fleet section) + swatch chip
 * ------------------------------------------------------------------- */
.model-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px; margin-top: 0;
}
.model-card {
  display: block; text-decoration: none; color: inherit;
  background: var(--glass); border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lit);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border-radius: var(--radius);
  padding: 20px 22px 18px;
  transition: transform .15s ease, border-color .15s ease;
}
.model-card:hover { border-color: rgba(143, 197, 255, .45); transform: translateY(-2px); }
.model-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.model-card .mc-name { font-size: 23px; font-weight: 600; letter-spacing: -.2px; margin: 0 0 2px; }
.model-card .mc-full { font-size: 13px; color: var(--ink-3); margin: 0 0 14px; }
.model-card .mc-stats {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px;
  padding-top: 14px; border-top: 1px solid var(--divider);
}
.model-card .mc-stat .mc-v { font-size: 19px; font-weight: 700; }
.model-card .mc-stat .mc-k { font-size: 10.5px; letter-spacing: 1px; color: var(--ink-3); margin-top: 2px; }
.model-card .mc-color { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 13px; color: var(--ink-2); }
.model-card .mc-updated { font-size: 12px; color: var(--ink-3); margin-top: 12px; }
.model-card .mc-cta { font-size: 13px; font-weight: 600; color: var(--accent); margin-top: 14px; }

.swatch {
  display: inline-block; width: 13px; height: 13px; border-radius: 4px; flex: none;
  box-shadow: inset 0 0 0 1px rgba(128, 128, 128, .35);
}
.swatch.swatch-none {
  background-image: repeating-linear-gradient(135deg, var(--ink-3) 0 2px, transparent 2px 6px);
  background-color: var(--panel);
}

/* the quieter "we also track these" line under the two featured fleets */
.more-models { margin: 18px 2px 0; font-size: 13.5px; color: var(--ink-3); line-height: 1.9; }
.more-models a { color: var(--ink-2); text-decoration: none; border-bottom: 1px solid var(--hair); }
.more-models a:hover { color: var(--accent); border-color: var(--accent); }

/* ---------------------------------------------------------------------
 * model hub: "browse by year & trim" segment grid
 * ------------------------------------------------------------------- */
.segment-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px; margin-top: 22px;
}
.segment-card {
  display: block; text-decoration: none; color: inherit;
  background: var(--quiet); border: 1px solid transparent; border-radius: var(--radius);
  padding: 16px 18px 15px;
  transition: transform .15s ease, border-color .15s ease;
}
a.segment-card:hover { border-color: rgba(143, 197, 255, .45); transform: translateY(-2px); }
a.segment-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.segment-card.segment-card-locked { opacity: .62; }
.segment-card .sg-title { font-size: 18px; font-weight: 600; margin: 0 0 12px; }
.segment-card .sg-title .sg-variant { color: var(--ink-2); }
.segment-card .sg-stats { display: flex; align-items: baseline; gap: 7px; }
.segment-card .sg-n { font-size: 20px; font-weight: 700; }
.segment-card .sg-k { font-size: 10.5px; letter-spacing: 1px; color: var(--ink-3); }
.segment-card .sg-color { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: 13px; color: var(--ink-2); }
.segment-card .sg-color-pct { font-family: var(--mono); color: var(--ink-3); }
.segment-card .sg-cta { font-size: 12.5px; font-weight: 600; color: var(--accent); margin-top: 12px; }
.segment-card .sg-locked-note { font-size: 12px; color: var(--ink-3); margin-top: 12px; }
.sg-unknown-note { font-size: 12.5px; color: var(--ink-3); margin: 14px 2px 0; }

.scope-banner {
  margin-top: 44px; padding: 14px 18px; border-radius: var(--radius-ctl);
  background: var(--quiet);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px;
}
.scope-banner-label { color: var(--accent); }
.scope-banner-note { font-size: 13px; color: var(--ink-2); }

/* ---------------------------------------------------------------------
 * segment page: zero-JS pill nav between sibling year/trim pages
 * ------------------------------------------------------------------- */
.pill-nav { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 26px; }
.pill-nav .pill {
  font-size: 13px; color: var(--ink-2); text-decoration: none;
  background: var(--lift); border: 1px solid var(--glass-edge); border-radius: 999px;
  padding: 7px 14px; display: inline-flex; align-items: center;
  transition: border-color .15s ease, color .15s ease;
}
.pill-nav a.pill:hover { border-color: rgba(143, 197, 255, .45); color: var(--accent); }
.pill-nav .pill.pill-active {
  background: var(--accent-soft); border-color: rgba(143, 197, 255, .45); color: var(--accent); font-weight: 600;
}

/* ---------------------------------------------------------------------
 * prose pages: privacy + support
 * ------------------------------------------------------------------- */
.prose { margin-top: 34px; }
.prose h2 {
  font-size: 22px; font-weight: 700; letter-spacing: -.3px; color: var(--ink);
  margin: 44px 0 12px; padding: 0; border: 0;
}
.prose h2:first-of-type { margin-top: 0; }
.prose h3 { font-size: 19px; font-weight: 600; letter-spacing: -.2px; margin: 28px 0 8px; }
.prose p, .prose li { font-size: 16px; color: var(--ink-2); }
.prose p { margin: 0 0 14px; }
.prose ul { margin: 0 0 14px; padding-left: 20px; }
.prose li { margin-bottom: 8px; }
.prose b, .prose strong { color: var(--ink); font-weight: 600; }
.prose .effective {
  font-family: var(--mono); font-size: 12px; color: var(--ink-3);
  margin: 0 0 30px; padding-bottom: 18px; border-bottom: 1px solid var(--divider);
}
.prose .note {
  background: var(--glass); border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-lit);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border-radius: var(--radius);
  padding: 18px 20px; margin: 0 0 14px;
}
.prose .note p:last-child { margin-bottom: 0; }
.faq h3 { margin-top: 30px; }

/* ---------------------------------------------------------------------
 * status-code pages: the pipeline flow list
 * ------------------------------------------------------------------- */
.stage-flow { list-style: none; margin: 0; padding: 0; font-size: 14px; }
.stage-flow li {
  display: flex; gap: 12px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px solid var(--divider);
}
.stage-flow li:last-child { border-bottom: none; }
.stage-flow .sf-code { font-family: var(--mono); color: var(--ink-3); min-width: 38px; }
.stage-flow a { text-decoration: none; color: var(--ink-2); }
.stage-flow a:hover { color: var(--accent); }
.stage-flow li.sf-now { color: var(--accent); }
.stage-flow li.sf-now .sf-code { color: var(--accent); }
.stage-flow .sf-days { margin-left: auto; color: var(--ink-3); font-size: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.stage-prevnext { display: flex; justify-content: space-between; gap: 16px; margin: 28px 0 0; font-size: 15px; }
.stage-prevnext a { text-decoration: none; }

/* ---------------------------------------------------------------------
 * responsive — single column under 900px, no horizontal scroll at 390px
 * ------------------------------------------------------------------- */
@media (max-width: 900px) {
  .split, .split-even { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .site-footer { grid-template-columns: minmax(0, 1fr); }
  .price-strip .price-item + .price-item { border-left: 0; padding-left: 0; }

  /* One column: the phone stands upright under the copy, centred, and the
     card's own bottom edge cuts it off. `.hero-stage` goes back into flow with
     a short fixed height, so it is the stage — not the phone — that sets where
     the card ends, and the phone spills past it into the crop. */
  .hero-card { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .hero-copy { padding-bottom: 4px; }
  .hero-stage { position: relative; width: 100%; height: 150px; }
  .phone {
    top: 0; left: 50%; width: 240px;
    transform: translateX(-50%);
    box-shadow: 0 20px 40px rgba(0, 0, 0, .45);
  }
}
@media (max-width: 620px) {
  /* Every line of the copy still has to fit above the crop, so the phone strip
     is the only part that gives. It shows the top of the device and nothing
     more, which is all the tilt was ever doing on desktop. */
  .hero-copy { padding: 22px 18px 2px; }
  .hero-pitch { margin-bottom: 18px; }
  .hero-sample { margin-top: 4px; }
  .hero-stage { height: 118px; }
  .row { grid-template-columns: 112px 1fr; gap: 11px; }
  .row .label { font-size: 12px; }
  h1 { max-width: none; }
  .sec-head { flex-direction: column; align-items: flex-start; gap: 6px; }
  .sec-note { text-align: left; }
  .gallery-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .pl-bar { width: 64px; }
  .rr-note { display: none; }
  .rr-k { width: 62px; }
  .bs-k { width: 74px; }
  .day-chip { margin-left: 0; }
  /* Six chapter names across a phone: the rubric's 1.2px tracking is what
     runs them together, so it goes first, then the size. */
  .route-node { gap: 6px; }
  .route-node svg { width: 20px; height: 20px; }
  .route-track { top: 9px; left: 6%; right: 6%; }
  .route-name { font-size: 9px; letter-spacing: .2px; }
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
  .notif-2, .notif-3 { transform: none; }
}

/* models dropdown (generated) */

  .bt-menu { position: relative; display: inline-block; }
  .bt-menu summary { list-style: none; cursor: pointer; color: #AAB8CC; font-size: 15px; user-select: none; }
  .bt-menu summary::-webkit-details-marker { display: none; }
  .bt-menu summary::after { content: " \25BE"; font-size: 11px; }
  .bt-menu summary:hover, .bt-menu[open] summary { color: #EAF1FA; }
  .bt-menu-list { position: absolute; right: 0; top: calc(100% + 12px); z-index: 60; min-width: 220px;
    max-height: 62vh; overflow: auto; background: #16233A; border: 1px solid rgba(255,255,255,.12); border-radius: 17px;
    padding: 8px; box-shadow: 0 18px 44px rgba(0,0,0,.5); display: grid; }
  .bt-menu-list a { display: flex; justify-content: space-between; gap: 18px; padding: 9px 11px;
    border-radius: 11px; color: #EAF1FA; text-decoration: none; font-size: 14px; white-space: nowrap; }
  .bt-menu-list a span { color: #7E8CA0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
  .bt-menu-list a:hover { background: rgba(255,255,255,.09); color: #8FC5FF; }
  .bt-menu-list a.bt-cur { color: #8FC5FF; }
