/* ==========================================================================
   Matey — landing page
   Dark, flat, typographic. The language is the references': Dropset's
   near-black surface, bold grotesque headlines with a dimmed second line and
   hairline-bordered cards; Opal's centered staging and the device standing
   in a pool of light.

   Two rules govern the sheet:

   1. Structure comes from hairlines and type, never from boxes. A card is a
      1px rgba border on a barely-lighter panel; depth is one soft black
      ambient shadow, used only where something truly floats (the phone).
   2. The brand orange is scarce. It fills the CTA, marks the key phrase,
      and lights the glow behind the device — never a decoration.
   ========================================================================== */

:root {
  /* --- Surface & ink ----------------------------------------------------
     One dark surface, two lifts. Every ratio below is COMPUTED against the
     backdrops actually used (rgba composited first), not asserted:
       --ink        #F4F4F6           17.9:1 on --bg
       --ink-muted  rgba(.66)          8.0:1 on --bg — all body copy
       --ink-faint  rgba(.50)          4.9:1 on --bg, 4.8:1 on --card-lift —
                    the floor for small labels; 0.48 is the minimum passing
                    alpha on the worst backdrop, so don't shave this
       --brand      #F25C05            5.9:1 on --bg
       --brand-ink  #FF8A4C            8.4:1 on --bg — accent text, safest */
  --bg: #0b0b0e;
  --bg-lift: #101014;         /* inset panels (the flat plan's rooms) */
  --card: #15151a;
  --card-lift: #1b1b21;
  --line: rgba(244, 244, 246, 0.09);
  --line-strong: rgba(244, 244, 246, 0.16);

  --ink: #f4f4f6;
  --ink-muted: rgba(244, 244, 246, 0.66);
  --ink-faint: rgba(244, 244, 246, 0.5);

  --brand: #f25c05;
  --brand-press: #d94f02;
  --brand-ink: #ff8a4c;
  --brand-glow: rgba(242, 92, 5, 0.28);

  --verified: #2fb886;

  /* --- Geometry ---------------------------------------------------------- */
  --r-card: 20px;
  --r-base: 14px;
  --r-inner: 10px;
  --r-pill: 999px;

  /* --- Type ---------------------------------------------------------------
     Figtree is the closest open face to the references' Eina 03 — same round
     geometric skeleton. Hangul falls through to Pretendard, whose weights
     track Figtree's closely enough that mixed KR/EN lines sit flush. */
  --font-display: "Figtree", "Pretendard Variable", Pretendard,
                  -apple-system, BlinkMacSystemFont, sans-serif;
  --font-body: "Figtree", "Pretendard Variable", Pretendard,
               -apple-system, BlinkMacSystemFont, sans-serif;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --shell: min(1200px, 100% - 48px);
}

/* --------------------------------------------------------------------------
   Reset & base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

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

/* The header is fixed, so an anchor jump would otherwise land the section's
   first line underneath it. */
:target,
section[id] { scroll-margin-top: 92px; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16.5px;
  line-height: 1.7;
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  word-break: keep-all;   /* Korean lines break on words, not syllables */
}

img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; padding: 0; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.16;
}

::selection { background: rgba(242, 92, 5, 0.35); color: #fff; }

/* Tabular figures everywhere a number can change or be compared. */
.num { font-variant-numeric: tabular-nums; }

:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--brand-ink);
  outline-offset: 3px;
  border-radius: 6px;
}

/* Unused today; kept for the skip-link / SR-text the page will grow. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.shell {
  width: var(--shell);
  margin-inline: auto;
}

/* --------------------------------------------------------------------------
   Primitives
   -------------------------------------------------------------------------- */

/* The references label sections with a bare micro-line, not a chip. Brand
   orange at this size clears 6:1 on the dark surface. */
.eyebrow {
  display: block;
  font-family: var(--font-display);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brand-ink);
}

.section-title {
  font-size: clamp(32px, 4.4vw, 54px);
  letter-spacing: -0.035em;
  margin-top: 20px;
}

.section-lede {
  margin-top: 20px;
  max-width: 60ch;
  color: var(--ink-muted);
  font-size: clamp(15.5px, 1.3vw, 17.5px);
  line-height: 1.8;
}

/* Buttons — flat fills, 12-14px radii, the references' idiom. ------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 50px;
  padding: 0 28px;
  border-radius: var(--r-base);
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.01em;
  transition: transform 0.25s var(--ease), background-color 0.25s var(--ease),
              border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

/* White on --brand is 3.33:1 — AA only as LARGE text, and WCAG's floor for
   large-bold is 14pt = 18.66px. So 19px is the contrast contract, not taste. */
.btn--primary {
  background: var(--brand);
  color: #fff;
  font-size: 19px;
  box-shadow: 0 12px 32px -12px rgba(242, 92, 5, 0.55);
}
.btn--primary:hover {
  background: var(--brand-press);
  transform: translateY(-1px);
  box-shadow: 0 16px 40px -12px rgba(242, 92, 5, 0.65);
}
.btn--primary:active { transform: translateY(0.5px); box-shadow: none; }

/* The Dropset "Download" button: a quiet gray fill that reads as a control
   against the black, no border theatrics. */
.btn--ghost {
  background: #232329;
  color: var(--ink);
  font-size: 16px;
  border: 1px solid var(--line);
}
.btn--ghost:hover {
  background: #2a2a31;
  border-color: var(--line-strong);
  transform: translateY(-1px);
}
.btn--ghost:active { transform: translateY(0.5px); }

/* --------------------------------------------------------------------------
   Light bands — not a second design, the same tokens re-declared. Any
   component dropped into a .theme-light section re-themes itself; nothing
   inside is written twice. Ratios computed against #f5f4f1:
     --ink #17171a 16.2:1 · muted rgba(.7) ~8.3:1 · faint rgba(.65) ~5.0:1
     --brand-ink #b04403 ~4.9:1 — accent text stays AA on the light clay.
   -------------------------------------------------------------------------- */
.theme-light {
  --bg: #f5f4f1;
  --bg-lift: #ecebe6;
  --card: #ffffff;
  --card-lift: #ffffff;
  --line: rgba(23, 23, 26, 0.1);
  --line-strong: rgba(23, 23, 26, 0.22);

  --ink: #17171a;
  --ink-muted: rgba(23, 23, 26, 0.7);
  --ink-faint: rgba(23, 23, 26, 0.65);

  --brand-ink: #b04403;
  --brand-glow: rgba(242, 92, 5, 0.16);

  background: var(--bg);
  color: var(--ink);
}

/* White cards on light clay need a touch of real depth — the hairline alone
   disappears against the near-white backdrop. */
.theme-light :is(.alt, .person, .safe, .plan, .gap-stat) {
  box-shadow: 0 18px 44px -32px rgba(23, 23, 26, 0.35);
}
.theme-light .rhythm__track { background: #e9e8e3; }
.theme-light ::selection { color: #17171a; }

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */
.header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  padding: 14px 0;
  transition: padding 0.35s var(--ease), background-color 0.35s var(--ease);
}

.header.is-stuck {
  padding: 9px 0;
  background: rgba(11, 11, 14, 0.78);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 var(--line);
}

/* The header wears whatever band is underneath it — main.js flags it when a
   light section scrolls under the bar, and the tokens flip like any other
   .theme-light surface. The hardcoded control fills flip with it. */
.header.is-light {
  --line: rgba(23, 23, 26, 0.1);
  --line-strong: rgba(23, 23, 26, 0.22);
  --ink: #17171a;
  --ink-muted: rgba(23, 23, 26, 0.7);
  --ink-faint: rgba(23, 23, 26, 0.65);
  --brand-ink: #b04403;
  color: var(--ink);
}
.header.is-light.is-stuck { background: rgba(245, 244, 241, 0.8); }
.header.is-light .lang { background: #e9e8e3; }
.header.is-light .lang__thumb { background: #fff; box-shadow: 0 2px 8px rgba(23, 23, 26, 0.18); }
.header.is-light .nav a:hover { background: rgba(23, 23, 26, 0.06); }
.header.is-light .nav-toggle { background: #e9e8e3; }
.header.is-light .nav-toggle[aria-expanded="true"] { background: #dbdad4; }
.header.is-light .nav.is-open { background: #fff; }

/* Reading progress — a hairline of brand orange, the page's only chrome. */
.header__progress {
  position: absolute;
  inset: auto 0 0;
  height: 2px;
  transform: scaleX(var(--read, 0));
  transform-origin: 0 50%;
  background: var(--brand);
  opacity: 0;
  transition: opacity 0.3s;
}
.header.is-stuck .header__progress { opacity: 1; }

.header__bar {
  display: flex;
  align-items: center;
  gap: 20px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-right: auto;
}

.brand__icon {
  width: 36px; height: 36px;
  border-radius: 10px;
  flex: none;
}

/* The script wordmark ships as an ALPHA mask (a CSS mask reads the alpha
   channel — a greyscale file would paint a solid block), so the colour is
   CSS rather than pixels: one file serves header, hero and footer. */
.wordmark {
  display: block;
  background-color: var(--brand);
  -webkit-mask: url("assets/matey-wordmark.png?v=1") no-repeat center / contain;
  mask: url("assets/matey-wordmark.png?v=1") no-repeat center / contain;
}

.brand .wordmark {
  width: 84px;
  height: 30px;
}

.nav {
  display: flex;
  align-items: center;
  gap: 2px;
}

.nav a {
  padding: 10px 14px;
  border-radius: var(--r-inner);
  font-size: 14.5px;
  font-weight: 500;
  color: var(--ink-muted);
  transition: color 0.25s, background-color 0.25s;
}
.nav a:hover { color: var(--ink); background: rgba(244, 244, 246, 0.06); }

/* Language toggle — a dark segmented control with a sliding lifted thumb. */
.lang {
  position: relative;
  display: flex;
  padding: 4px;
  border-radius: var(--r-pill);
  background: #17171c;
  border: 1px solid var(--line);
}

.lang__thumb {
  position: absolute;
  top: 4px; left: 4px;
  width: 42px; height: 42px;
  border-radius: var(--r-pill);
  background: #2b2b33;
  transition: transform 0.35s var(--ease);
}
.lang[data-lang="en"] .lang__thumb { transform: translateX(42px); }

.lang button {
  position: relative;
  z-index: 1;
  width: 42px; height: 42px;   /* keeps the 44px-ish touch target with padding */
  border-radius: var(--r-pill);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
  transition: color 0.3s;
}
.lang button[aria-pressed="true"] { color: var(--ink); }

.nav-toggle { display: none; }

/* --------------------------------------------------------------------------
   Hero — Opal's staging: the claim, then the product standing centred in
   a pool of the brand's light.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  padding: 168px 0 110px;
  overflow: hidden;
}

/* A faint brand aurora high behind the headline, and nothing else. */
.hero::before {
  content: "";
  position: absolute;
  top: -340px; left: 50%;
  width: 1100px; height: 700px;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(242, 92, 5, 0.16) 0%, rgba(242, 92, 5, 0) 70%);
  pointer-events: none;
}

.hero__stack {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.hero .wordmark {
  width: clamp(150px, 15vw, 190px);
  height: clamp(55px, 5.5vw, 70px);
  margin-bottom: 34px;
}

/* The Dropset two-tone: the sentence is dimmed, the phrase that is the whole
   company is white. <em> carries the key phrase in both languages. */
.hero__title {
  font-size: clamp(42px, 6.4vw, 82px);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.045em;
  color: var(--ink-faint);
}
.hero__title em {
  font-style: normal;
  color: var(--ink);
}

.hero__lede {
  margin-top: 26px;
  /* min() with 100%: 56ch of Korean under word-break:keep-all can exceed a
     phone viewport, and a centered flex child sized to its max-width would
     drag the whole stack wider than the screen. */
  max-width: min(56ch, 100%);
  color: var(--ink-muted);
  font-size: clamp(16px, 1.5vw, 18.5px);
  line-height: 1.75;
}
.hero__lede b { color: var(--ink); font-weight: 600; }

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 36px;
}

/* The hero phone answers the viewport, not a breakpoint table: the device is
   428 logical px wide and gets scaled so it always spans ~78vw on a phone yet
   never exceeds ~396px on a desktop.
   --ps must stay a unitless NUMBER: it feeds transform:scale() and the 428px
   multiplications. calc(length/number) yields a LENGTH (0.71px!), which
   silently invalidates all of them — hence the ladder, not a vw formula. */
.hero .phone {
  --ps: 0.925;
  margin-top: clamp(48px, 7vh, 84px);
}

@media (max-width: 900px) {
  .hero .phone { --ps: 0.8; }
}
@media (max-width: 560px) {
  .hero .phone { --ps: 0.71; }
}
@media (max-width: 400px) {
  .hero .phone { --ps: 0.63; }
}
@media (max-width: 350px) {
  .hero .phone { --ps: 0.55; }
}

/* --------------------------------------------------------------------------
   Phone

   The frame is Devices.css's iPhone 14 Pro (MIT, vendored in
   assets/device-iphone-14-pro.css) — a real device geometry, Dynamic Island
   and all, rather than a bezel we guessed at. It renders at the iPhone's true
   logical size (428x868, screen 390x830) and is scaled down to fit.
   -------------------------------------------------------------------------- */
.phone {
  --ps: 0.72;                            /* device scale */
  position: relative;
  flex: none;
  width: calc(428px * var(--ps));
  height: calc(868px * var(--ps));
}

.phone .device {
  transform: scale(var(--ps));
  transform-origin: 0 0;
}

/* One soft ambient shadow — the only real shadow on the page. */
.phone::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: calc(68px * var(--ps));
  box-shadow: 0 40px 90px -30px rgba(0, 0, 0, 0.85);
}

/* The pool of light the device stands in — Opal's trick, in brand orange. */
.phone::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 10% -12% -8%;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 55%,
    var(--brand-glow) 0%, rgba(242, 92, 5, 0) 72%);
  filter: blur(30px);
}

/* Hero-only: taller, brighter halo for the centred stage. */
.hero .phone::after {
  inset: -6% -22% -12%;
  background: radial-gradient(50% 50% at 50% 55%,
    rgba(242, 92, 5, 0.34) 0%, rgba(242, 92, 5, 0) 70%);
}

/* The hero phone is the one element that moves every frame. */
#heroPhone { will-change: transform; }

/* Real captures off the running app, crossfading in the hero. Cover-fit
   absorbs the tiny aspect gap between the capture device (402x874) and the
   frame (390x830). */
.shots {
  position: absolute;
  inset: 0;
  background: #000;
}
.shot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.9s var(--ease);
}
.shot.is-on { opacity: 1; }

/* --------------------------------------------------------------------------
   Neighbourhood ticker — a hairline-bounded marquee of the places the app
   actually covers. Pure CSS; two copies of the list loop at -50%.
   -------------------------------------------------------------------------- */
.ticker {
  overflow: hidden;
  padding: 18px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.ticker__track {
  display: flex;
  align-items: center;
  width: max-content;
  animation: ticker 36s linear infinite;
}
/* Spacing rides on the items, not the flex gap: with a trailing margin on
   every child both halves of the track measure identically, so the -50%
   loop point lands exactly on a copy boundary — no seam. */
.ticker__track > * { margin-right: 28px; }
.ticker__track span {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  white-space: nowrap;
}
.ticker__track i { font-style: normal; color: var(--brand); }
@keyframes ticker { to { transform: translateX(-50%); } }

/* --------------------------------------------------------------------------
   Sections
   -------------------------------------------------------------------------- */
.section { padding: 116px 0; position: relative; }
.section--tight { padding: 92px 0; }

/* Reveal-on-scroll. Sets the resting state; .is-in releases it.
   Gated on .js — see the inline script in <head>. Without JavaScript these
   elements are simply visible. */
.js .rise {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--d, 0ms);
}
.rise.is-in { opacity: 1; transform: none; }

/* ---- The real problem -----------------------------------------------------
   Dropset states its thesis as huge dim type that turns white as you read.
   Ours turns brand: the second clause is the whole company. */
.problem {
  position: relative;
  padding: clamp(24px, 4vw, 56px) 0;
  text-align: center;
}

.problem__q {
  font-size: clamp(30px, 4.6vw, 56px);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1.22;
  max-width: 21ch;
  margin-inline: auto;
}

/* The turn of the argument — it arrives on scroll. */
.problem__q em {
  display: block;
  margin-top: 0.35em;
  font-style: normal;
  color: var(--brand-ink);
}
.js .problem__q em {
  opacity: var(--turn, 0);
  transform: translateY(calc((1 - var(--turn, 0)) * 14px));
}

.problem__body {
  margin: 34px auto 0;
  max-width: 58ch;
  color: var(--ink-muted);
  line-height: 1.85;
}

/* --------------------------------------------------------------------------
   Panels — the market section keeps its cinematic full-bleed photograph;
   on the dark page it no longer needs its own theme, just its wash.
   -------------------------------------------------------------------------- */
.panel {
  position: relative;
  overflow: hidden;
  padding: clamp(88px, 9vw, 132px) 0;
}

/* The photograph is the argument — a grid of identical flats with a completely
   different life spilling out of every one — so it stays legible: darkened,
   not hidden. */
.panel__bg {
  position: absolute;
  inset: 0;
  background: url("assets/hdb-facade.jpg") center / cover no-repeat;
  filter: brightness(0.75) saturate(0.85);
}

.panel__wash {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, var(--bg) 0%, rgba(11, 11, 14, 0.42) 16%,
                    rgba(11, 11, 14, 0.46) 78%, var(--bg) 100%),
    radial-gradient(115% 100% at 4% 50%, rgba(11, 11, 14, 0.99) 0%,
                    rgba(11, 11, 14, 0.95) 30%, rgba(11, 11, 14, 0.6) 62%,
                    rgba(11, 11, 14, 0.4) 100%);
}

.panel__grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(40px, 5vw, 76px);
  align-items: center;
}

.panel__title {
  font-size: clamp(30px, 4.2vw, 52px);
  letter-spacing: -0.035em;
  margin-top: 20px;
}
.panel__lede {
  margin-top: 20px;
  max-width: 46ch;
  color: var(--ink-muted);
  font-size: clamp(15.5px, 1.3vw, 17.5px);
  line-height: 1.8;
}

/* ---- The two sides of a room rent --------------------------------------- */
.parties {
  margin-top: 40px;
  display: grid;
  gap: 12px;
}

.party {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: 16px;
  align-items: start;
  padding: 20px 22px;
  border-radius: var(--r-base);
  background: rgba(21, 21, 26, 0.82);
  border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.party__icon {
  width: 44px; height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--r-inner);
  background: rgba(242, 92, 5, 0.12);
  color: var(--brand-ink);
}
.party h3 { font-size: 16px; letter-spacing: -0.02em; }
.party p {
  margin-top: 5px;
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-muted);
}

/* ---- The cutaway: one flat, four contracts -------------------------------
   The claim is that a Singapore flat is not one household but several, so
   the flat is drawn as what it actually is — a plan, a life per room. */
.flat {
  padding: clamp(24px, 2.6vw, 34px);
  border-radius: var(--r-card);
  background: rgba(21, 21, 26, 0.88);
  border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.flat__head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}
.flat__t {
  font-family: var(--font-display);
  font-size: clamp(17px, 1.8vw, 21px);
  font-weight: 700;
  letter-spacing: -0.025em;
}
.flat__k {
  margin-left: auto;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  /* muted, not faint: this pill sits on a translucent card over the
     photograph, the least predictable backdrop on the page (7.4:1 worst case) */
  color: var(--ink-muted);
}

.flat__plan {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  grid-template-areas:
    "master  c1"
    "master  c2"
    "shared  shared";
  gap: 10px;
}

.room {
  display: grid;
  align-content: space-between;
  gap: 14px;
  min-height: 92px;
  padding: 16px 18px;
  border-radius: var(--r-base);
  background: var(--bg-lift);
  border: 1px solid var(--line);
}

/* The en-suite is what makes a master room a master room. */
.room__sub {
  align-self: center;
  justify-self: start;
  padding: 8px 13px;
  border-radius: var(--r-inner);
  border: 1px solid var(--line);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.room--master { grid-area: master; }
.room--c1 { grid-area: c1; }
.room--c2 { grid-area: c2; }
.room--shared {
  grid-area: shared;
  min-height: 0;
  grid-auto-flow: column;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.room__k {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.room__who {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13.5px;
  color: var(--ink-muted);
}
.room__who b {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.room__dot {
  width: 8px; height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 10px var(--brand-glow);
}
.room--shared .room__dot { background: var(--ink-faint); box-shadow: none; }

.flat__note {
  margin-top: 22px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--ink-muted);
}
.flat__note b { color: var(--brand-ink); font-weight: 700; }

/* ---- Alternatives --------------------------------------------------------
   The references' card: barely-lighter panel, hairline border, generous
   radius, and a hover that lifts the border, not the box. */
.alts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-top: 56px;
}

.alt {
  padding: 32px 28px;
  border-radius: var(--r-card);
  background: var(--card);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  transition: transform 0.35s var(--ease), border-color 0.35s var(--ease),
              background-color 0.35s var(--ease);
}
.alt:hover {
  transform: translateY(-3px);
  border-color: var(--line-strong);
  background: var(--card-lift);
}
.alt__name {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.alt__kind {
  margin-top: 4px;
  font-size: 12.5px;
  color: var(--ink-faint);
  font-weight: 500;
}
.alt__body {
  margin-top: 18px;
  font-size: 14.5px;
  line-height: 1.75;
  color: var(--ink-muted);
}

/* margin-top:auto pins the can/can't list to the bottom of the card, so the
   three cards line up across the row no matter how long the copy above is. */
.alt__can {
  position: relative;
  margin-top: auto;
  padding-top: 22px;
  display: grid;
  gap: 9px;
  font-size: 13px;
}
.alt__can::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: var(--line);
}
.alt__can li { display: flex; align-items: center; gap: 9px; }
.alt__can .yes { color: var(--ink); }
.alt__can .no { color: var(--ink-muted); }
.alt__can .no b { font-weight: 600; }

.tick {
  width: 18px; height: 18px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
}
.tick--yes { color: var(--verified); border-color: rgba(47, 184, 134, 0.4); }
.tick--no { color: var(--ink-faint); }

/* The one number on the page that isn't ours — so it gets a source line. */
.gap-stat {
  margin-top: 56px;
  padding: clamp(36px, 4vw, 52px);
  border-radius: var(--r-card);
  background: var(--card);
  border: 1px solid var(--line);
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: clamp(28px, 5vw, 64px);
}
.gap-stat__n {
  font-family: var(--font-display);
  font-size: clamp(48px, 7vw, 84px);
  font-weight: 800;
  letter-spacing: -0.05em;
  line-height: 1;
  color: var(--ink);
}
/* A citation should not be the least legible text in the card: muted, not
   faint — 7.7:1 on --card. */
.gap-stat__src {
  margin-top: 10px;
  font-size: 12px;
  color: var(--ink-muted);
}
.gap-stat__say {
  font-family: var(--font-display);
  font-size: clamp(19px, 2.4vw, 27px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.5;
}
.gap-stat__zero {
  color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
}

/* ---- Lifestyle personas + 24h rhythm ------------------------------------ */
.people {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-top: 56px;
}

.person {
  padding: 28px 24px 24px;
  border-radius: var(--r-card);
  background: var(--card);
  border: 1px solid var(--line);
  transition: transform 0.35s var(--ease), border-color 0.35s var(--ease),
              background-color 0.35s var(--ease);
}
.person:hover {
  transform: translateY(-3px);
  border-color: var(--line-strong);
  background: var(--card-lift);
}
.person__icon {
  width: 48px; height: 48px;
  display: grid;
  place-items: center;
  border-radius: var(--r-inner);
  background: rgba(242, 92, 5, 0.12);
  color: var(--brand-ink);
  margin-bottom: 18px;
}
.person h3 { font-size: 17.5px; }
.person ul {
  margin-top: 13px;
  display: grid;
  gap: 8px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-muted);
}
.person li { display: flex; gap: 8px; }
.person li::before {
  content: "";
  width: 4px; height: 4px;
  margin-top: 9px;
  flex: none;
  border-radius: 50%;
  background: var(--brand);
  opacity: 0.8;
}

/* When each persona is actually home. Two bars that don't overlap are the
   whole pitch — a filter that reads a room can't see this. */
.rhythm { margin-top: 22px; }
.rhythm__label {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-muted);   /* the hour markers ARE the chart — keep them legible */
  margin-bottom: 7px;
}
.rhythm__track {
  position: relative;
  height: 10px;
  border-radius: var(--r-pill);
  background: #0d0d11;
  border: 1px solid var(--line);
  overflow: hidden;
}
.rhythm__at {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--from);
  width: 0;
  border-radius: var(--r-pill);
  background: var(--brand);
  opacity: 0.9;
  transition: width 0.9s var(--ease);
  transition-delay: var(--d, 0ms);
}
.is-in .rhythm__at { width: var(--w); }

/* ---- Feature sections -----------------------------------------------------
   One section per shipped feature: a claim, three checkable facts, and a
   real capture in the device frame. Copy and phone alternate sides via
   .feature--flip; below 900px the copy always leads (see the media block). */
.features-head { padding-bottom: 0; }
.features-head .section-lede { max-width: 56ch; }

.feature { padding: clamp(64px, 8vw, 110px) 0; }

.feature__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(44px, 6vw, 96px);
}
.feature--flip .feature__grid { grid-template-columns: auto minmax(0, 1fr); }
.feature--flip .feature__copy { order: 2; }

.feature__title {
  font-size: clamp(26px, 3.4vw, 42px);
  font-weight: 800;
  letter-spacing: -0.035em;
  margin-top: 20px;
}
.feature__body {
  margin-top: 18px;
  max-width: 46ch;
  color: var(--ink-muted);
  font-size: clamp(15.5px, 1.35vw, 17.5px);
  line-height: 1.8;
}
.feature__body b { color: var(--brand-ink); font-weight: 700; }

/* Facts as pills, not sentences — three glances, not three lines. */
.feature__points {
  margin-top: 24px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.feature__points li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 15px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink-muted);
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}
.feature__points li:hover { border-color: var(--line-strong); color: var(--ink); }
.feature__points li::before {
  content: "";
  width: 6px; height: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 8px var(--brand-glow);
}

.feature .phone { --ps: 0.76; }

/* Where the browser can drive animation from scroll position, the feature
   phones ride their own view timeline instead of the JS observer — the
   reveal tracks the scrollbar in both directions, which the one-shot
   IntersectionObserver class can't do. The .rise gating is overridden here
   so the two mechanisms never fight. */
@supports (animation-timeline: view()) {
  .js .feature .phone.rise {
    opacity: 1;
    transform: none;
    transition: none;
    animation: feature-phone-in both;
    animation-timeline: view();
    animation-range: entry 5% entry 55%;
  }
  @keyframes feature-phone-in {
    from { opacity: 0; transform: translateY(46px) scale(0.965); }
    to   { opacity: 1; transform: none; }
  }
}

/* ---- Trust & safety ------------------------------------------------------ */
.safes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-top: 56px;
}

.safe {
  padding: 32px 28px;
  border-radius: var(--r-card);
  background: var(--card);
  border: 1px solid var(--line);
  transition: transform 0.35s var(--ease), border-color 0.35s var(--ease),
              background-color 0.35s var(--ease);
}
.safe:hover {
  transform: translateY(-3px);
  border-color: var(--line-strong);
  background: var(--card-lift);
}
.safe__icon {
  width: 48px; height: 48px;
  display: grid;
  place-items: center;
  border-radius: var(--r-inner);
  background: rgba(242, 92, 5, 0.12);
  color: var(--brand-ink);
  margin-bottom: 18px;
}
.safe h3 { font-size: 19px; }
.safe p {
  margin-top: 12px;
  font-size: 14.5px;
  line-height: 1.75;
  color: var(--ink-muted);
}
.safe p b { color: var(--brand-ink); font-weight: 700; }

/* The small everyday things, worn as hairline pills. */
.alsos {
  margin-top: 36px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
}
.alsos li {
  padding: 10px 18px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-muted);
}

/* ---- Pricing ---------------------------------------------------------------
   Three plans, one message: the seeker pays nothing, ever — so that card
   leads and wears the brand. Hosts read what Basic includes and what Boost
   will add. -------------------------------------------------------------- */
.plans {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-top: 56px;
}

.plan {
  padding: 34px 30px;
  border-radius: var(--r-card);
  background: var(--card);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  transition: transform 0.35s var(--ease), border-color 0.35s var(--ease);
}
.plan:hover { transform: translateY(-3px); border-color: var(--line-strong); }

/* The seeker's card IS the pricing story. */
.plan--hero {
  border-color: rgba(242, 92, 5, 0.45);
  box-shadow: 0 24px 60px -36px rgba(242, 92, 5, 0.45);
}

.plan__who {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.plan--hero .plan__who { color: var(--brand-ink); }

.plan__price {
  margin-top: 16px;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.plan__price b {
  font-family: var(--font-display);
  font-size: clamp(40px, 4.5vw, 56px);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 1;
}
.plan__price span {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-muted);
}
.plan__tag {
  padding: 5px 12px;
  border-radius: var(--r-pill);
  background: rgba(242, 92, 5, 0.12);
  color: var(--brand-ink) !important;
  font-size: 12px !important;
}

.plan__note {
  margin-top: 12px;
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-muted);
}

.plan__list {
  position: relative;
  margin-top: auto;
  padding-top: 22px;
  display: grid;
  gap: 10px;
  font-size: 14px;
  color: var(--ink-muted);
}
.plan__list::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: var(--line);
}
.plan__list li { display: flex; gap: 9px; align-items: flex-start; }
.plan__list li::before {
  content: "";
  width: 6px; height: 6px;
  margin-top: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--brand);
}


/* ---- Contact -------------------------------------------------------------
   The closing panel stands in the same pool of light as the hero phone. */
.contact {
  position: relative;
  overflow: hidden;
  padding: clamp(52px, 6vw, 88px);
  border-radius: calc(var(--r-card) + 8px);
  background: var(--card);
  border: 1px solid var(--line);
  text-align: center;
}
.contact::before {
  content: "";
  position: absolute;
  top: -60%; left: 50%;
  width: 900px; height: 500px;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(242, 92, 5, 0.18) 0%, rgba(242, 92, 5, 0) 70%);
  pointer-events: none;
}
.contact__mark {
  position: relative;
  width: clamp(130px, 14vw, 160px);
  height: clamp(48px, 5.2vw, 59px);
  margin: 0 auto 30px;
}
.contact__title {
  position: relative;
  font-size: clamp(25px, 3.2vw, 40px);
  line-height: 1.35;
  letter-spacing: -0.03em;
}
.contact__lede {
  position: relative;
  margin: 18px auto 0;
  max-width: 52ch;
  color: var(--ink-muted);
  line-height: 1.8;
}
.contact__cta {
  position: relative;
  margin-top: 34px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
}

/* ---- Footer -------------------------------------------------------------- */
.footer {
  padding: 60px 0 52px;
  margin-top: 40px;
}
.footer__bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding-top: 32px;
}
.footer__bar::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: var(--line);
}
.footer .wordmark {
  width: 70px; height: 26px;
  background-color: var(--ink-faint);
}
.footer__meta {
  margin-left: auto;
  font-size: 13px;
  color: var(--ink-faint);
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
  .people { grid-template-columns: repeat(2, 1fr); }
  .feature .phone { --ps: 0.68; }
}

@media (max-width: 900px) {
  :root { --shell: min(1200px, 100% - 36px); }

  .nav { display: none; }
  .nav-toggle {
    display: grid;
    place-items: center;
    width: 46px; height: 46px;
    border-radius: 13px;
    background: #17171c;
    border: 1px solid var(--line);
    color: var(--ink);
  }
  .nav-toggle[aria-expanded="true"] { background: #2b2b33; }

  .nav.is-open {
    display: grid;
    position: absolute;
    top: calc(100% + 10px);
    left: 18px; right: 18px;
    padding: 12px;
    gap: 2px;
    border-radius: var(--r-card);
    background: #17171c;
    border: 1px solid var(--line);
    box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.8);
  }
  .nav.is-open a { padding: 14px 16px; font-size: 16px; }

  .hero { padding: 130px 0 84px; }

  .section { padding: 84px 0; }
  .panel__grid { grid-template-columns: 1fr; gap: 40px; }
  .flat__plan { grid-template-columns: 1fr; grid-template-areas: "master" "c1" "c2" "shared"; }
  .room--shared { grid-auto-flow: row; align-items: start; }

  .alts, .plans, .safes { grid-template-columns: 1fr; }
  .gap-stat { grid-template-columns: 1fr; gap: 24px; text-align: left; }

  /* Features stack: the copy leads on every one — flipped or not — and the
     phone stands centred underneath it. */
  .feature { padding: 64px 0; }
  .feature__grid,
  .feature--flip .feature__grid { grid-template-columns: 1fr; justify-items: center; gap: 44px; }
  .feature--flip .feature__copy { order: 0; }
  .feature__copy { justify-self: stretch; }
  .feature .phone { --ps: 0.7; }
}

@media (max-width: 560px) {
  body { font-size: 16px; }
  .people { grid-template-columns: 1fr; }
  .phone { --ps: 0.64; }          /* the device scales; nothing inside reflows */
  /* .feature .phone outranks the bare .phone above at every width, so each
     step of the small-screen ladder has to be restated for it. */
  .feature .phone { --ps: 0.64; }

  /* Stacked, centred, and capped — full-bleed buttons read as a form, not
     a landing page. 300px keeps clear air on both sides at every width. */
  .hero__cta,
  .contact__cta {
    flex-direction: column;
    align-items: center;
    width: 100%;
  }
  .hero__cta .btn,
  .contact__cta .btn {
    width: 100%;
    max-width: 300px;
  }

  .footer__meta { margin-left: 0; }
}

@media (max-width: 400px) {
  .feature .phone { --ps: 0.58; }
}
@media (max-width: 350px) {
  .feature .phone { --ps: 0.52; }
}

/* --------------------------------------------------------------------------
   Reduced motion — every scroll-driven effect resolves to its final state.
   main.js reads the same query and stops its rAF loop.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

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

  /* Each override restates the .js- (or @supports-) gated selector it must
     beat: a bare class here loses the cascade to the gated rule and the
     element stays invisible — that is a real shipped bug class, not theory. */
  .rise, .js .rise { opacity: 1; transform: none; }
  .problem__q em, .js .problem__q em { opacity: 1; transform: none; }
  .rhythm__at { width: var(--w); }
  .ticker__track { animation: none; }
  .feature .phone.rise, .js .feature .phone.rise { animation: none; }
}

/* --------------------------------------------------------------------------
   Forced colours (Windows high-contrast). The OS discards backgrounds and
   most borders' colours; explicit borders keep the structure legible.
   -------------------------------------------------------------------------- */
@media (forced-colors: active) {
  .btn,
  .alt,
  .party,
  .person,
  .plan,
  .safe,
  .alsos li,
  .lang,
  .nav-toggle,
  .flat,
  .room,
  .gap-stat,
  .contact,
  .phone {
    border: 1px solid;
    border-radius: var(--r-base);
  }

  .btn--primary { border-width: 3px; }

  :where(a, button, input, [tabindex]):focus-visible { outline: 3px solid; }

  .phone::after, .hero::before, .contact::before { display: none; }
}
.footer__meta a { color: inherit; text-decoration: none; }
.footer__meta a:hover { color: var(--ink); text-decoration: underline; }
