/* ============================================================
   Bumpr — Direction 1 · "tracked like a flight", rendered in the
   Bumpr Design System (Desktop/Bumpr Design System/DESIGN.md).
   Flat cream / orange / roast fields. Giant lowercase Sora. Money in
   JetBrains Mono. Nothing floats: no shadows, no glass, no pills.
   Depth is ground inversion → hairline → scrim, in that order.
   ============================================================ */

:root {
  /* colours — verbatim from DESIGN.md */
  --primary: #FF6A1A;
  --primary-deep: #E4530A;
  --primary-wash: rgba(255,106,26,0.12);
  --cream: #FFF8EE;
  --cream-dim: #F4E7D6;
  --roast: #2E1502;
  --roast-soft: #4A1D03;
  --clay: #7A3A10;
  --sand: #C9A98F;
  --hairline: rgba(122,58,16,0.16);
  --hairline-on-dark: rgba(201,169,143,0.24);

  /* type — three families, three jobs */
  --sora: "Sora", system-ui, sans-serif;
  --inter: "Inter", system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, monospace;

  /* radii — chosen by what the object is */
  --r-mark: 3px;
  --r-chip: 9px;
  --r-control: 12px;
  --r-frame: 22px;
  --r-block: 24px;
  --r-full: 999px;

  /* rhythm */
  --s-xs: 4px; --s-sm: 8px; --s-md: 12px; --s-lg: 16px;
  --s-xl: 20px; --s-xxl: 24px; --s-xxxl: 32px;

  --page: 1200px;
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

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

/* The hidden attribute always wins, so links parked until their URL exists stay out of the page. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; overflow-x: clip; }

/* Phone browser bars — measured on iPhone 17 Pro / iOS 26.3, 2026-09-12.
   iOS 26 Safari paints two strips the page cannot reach: viewport-fit and env(safe-area-inset-*) do
   nothing here, and even 100lvh stops 120pt short of the screen. What it paints there:
     · the strip behind the status bar takes <body>'s background-colour;
     · the strip behind its own bottom bar takes the page's real pixels at that edge;
     · but a fixed or sticky element carrying a background at either edge overrides both and the bar
       turns into a solid block. That is why .hero-pin has no background of its own.
   So <main> carries the page colour, which frees <body> to be nothing but a signal, and script.js
   writes data-strip on <body> for whatever section is under the top of the screen. The rules live in
   this linked stylesheet, not in inline styles, which older iOS ignored.
   See ~/.claude/skills/mobile-browser-bars. */
html, body { background: var(--cream); }
main { background: var(--cream); }
body[data-strip="mist"]   { background: #F6F1E7; } /* measured: the hero photograph's first rendered row */
body[data-strip="cream"]  { background: var(--cream); }
body[data-strip="dim"]    { background: var(--cream-dim); }
body[data-strip="roast"]  { background: var(--roast); }
body[data-strip="orange"] { background: var(--primary); }

body {
  font-family: var(--inter);
  background: var(--cream);
  color: var(--roast);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  /* No overflow-x here: it would make <body> a scroll container and break
     position:sticky for the nav and the pinned hero. html's overflow-x:clip
     already holds the horizontal edge. */
}

/* Browser surfaces carry the palette too. */
::selection { background: var(--primary); color: var(--roast); }
body { scrollbar-width: thin; scrollbar-color: var(--sand) var(--cream); }
body::-webkit-scrollbar { width: 10px; }
body::-webkit-scrollbar-track { background: var(--cream); }
body::-webkit-scrollbar-thumb { background: var(--sand); border-radius: 5px; border: 2px solid var(--cream); }

:focus-visible { outline: 2px solid var(--roast); outline-offset: 3px; border-radius: var(--r-chip); }
.night :focus-visible { outline-color: var(--cream); }

img { max-width: 100%; display: block; }
a { color: inherit; }
b, strong { font-weight: 700; }

/* Every countable figure. */
.fig { font-family: var(--mono); font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }

.skip-link {
  position: absolute; left: 16px; top: -60px; z-index: 100;
  background: var(--roast); color: var(--cream);
  padding: 10px 18px; border-radius: var(--r-control); text-decoration: none;
  font-family: var(--sora); font-weight: 700;
  transition: top .2s;
}
.skip-link:focus { top: 12px; }

.wrap { max-width: var(--page); margin: 0 auto; padding: 0 var(--s-xl); }

/* ---------------- Type roles ---------------- */

.hero-type {
  font-family: var(--sora);
  font-weight: 800;
  font-size: clamp(2.5rem, 6.2vw, 5.25rem);
  line-height: 1.05;
  letter-spacing: -0.035em;
  text-wrap: balance;
}
.display {
  font-family: var(--sora);
  font-weight: 800;
  font-size: clamp(2.125rem, 4vw, 3.1rem); /* 34–50px: the ≥34 tracking band */
  line-height: 1.06;
  letter-spacing: -0.035em;
  text-wrap: balance;
}
.title {
  font-family: var(--sora);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.2;
  letter-spacing: -0.02em;
}
.label {
  font-family: var(--inter);
  font-weight: 700;
  font-size: 11px;
  line-height: 1.2;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.prose { font-weight: 400; line-height: 1.6; }

/* ---------------- Header band ----------------
   A band, never a floating pill. Sticky so the action stays reachable;
   the hairline caps it. */

.navwrap {
  position: sticky; top: 0; z-index: 50;
  background: var(--primary); /* live mode 2026-09-04: the header is the top of the orange ask field */
  padding: 10px 0; /* the capsule's breathing room lives on the band, so nothing collapses through it */
}
/* The nav is a compact white capsule centred on the orange band (chosen in
   live mode 2026-09-04): orange wordmark, roast links, roast stamp. Capsule
   radius and white are the user's calls; it carries no shadow, so it sits in
   the field rather than floating over the page. */
.nav {
  width: fit-content; max-width: calc(100% - 40px); margin: 0 auto;
  height: 56px; padding: 0 6px 0 22px;
  display: flex; align-items: center; gap: 28px;
  background: #FFFFFF; color: var(--roast);
  border-radius: var(--r-full);
}
.nav-logo { display: flex; align-items: center; height: 48px; }
.nav-logo img { width: 84px; height: auto; }
.nav-links { display: flex; gap: 22px; font-family: var(--sora); font-weight: 700; font-size: 15px; letter-spacing: -0.02em; }
.nav-links a { text-decoration: none; padding: 14px 0; transition: color .15s; }
.nav-links a:hover { color: var(--clay); }
.nav .stamp { margin-left: 0; background: var(--roast); color: var(--cream); border-radius: var(--r-full); min-height: 44px; padding: 0 20px; }
.nav .stamp:hover { background: var(--roast-soft); }

/* The stamp: the system's only small solid control. Roast on orange. */
.stamp {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 0 18px;
  background: var(--primary); color: var(--roast);
  font-family: var(--sora); font-weight: 700; font-size: 15px; letter-spacing: -0.02em;
  border-radius: var(--r-control);
  text-decoration: none; border: 0; cursor: pointer;
  transition: background .15s;
}
.stamp:hover { background: var(--primary-deep); }
.stamp:active { background: var(--primary-deep); }
.stamp-sm { min-height: 28px; padding: 0 10px; font-size: 12.5px; letter-spacing: 0; border-radius: var(--r-chip); }

/* ---------------- Ask field (hero) ----------------
   Full-bleed orange. Roast ink. The page below it is the answer. */

.hero {
  background: var(--primary);
  color: var(--roast);
  padding: clamp(48px, 8vw, 96px) 0 clamp(40px, 6vw, 72px);
}
.hero .wrap { display: flex; flex-direction: column; align-items: flex-start; }
.hero-sub {
  margin-top: var(--s-xxl);
  max-width: 56ch;
  font-size: 17px; font-weight: 500; line-height: 1.5;
  color: var(--roast);
}
.hero-facts {
  margin-top: var(--s-xxxl);
  display: flex; flex-wrap: wrap; gap: 6px var(--s-lg);
  font-family: var(--mono); font-weight: 700; font-size: 12.5px; letter-spacing: -0.02em;
  color: var(--roast-soft);
  list-style: none;
}
.hero-facts li { white-space: nowrap; }
.hero-facts li:not(:last-child)::after { content: "·"; margin-left: var(--s-lg); }

/* ---------------- Pinned stage sequence ----------------
   One tall section, three stage-heights of travel: Browse (morning) →
   Book (golden hour) → The bump (night). A photographed hand holds the
   coded screen; full-bleed villa grounds cross-fade behind it; the caption
   and the dock live in a cream band at the foot, in flow, so nothing can
   ever overlap the viewport. Stage 2's scrim lands on roast so .night
   continues seamlessly. */

.hero-seq { position: relative; height: 370vh; z-index: 1; background: var(--roast); }

.hero-pin {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: hidden;
  display: flex; flex-direction: column; align-items: center;
  background: var(--roast);
}

/* Phones: the hero's roast is painted as a gradient instead of a colour. It looks identical on screen.
   iOS 26 Safari reads only background-COLOUR when it decides what to put behind the status bar, taking
   the first solid one it finds under that edge — so declared as a colour, this roast wore through the
   strip for the whole hero, dark over the pale morning photograph. As a gradient Safari skips it, the
   strip falls through to <body> (script.js keeps that matched to the section on screen), and the strip
   behind Safari's own bottom bar shows the photograph's real pixels. Measured iPhone 17 Pro / iOS 26.3. */
@media (max-width: 720px) {
  html .hero-seq, html .hero-pin, html .hero-ground {
    background-color: transparent;
    background-image: linear-gradient(var(--roast), var(--roast));
  }
}

.hero-ground { position: absolute; inset: 0; z-index: 0; background: var(--roast); }
.hero-ground i {
  position: absolute; inset: 0; display: block;
  background-size: cover; background-position: center;
  opacity: 0; transition: opacity .8s ease;
}
.hero-ground i.is-on { opacity: 1; }
.hero-ground .g0 { background-image: url("../assets/generated/hero-bg-morning.jpg?v=3"); }
.hero-ground .g1 { background-image: url("../assets/generated/hero-bg-golden.jpg?v=3"); }
.hero-ground .g2 { background-image: url("../assets/generated/hero-bg-night.jpg?v=3"); }
.hero-ground i::after { content: ""; position: absolute; inset: 0; }
/* Scrims — the one place a gradient is allowed: over photography, so type can sit on it. */
.hero-ground .g0::after { background: linear-gradient(180deg, rgba(255,248,238,.10) 0%, rgba(255,248,238,0) 30%, rgba(46,21,2,.16) 100%); }
.hero-ground .g1::after { background: linear-gradient(180deg, rgba(255,248,238,.06) 0%, rgba(255,248,238,0) 30%, rgba(46,21,2,.28) 100%); }
.hero-ground .g2::after { background: linear-gradient(180deg, rgba(46,21,2,.36) 0%, rgba(46,21,2,.14) 40%, var(--roast) 96%); }

.hero-stage {
  position: relative; z-index: 2;
  width: min(1140px, 100%);
  margin: auto 0 0;
  display: flex; justify-content: center;
}

/* ----- The hand + coded screen composite ----- */

/* The phone sits 28.5% into the crop, so the whole composite shifts right
   by 21.5% of its own width to center the glass; the arm then runs out of
   the bottom of the pin (negative margin, clipped by overflow) and the mask
   fades the raster's lower and right edges so no crop line ever floats. */
.handwrap {
  position: relative;
  height: min(76svh, 720px);
  aspect-ratio: 1366 / 2018;
  transform: translateX(21.5%);
  margin-bottom: -18svh;
}
.hand {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain;
  -webkit-mask-image:
    linear-gradient(to bottom, #000 86%, transparent 99%),
    linear-gradient(to right, #000 84%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to bottom, #000 86%, transparent 99%),
    linear-gradient(to right, #000 84%, transparent 100%);
  mask-composite: intersect;
}

/* The screen quad inside the hand raster, as fractions of the rendered box.
   Tuned to the shipped asset — retune these four numbers if it's regenerated. */
.screen-fit {
  position: absolute;
  left: 10.18%; top: 2.63%; width: 36.68%; height: 53.47%;
  overflow: hidden;
  background: #000; /* the glass, not a UI colour */
  z-index: 2;
}
.island {
  position: absolute; z-index: 5;
  top: 2.6%; left: 50%; transform: translateX(-50%);
  width: 32%; height: 3.2%;
  background: #000; border-radius: var(--r-full);
}
/* The app screens are laid out at 264px (≈0.68 of a 390pt phone), so every
   app radius below is the DESIGN.md value × 0.68: block 24→16, frame 22→15,
   control 12→8, chip 9→6. */
.screen-base { position: absolute; top: 0; left: 0; width: 264px; height: 572px; transform-origin: 0 0; }

.scr {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  opacity: 0; transform: translateX(14px);
  transition: opacity .5s ease, transform .6s var(--ease-out);
  pointer-events: none;
  font-family: var(--inter);
  -webkit-font-smoothing: antialiased;
}
.scr.is-live { opacity: 1; transform: none; }

.bw-status, .bk-status, .bp-status {
  position: absolute; top: 8px; left: 15px; z-index: 4;
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.bw-status, .bk-status { color: var(--roast); }
.bp-status { color: var(--cream); }

/* Scene 0 · Browse — the ask field, the grid, the dock */
.scr-browse { background: var(--cream); }
.bw-orange { background: var(--primary); padding: 28px 15px 14px; }
.bw-toprow { display: flex; align-items: center; justify-content: space-between; }
.bw-mark { width: 52px; height: auto; }
.bw-search {
  display: inline-flex; align-items: center; gap: 4px;
  height: 24px; padding: 0 9px;
  background: var(--cream-dim); color: var(--roast);
  font-family: var(--sora); font-size: 10px; font-weight: 700;
  border-radius: 6px;
}
.bw-search svg { width: 9px; height: 9px; }
.bw-ask {
  font-family: var(--sora); font-weight: 800;
  font-size: 22px; line-height: 1.05; letter-spacing: -0.028em;
  color: var(--roast); margin-top: 16px;
}
.bw-areas { list-style: none; margin-top: 12px; display: grid; gap: 3px; }
.bw-areas li { font-family: var(--sora); font-weight: 700; font-size: 12px; letter-spacing: -0.02em; color: var(--roast-soft); }
.bw-areas li.on { color: var(--roast); }
.bw-cream { background: var(--cream); padding: 9px 15px 0; flex: 1; display: flex; flex-direction: column; min-height: 0; }
.bw-left { font-family: var(--mono); font-size: 10px; font-weight: 700; color: var(--clay); }
/* The second row runs on under the dock, so the shelf reads as a scrolling list. */
.bw-grid { display: grid; grid-template-columns: 1fr 1fr; align-content: start; gap: 9px; margin-top: 8px; flex: 1; min-height: 0; overflow: hidden; }
.bw-grid figure { margin: 0; min-width: 0; }
.bw-frame { position: relative; }
.bw-grid img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 15px; }
.bw-chip {
  position: absolute; left: 6px;
  font-family: var(--mono); font-weight: 700; font-size: 7.5px; letter-spacing: -0.02em;
  padding: 3px 6px; border-radius: var(--r-full);
}
.bw-chip-off { top: 6px; background: var(--roast); color: var(--cream); }
.bw-chip-price { bottom: 6px; background: var(--cream); color: var(--roast); }
.bw-grid strong { display: block; font-family: var(--sora); font-weight: 700; font-size: 10.5px; letter-spacing: -0.02em; color: var(--roast); margin-top: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bw-grid figcaption span { display: block; font-size: 8.5px; font-weight: 500; color: var(--clay); margin-top: 1px; }
.bw-dock { margin-top: auto; display: flex; justify-content: space-around; align-items: center; height: 40px; border-top: 1px solid var(--hairline); }
.bw-dock span { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 6px; color: var(--clay); }
.bw-dock span i { display: none; font-style: normal; font-family: var(--sora); font-size: 8.5px; font-weight: 700; letter-spacing: -0.02em; }
.bw-dock svg { width: 12px; height: 12px; }
.bw-dock .on { background: var(--primary); color: var(--roast); border-radius: 6px; padding: 0 8px; }
.bw-dock .on i { display: inline; }

/* Scene 1 · Book — the itemised quote as ruled rows */
.scr-book { background: var(--cream); padding: 27px 15px 12px; }
.bk-head { font-family: var(--sora); font-weight: 800; font-size: 24px; letter-spacing: -0.028em; color: var(--roast); margin-top: 6px; }
.bk-villa { display: flex; gap: 9px; align-items: center; margin-top: 12px; }
.bk-villa img { width: 48px; height: 48px; border-radius: 8px; object-fit: cover; flex: none; }
.bk-villa strong { display: block; font-family: var(--sora); font-weight: 700; font-size: 14px; letter-spacing: -0.02em; color: var(--roast); }
.bk-villa span { font-size: 11px; font-weight: 500; color: var(--clay); }
.bk-quote { margin-top: 14px; border-top: 1px solid var(--hairline); }
.bk-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  padding: 12px 0; border-bottom: 1px solid var(--hairline);
  font-size: 13px; font-weight: 500; color: var(--clay);
}
.bk-row b { font-family: var(--mono); font-size: 14px; font-weight: 700; letter-spacing: -0.02em; color: var(--roast); white-space: nowrap; }
.bk-compare b s { color: var(--clay); font-weight: 700; }
.bk-compare i { font-style: normal; font-family: var(--mono); color: var(--primary-deep); margin-left: 2px; }
.bk-total span { color: var(--roast); font-weight: 700; }
.bk-total b { font-size: 17px; }
.bk-cta {
  margin-top: auto; display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 11px 12px; border-radius: 16px;
  background: var(--primary); color: var(--roast);
  font-family: var(--sora); font-weight: 800; font-size: 16px; letter-spacing: -0.02em; line-height: 1.1;
}
.bk-cta small { font-family: var(--mono); font-weight: 700; font-size: 10.5px; letter-spacing: -0.02em; margin-top: 3px; color: var(--roast-soft); }
.bk-note { text-align: center; font-size: 10px; font-weight: 500; color: var(--clay); margin-top: 8px; }

/* Scene 2 · The bump — day 21, handled. Roast ground, cream + sand ink, orange figures. */
.scr-bump { background: var(--roast); padding: 27px 15px 12px; }
.bp-head { font-family: var(--sora); font-weight: 800; font-size: 22px; line-height: 1.05; letter-spacing: -0.028em; color: var(--cream); margin-top: 6px; }
.bp-sub { font-size: 9.5px; font-weight: 500; line-height: 1.5; color: var(--sand); margin-top: 8px; }
.bp-sub b { font-family: var(--mono); color: var(--primary); }
.bp-rows { margin-top: 10px; border-top: 1px solid var(--hairline-on-dark); }
.bp-row { display: flex; align-items: center; gap: 9px; padding: 8px 0; border-bottom: 1px solid var(--hairline-on-dark); }
.bp-row img { width: 32px; height: 32px; border-radius: 8px; object-fit: cover; flex: none; }
.bp-row div { min-width: 0; }
.bp-row strong { display: block; font-family: var(--sora); font-weight: 700; font-size: 11px; letter-spacing: -0.02em; color: var(--cream); }
.bp-row span { font-size: 8.5px; font-weight: 500; color: var(--sand); }
.bp-row b { margin-left: auto; font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: -0.02em; color: var(--cream); white-space: nowrap; }
.bp-refund {
  display: flex; gap: 8px; align-items: center; margin-top: auto; margin-bottom: 4px;
  padding: 9px 0 4px;
}
.bp-check { width: 20px; height: 20px; flex: none; border-radius: var(--r-full); background: var(--primary); color: var(--roast); display: grid; place-items: center; }
.bp-check svg { width: 10px; height: 10px; }
.bp-refund strong { display: block; font-family: var(--mono); font-size: 10.5px; font-weight: 700; letter-spacing: -0.02em; color: var(--primary); }
.bp-refund span { font-size: 8.5px; font-weight: 500; color: var(--sand); }

/* ---------------- Night — the catch, at page scale ----------------
   The sequence already landed on roast, so this continues that ground.
   Display heading in cream, body in sand, terms as mono figures in orange. */

.night {
  background: var(--roast);
  color: var(--sand);
  padding: clamp(72px, 9vw, 112px) 0 clamp(64px, 8vw, 96px);
  position: relative;
  z-index: 2;
}
.night .display { color: var(--cream); max-width: 22ch; }
.night-sub {
  margin-top: var(--s-xxl);
  max-width: 58ch;
  font-size: 17px; font-weight: 500; line-height: 1.5;
  color: var(--sand);
}

.night-rows {
  list-style: none;
  margin-top: clamp(40px, 5vw, 56px);
  border-top: 1px solid var(--hairline-on-dark);
  max-width: 900px;
}
.night-row {
  display: grid; grid-template-columns: 132px 1fr; gap: var(--s-xl);
  padding: var(--s-xxl) 0;
  border-bottom: 1px solid var(--hairline-on-dark);
  cursor: pointer;
}
.night-row:focus-visible { outline-offset: 6px; }
.night-fig {
  font-family: var(--mono); font-weight: 700; font-size: 30px; letter-spacing: -0.03em; line-height: 1.1;
  color: var(--sand);
  transition: color .4s ease;
}
.night-row.is-on .night-fig { color: var(--primary); }
.night-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-md); }
.night-head strong { font-family: var(--sora); font-size: 19px; font-weight: 700; letter-spacing: -0.02em; color: var(--cream); }
.night-head span { font-family: var(--mono); font-weight: 700; font-size: 12.5px; letter-spacing: -0.02em; color: var(--sand); white-space: nowrap; }
.night-row p { font-size: 15px; font-weight: 400; line-height: 1.6; color: var(--sand); margin-top: 6px; max-width: 60ch; }
.night-row p b { font-family: var(--mono); letter-spacing: -0.02em; color: var(--cream); }

.night-legend {
  margin-top: var(--s-xxxl);
  max-width: 900px;
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-xxl) var(--s-xxxl);
}
.night-legend p { font-size: 15px; font-weight: 400; line-height: 1.6; color: var(--sand); }
.night-legend b { display: block; font-family: var(--sora); font-weight: 700; font-size: 15px; letter-spacing: -0.02em; color: var(--cream); margin-bottom: 4px; }
.night-legend p .fig { color: var(--cream); }

/* Commit buttons: orange radius 24, and its inverted twin. */
.night-actions {
  display: flex; gap: var(--s-md); flex-wrap: wrap;
  margin-top: clamp(40px, 6vw, 64px);
}
.commit {
  display: inline-flex; align-items: center; gap: 12px;
  min-height: 64px; padding: 20px 28px;
  border-radius: var(--r-block);
  text-decoration: none;
  font-family: var(--sora); font-weight: 800; font-size: 22px; letter-spacing: -0.028em; line-height: 1.1;
  transition: background .15s;
}
.commit svg { width: 22px; height: 22px; fill: currentColor; flex: none; }
.commit-primary { background: var(--primary); color: var(--roast); }
.commit-primary:hover, .commit-primary:active { background: var(--primary-deep); }
.commit-invert { background: var(--cream); color: var(--roast); }
.commit-invert:hover { background: var(--cream-dim); }

/* ---------------- The odds — one figure, a thousand stays on orange ----------------
   Ground inversion from roast to orange before the cream board. One sentence, and the
   figure drawn behind it: 1,000 dots in roast ink at a wash filling the whole
   block edge to edge, 27 of them solid. The grid's column count, row count and dot size
   are set per layout by script.js. In view the figure builds itself: the dots print in on
   a diagonal sweep, the 27 bumps pop one after another while the headline figure ticks up
   to 2.7%. `.is-armed` hides the dots until then; `.is-in` runs the build. */

/* The field runs on under the footer's top: the section carries the bleed as extra bottom padding, the
   footer pulls up over it with a transparent top band, and the dot columns end at different depths in it. */
:root { --odds-bleed: 220px; }
.odds {
  background: var(--primary);
  color: var(--roast);
  padding: clamp(72px, 9vw, 112px) 0 calc(clamp(64px, 8vw, 96px) + var(--odds-bleed));
  min-height: clamp(560px, 82vh, 860px);
  position: relative;
  z-index: 2;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.odds .wrap {
  position: relative;
  z-index: 1;
  flex: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
}
.odds .display { max-width: 16ch; }
/* The figure stays in Sora: mono's full-width period breaks "2.7%" apart at display size. */
.odds-fig {
  display: inline-block;
  font-variant-numeric: tabular-nums;
  transition: opacity .3s ease, transform .5s var(--ease-out);
}
/* The figure sits at 0.0% and dimmed while the stays print, then ticks up in full ink. */
.odds.is-armed:not(.is-done) .odds-fig { opacity: .4; }
.odds.is-done .odds-fig { animation: odds-fig-land .55s var(--ease-out); }

.odds-field {
  --dot: rgba(46, 21, 2, 0.2);
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(var(--cols, 40), minmax(0, 1fr));
  grid-template-rows: repeat(var(--rows, 25), minmax(0, 1fr));
  justify-items: center;
  align-items: center;
  pointer-events: none;
}
/* The tail under the footer's top: script.js adds the extra rows, each column running a different
   number of them. Off cells keep their grid slot so the columns stay aligned. */
.odds-field i.is-off { visibility: hidden; }
.odds-field i {
  display: block;
  width: var(--dot-size, 14px);
  height: var(--dot-size, 14px);
  border-radius: 50%;
  background: var(--dot);
  transition: background .2s ease;
}
.odds.is-armed .odds-field i { opacity: 0; transform: scale(.3); }
.odds.is-in .odds-field i { animation: odds-dot-in .55s var(--ease-out) var(--d, 0ms) both; }
.odds-field i.is-bump { background: var(--roast); }
.odds.is-in .odds-field i.is-bump { animation: odds-bump-pop .6s var(--ease-out) both; }

@keyframes odds-dot-in {
  from { opacity: 0; transform: scale(.3); }
  to   { opacity: 1; transform: none; }
}
@keyframes odds-bump-pop {
  0%   { opacity: 1; transform: scale(1); }
  45%  { opacity: 1; transform: scale(2.1); }
  100% { opacity: 1; transform: scale(1.35); }
}
@keyframes odds-fig-land {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.06); }
  100% { transform: scale(1); }
}

/* ---------------- Board — the villa grid on cream ---------------- */

.board {
  background: var(--cream);
  color: var(--roast);
  padding: clamp(64px, 8vw, 96px) 0 clamp(64px, 8vw, 96px);
}
.board-sub { margin-top: var(--s-md); max-width: 56ch; font-size: 15px; font-weight: 500; color: var(--clay); }

.board-grid {
  margin-top: clamp(28px, 4vw, 44px);
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s-xxxl) 14px;
}
.villa { display: flex; flex-direction: column; min-width: 0; }
.villa-frame { position: relative; aspect-ratio: 1; overflow: hidden; border-radius: var(--r-frame); background: var(--cream-dim); }
.villa-frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.chip {
  position: absolute; left: 10px;
  font-family: var(--mono); font-weight: 700; font-size: 12.5px; letter-spacing: -0.02em; line-height: 1.2;
  border-radius: var(--r-full);
}
.chip-off { top: 10px; padding: 4px 9px; background: var(--roast); color: var(--cream); }
.chip-price { bottom: 10px; padding: 5px 10px; background: var(--cream); color: var(--roast); }
.chip-price i { font-style: normal; font-weight: 700; color: var(--clay); }
.villa-name { margin-top: var(--s-md); font-family: var(--sora); font-weight: 700; font-size: 17px; letter-spacing: -0.02em; line-height: 1.2; }
.villa-meta { margin-top: 3px; font-size: 12.5px; font-weight: 500; color: var(--clay); }
.villa-compare { margin-top: var(--s-sm); font-size: 12.5px; font-weight: 500; color: var(--clay); }
.villa-compare b { font-family: var(--mono); letter-spacing: -0.02em; color: var(--roast); }

/* ---------------- Help-center rows (.closer-sub, .facts, .fact) ----------------
   The home page's closer section was removed on 2026-09-12 — the page now ends on the
   odds poster into the footer. These rows stay because help.html still uses them. */

/* Facts as rows (help center answers). */
.closer-sub { margin-top: var(--s-md); max-width: 56ch; font-size: 15px; font-weight: 500; color: var(--clay); }
.facts {
  margin-top: clamp(28px, 4vw, 44px);
  max-width: 860px;
  border-top: 1px solid var(--hairline);
}
.fact {
  display: grid; grid-template-columns: 168px 1fr; gap: var(--s-xl);
  padding: var(--s-md) 0;
  border-bottom: 1px solid var(--hairline);
}
.fact dt { padding-top: 3px; color: var(--clay); }
.fact dd { font-size: 15px; font-weight: 400; line-height: 1.6; max-width: 60ch; }
.fact dd b { font-family: var(--mono); letter-spacing: -0.02em; }

/* ---------------- Footer — the poster field closes the page ---------------- */

.footer {
  background: var(--primary);
  color: var(--roast);
  padding: clamp(56px, 7vw, 80px) 0 max(clamp(28px, 4vw, 40px), env(safe-area-inset-bottom, 0px));
}
/* After the odds poster the footer rides up over the bleed; its top band is clear so the dots show through. */
.odds + .footer {
  position: relative; z-index: 3;
  margin-top: calc(-1 * var(--odds-bleed));
  background: linear-gradient(to bottom, transparent var(--odds-bleed), var(--primary) var(--odds-bleed));
}
.footer .label { color: var(--roast-soft); }
.footer ul { list-style: none; }
.footer a { text-decoration: none; }

.footer-top {
  padding-bottom: clamp(36px, 5vw, 56px);
  border-bottom: 1px solid rgba(46,21,2,0.22);
}
.footer-logo { width: 136px; height: auto; }
.footer-stores { display: flex; gap: 10px; flex-wrap: wrap; margin-top: var(--s-xxl); }
/* The store badges, same anatomy as the hero's, in roast on the orange field. */
.ft-badge {
  display: inline-flex; align-items: center; gap: 9px;
  height: 48px; padding: 0 18px 0 14px;
  background: var(--roast); color: var(--cream); border-radius: var(--r-control);
  white-space: nowrap; transition: background .15s;
}
.ft-badge:hover, .ft-badge:active { background: var(--roast-soft); }
.ft-badge svg { display: block; flex: none; fill: currentColor; }
.ft-badge .sb-apple { width: 21px; height: 21px; margin-top: -2px; }
.ft-badge .sb-play { width: 19px; height: 19px; }
.ft-badge span { display: flex; flex-direction: column; line-height: 1; text-align: left; }
.ft-badge small { font-size: 11px; font-weight: 500; color: var(--sand); }
.ft-badge b { font-family: var(--sora); font-size: 16.5px; font-weight: 700; letter-spacing: -.02em; margin-top: 2px; }

.footer-cols {
  display: grid; grid-template-columns: 1.35fr 1.35fr 1fr 1fr; gap: var(--s-xxl);
  padding: clamp(36px, 5vw, 56px) 0;
}
.footer-col .label { display: block; margin-bottom: var(--s-lg); }
.footer-col li { font-size: 15px; font-weight: 500; line-height: 1.2; }
.footer-col li + li { margin-top: 2px; }
.footer-col li a { display: inline-block; padding: 7px 0; transition: color .15s; }
.footer-col li a:hover { color: var(--roast-soft); text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1.5px; }
.footer-more { font-family: var(--sora); font-weight: 700; letter-spacing: -0.02em; margin-top: var(--s-sm); }
/* Company names are printed, not linked: no page behind them yet. Secondary ink says so. */
.footer-plain li { padding: 7px 0; color: var(--roast-soft); cursor: default; }

.footer-end {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-xl); flex-wrap: wrap;
  padding-top: var(--s-xl);
  border-top: 1px solid rgba(46,21,2,0.22);
}
.footer-legal { display: flex; gap: var(--s-xxl); flex-wrap: wrap; font-family: var(--sora); font-weight: 700; font-size: 15px; letter-spacing: -0.02em; }
.footer-legal a { padding: 10px 0; transition: color .15s; }
.footer-legal a:hover { color: var(--roast-soft); text-decoration: underline; text-underline-offset: 4px; }
.footer-fine { font-size: 12.5px; font-weight: 500; line-height: 1.5; color: var(--roast-soft); }
.footer-fine b { font-family: var(--mono); letter-spacing: -0.02em; }

/* ---------------- Responsive ---------------- */

@media (max-width: 1100px) {
  .board-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 900px) {
  .board-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 720px) {
  .navwrap { padding: 6px 12px; }
  .nav { width: auto; margin: 0; gap: var(--s-lg); }
  .nav .stamp { margin-left: auto; }
  .nav-links { display: none; }
  .hero-sub { font-size: 16px; }
  /* One fact per line on a phone; the separators only make sense on one line. */
  .hero-facts { display: grid; gap: 6px; }
  .hero-facts li:not(:last-child)::after { content: none; }
  .hero-seq { height: 340vh; }
  .handwrap { height: auto; width: min(94vw, 440px); margin-bottom: -16svh; }
  .night-rows { max-width: none; }
  .night-row { grid-template-columns: 1fr; gap: var(--s-sm); padding: var(--s-xl) 0; }
  .night-fig { font-size: 26px; }
  .night-legend { grid-template-columns: 1fr; gap: var(--s-xl); }
  .odds { min-height: clamp(520px, 78vh, 760px); --odds-bleed: 160px; }
  .night-actions { flex-direction: column; align-items: stretch; }
  .commit { justify-content: center; font-size: 18px; }
  .board-grid { gap: var(--s-xxl) 14px; }
  .fact { grid-template-columns: 1fr; gap: 6px; }
  .footer-cols { grid-template-columns: 1fr 1fr; gap: var(--s-xxxl) var(--s-xxl); }
  .footer-end { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 400px) {
  .board-grid { grid-template-columns: 1fr 1fr; gap: var(--s-xl) 10px; }
  .villa-name { font-size: 15px; }
}

/* ---------------- Reduced motion ---------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .scr, .scr.is-live { transition: none; }
  .night-fig { transition: none; }
  .odds-field i, .odds-fig { transition: none; animation: none; }
  /* The sequence stays scroll-driven — stages simply cut instead of fading. */
  .hero-ground i, .stage-swap > span { transition: none; }
}
