/* FLIP FLOW — DESIGN TOKENS · LIGHT (2026-09-08)
 *
 * Everett: "the MVP user interface should be more like airbnb." So the page got out of the way.
 * White ground, near-black type, and the photographs are the only colour on screen — which is the
 * actual mechanism behind Airbnb's grid, not the pink.
 *
 * THIS REPLACES THE DARK SATELLITE CONSOLE, and the old note was half right. Dark map tiles do read
 * as holes punched in white paper — but that is an argument about the MAP, not the GRID. Two hundred
 * seller photographs of Arizona houses are bright, dusty and warm, and on near-black they flattened
 * into identical grey rectangles. On white they separate. The map keeps a dark treatment inside its
 * own frame, where the tiles belong.
 *
 * WHAT IS NOT COPIED FROM AIRBNB. The accent stays Everett's Signal Blue, not Airbnb's pink — the
 * brand is his. And the cards keep their numbers: a traveller shops on desire and the photograph
 * sells the room, but a wholesale buyer shops on arithmetic. Strip the specs to three lines of prose
 * and you have deleted the thing they came for.
 */
:root{
  color-scheme: light;

  /* ── SURFACES ────────────────────────────────────────────────────────────────────────────────
     One ground, plus paper for the few things that must lift off it. Airbnb's grid has no card
     background at all — the photograph IS the card — so --card matches --bg on purpose. */
  --bg:#FFFFFF;
  --card:#FFFFFF;
  --sunk:#F7F7F7;
  --raised:#FFFFFF;
  --brand-surface:#006AFF;
  --deep:#FFFFFF;

  /* ── TEXT ────────────────────────────────────────────────────────────────────────────────────
     #1C1C1C rather than #000, because pure black on pure white vibrates at small sizes. Not
     #0B0B0B or #111 either: a tinted near-black impersonating black is its own tell. */
  --ink:#1C1C1C;
  --ink-2:#4A4A4F;         /* body and spec values — 8.9:1 */
  --ink-3:#6E6E73;         /* captions and provenance — 5.3:1, clears AA */

  /* ── LINES ───────────────────────────────────────────────────────────────────────────────────
     Hairlines only where a boundary carries information. The grid has none: cards are separated by
     space, which is the whole reason the page breathes. */
  --line:#EBEBEB;
  --line-2:#DDDDDD;
  --line-btn:#B0B0B5;

  /* ── ACTION ──────────────────────────────────────────────────────────────────────────────────
     Everett's blue, darkened for white. #007AFC is 3.1:1 here and fails AA for text; this is 4.6:1
     and passes. The brand survives the palette change, the contrast bug does not. */
  --blue:#006AFF;
  --blue-2:#0052CC;
  --blue-soft:#EAF2FF;
  --blue-deep:#0052CC;
  --link:#0052CC;

  /* ── STATUS — still earned, still rare ───────────────────────────────────────────────────────*/
  --green:#12805C;
  --green-ink:#FFFFFF;
  --green-soft:#E7F5EF;
  --amber:var(--ink-2);
  --violet:var(--blue);
  --teal:var(--blue);
  --red:#C4183C;
  --navy:#0052CC;
  --sold:#8E8E93;

  /* ── ELEVATION ───────────────────────────────────────────────────────────────────────────────
     Airbnb lifts almost nothing. One shadow for things that genuinely float, and a hairline ring on
     the photograph so a white house on a white page still has an edge. No shadow under a card. */
  --shadow:0 6px 16px rgba(0,0,0,.12);
  --shadow-media:inset 0 0 0 1px rgba(0,0,0,.06);
  --shadow-lg:0 12px 32px rgba(0,0,0,.14);

  --ink2:var(--ink-2); --ink3:var(--ink-3); --line2:var(--line-2);
  --accent:var(--blue); --good:var(--green);
  --bar:var(--bg); --dim:var(--ink-3); --fg:var(--ink); --bg-2:var(--sunk);

  /* ── TYPE ────────────────────────────────────────────────────────────────────────────────────
     Inter stands in for Circular: same geometric construction, already loaded, no new request. Card
     type is small and calm — the photograph carries the card and the price is the only heavy thing. */
  --font:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --t-xs:12px; --t-sm:13px; --t-base:15px; --t-md:var(--t-base);
  --t-lg:17px; --t-xl:22px; --t-2xl:32px;
  --t-hero:44px;    --track-hero:-.02em;
  --t-display:64px; --track-display:-.03em;
  --track-tight:-.01em;
  --track-label:.02em;

  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px; --s-6:40px; --s-7:64px; --s-8:96px;
  --section-gap:80px;

  /* ── SHAPE ───────────────────────────────────────────────────────────────────────────────────
     12px is the photograph. Everything else is quieter than the dark system, which used 24px cards
     and 100px pills to make shapes read against near-black. On white that reads as toy. */
  --r:12px;
  --r-sm:8px;
  --r-input:8px;
  --r-badge:6px;
  --r-pill:100px;
  --r-tag:100px;
}

/* ── COMPONENTS ───────────────────────────────────────────────────────────────────────────────
 * Deliberately few — the things every surface repeats. Prefixed ff- so they cannot collide. */
.ff-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font:inherit;
  font-size:var(--t-base);font-weight:500;letter-spacing:var(--track-tight);
  padding:12px 24px;border-radius:var(--r-pill);
  border:1px solid var(--line-btn);background:transparent;color:var(--ink);cursor:pointer;
  text-decoration:none;white-space:nowrap;transition:background .12s,border-color .12s,color .12s}
.ff-btn:hover{border-color:#fff;background:var(--raised)}

/* The one filled blue on the page. If there are two, one of them is wrong. */
.ff-btn-primary{background:var(--blue);border-color:transparent;color:#fff;font-weight:500}
.ff-btn-primary:hover{background:var(--blue-2);border-color:transparent;color:#fff}
.ff-btn:focus-visible,.ff-chip:focus-visible{outline:2px solid var(--blue);outline-offset:2px}

/* Sharp radius signals "tool", not "action". */
.ff-btn-util{border-radius:var(--r-input);border-color:#444D5A;padding:8px 10px}

.ff-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:var(--s-5)}
/* Media dissolves into the page instead of floating above it. */
.ff-media{border-radius:var(--r);overflow:hidden;position:relative}
.ff-media::after{content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:var(--shadow-media)}

.ff-chip{display:inline-flex;align-items:center;gap:4px;font-size:var(--t-xs);font-weight:500;
  letter-spacing:var(--track-tight);padding:5px 12px;border-radius:var(--r-pill);
  background:transparent;border:1px solid var(--line-2);color:var(--ink-2)}
.ff-chip[aria-pressed="true"],.ff-chip-on{background:var(--blue);border-color:transparent;color:#fff}
.ff-chip-info{background:var(--blue-deep);color:#fff;border-color:transparent;
  border-radius:var(--r-badge);font-size:var(--t-xs)}
/* Earned, and rare: the cartographic "new / live" green. */
.ff-chip-earned{background:var(--green);color:var(--green-ink);border-color:transparent;
  border-radius:var(--r-badge);font-weight:700;text-transform:uppercase;
  letter-spacing:var(--track-label);font-size:10px;padding:5px 8px}

.ff-input{width:100%;font:inherit;font-size:var(--t-base);padding:11px 14px;
  border:1px solid var(--line-2);border-radius:var(--r-input);background:var(--sunk);color:var(--ink)}
.ff-input::placeholder{color:var(--ink-3)}
.ff-input:focus{outline:none;border-color:var(--blue)}

/* All-caps section label — the eyebrow that sits above a block. */
.ff-eyebrow{font-size:11px;font-weight:500;text-transform:uppercase;
  letter-spacing:var(--track-label);color:#566171}

/* Numbers that sit in columns line up. */
.ff-num{font-variant-numeric:tabular-nums}

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

/* ── iOS ZOOM-ON-FOCUS ────────────────────────────────────────────────────────────────────────
   Everett, on the phone experience: "our mobile version should work like a mobile app". Nothing
   breaks that illusion faster than the page lurching and zooming the instant a field is tapped,
   and that is exactly what iOS Safari does whenever the focused input is under 16px. Every form on
   this site was 14px — the offer box, request access, the buy-box, the agent, and the new
   calculator — so tapping any of them jumped the layout and left the buyer pinch-zooming back out
   mid-offer.

   16px is a browser threshold, not a design preference. Phones only: the desktop type scale is
   untouched. !important is deliberate and is the narrow case it exists for — the 14px rules are
   class-scoped (.ask input, .pair input) and would otherwise outrank a bare element selector no
   matter where it sits in the file. */
@media (max-width:760px){
  input,select,textarea{font-size:16px !important}
}

/* NO SECOND TOKEN SCALE. A block here once declared --s-1..7, --r-1..3, --r-pill and --lift-1..3
   under the claim that "spacing, radius and elevation had no tokens". They all did, forty lines
   above: --s-1..8, --r / --r-sm / --r-input / --r-badge / --r-pill / --r-tag, and --shadow /
   --shadow-lg. Being later in the file, the duplicate WON — silently redefining --s-6 (40→32px),
   --s-7 (64→48px) and --r-pill (100→999px), the last of which .ff-btn actually uses.

   Nothing looked broken, which is the point: a parallel scale does not announce itself, it waits
   for the next person who writes var(--s-7) expecting 64px. The components that were built against
   it now use the real tokens instead. Read the file before adding to it. */

/* ── POPOVER ─────────────────────────────────────────────────────────────────────────────────────
   One component, two uses: the list-layout menu and the map-layers menu. Written once so the two
   cannot drift into looking like different products, which is exactly how this toolbar accumulated
   thirteen competing controls in the first place. */
.popwrap{position:relative;display:inline-flex}
.poptrigger{white-space:nowrap}
.popmenu{position:absolute;top:calc(100% + var(--s-2));left:0;z-index:620;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--shadow);padding:var(--s-1);min-width:172px;
  display:flex;flex-direction:column;gap:2px}
.popmenu[hidden]{display:none}
.popmenu > button{display:flex;align-items:center;justify-content:space-between;gap:var(--s-3);
  width:100%;text-align:left;background:none;border:0;border-radius:var(--r-badge);
  padding:10px var(--s-3);font:inherit;font-size:14px;color:var(--ink);cursor:pointer;
  min-height:40px}
.popmenu > button:hover{background:var(--sunk)}
.popmenu > button[aria-pressed="true"],
.popmenu > button[data-on="1"]{background:var(--blue-soft);color:var(--blue-deep);font-weight:600}
/* A checked layer says so in the menu; the trigger only carries the count. */
.popmenu > button[aria-pressed="true"]::after{content:"\2713";font-weight:700}
.popmenu-map{right:0;left:auto}

/* Saved is a collection, not a view mode — it reads as its own thing rather than a fifth tab. */
.savedchip{background:var(--card);border:1px solid var(--line-btn);border-radius:var(--r-pill);
  padding:8px 14px;font:inherit;font-size:13.5px;color:var(--ink);cursor:pointer;min-height:40px;
  display:inline-flex;align-items:center;gap:6px}
.savedchip[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff;font-weight:600}
.savedchip .n{background:var(--blue);color:#fff;border-radius:var(--r-pill);
  font-size:11px;font-weight:700;padding:1px 6px}
.poptrigger .n{background:var(--blue);color:#fff;border-radius:var(--r-pill);
  font-size:11px;font-weight:700;padding:1px 6px;margin-left:2px}

/* ── ALERT SIGNUP ────────────────────────────────────────────────────────────────────────────────
   Email, an optional mobile, and one unticked box. The consent line is the SAME STRING the server
   stores against the subscriber, so what a buyer agreed to and what the record says they agreed to
   cannot drift apart. */
.alertform{display:inline-flex;flex-wrap:wrap;align-items:center;gap:var(--s-2);max-width:100%}
.alertform input[type=email],.alertform input[type=tel]{
  font:inherit;font-size:14px;padding:9px 11px;border:1px solid var(--line-2);
  border-radius:var(--r-badge);background:var(--card);color:var(--ink);width:186px;min-height:44px}
.alertform .smsopt{display:flex;align-items:flex-start;gap:var(--s-2);flex:1 1 260px;
  font-size:12.5px;line-height:1.45;color:var(--ink-3);cursor:pointer;min-width:0}
.alertform .smsopt input{width:20px;height:20px;margin:1px 0 0;flex:0 0 auto;accent-color:var(--blue)}
@media (max-width:640px){
  .alertform{flex-direction:column;align-items:stretch;width:100%}
  .alertform input[type=email],.alertform input[type=tel]{width:100%}
}

/* ── BUY BOX RECEIPT ─────────────────────────────────────────────────────────────────────────────
   Sits above the results and names the box that produced them. Reasons once, not fifty times. */
.boxreceipt{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;
  padding:var(--s-3) var(--s-4);border:1px solid var(--line);border-radius:var(--r);
  background:var(--blue-soft);margin:0 0 var(--s-3)}
.boxreceipt[hidden]{display:none}
.brlead{font-size:13.5px;color:var(--ink-2);white-space:nowrap}
.brlead b{color:var(--ink);font-weight:700;font-size:15px}
.brchips{display:flex;gap:6px;flex-wrap:wrap;flex:1 1 auto;min-width:0}
.brchip{display:inline-flex;align-items:center;gap:6px;background:var(--card);
  border:1px solid var(--line-2);border-radius:var(--r-pill);padding:6px 10px;
  font:inherit;font-size:12.5px;color:var(--ink);cursor:pointer;min-height:32px}
.brchip:hover{border-color:var(--line-btn)}
.brchip em{font-style:normal;color:var(--ink-3);font-size:14px;line-height:1}
.brclear{background:none;border:0;color:var(--link);font:inherit;font-size:13px;
  cursor:pointer;padding:6px 4px;white-space:nowrap;min-height:32px}
@media (max-width:640px){ .brchip{min-height:36px} .brclear{min-height:36px} }
