/* ═══════════════════════════════════════════════════════════════════════════
   PACT v2 — shared design system
   Direction: light "porcelain workshop" adaptation of a dusk-workspace
   reference (frosted panels, hairline borders, pill controls, weight-500
   display type) re-grounded in Pact's own identity: pine-teal accent,
   IBM Plex Mono for money/metadata, warm-into-pine hero gradient.

   DARK MODE: every color routes through the tokens below. To enable dark
   mode, set data-theme="dark" on <html> — the token block is already
   populated. Nothing else needs to change.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Surfaces ── */
  --canvas:        #F4F5F7;                 /* page background — cool porcelain */
  --surface:       #FFFFFF;                 /* elevated panels, cards */
  --surface-2:     #ECEEF1;                 /* recessed wells, input fields */
  --glass:         rgba(255, 255, 255, 0.72); /* frosted floating panels */
  --glass-strong:  rgba(255, 255, 255, 0.88);
  --scrim:         rgba(23, 32, 31, 0.44);  /* modal backdrop */

  /* ── Ink ── */
  --ink:           #17201F;                 /* primary text — near-black w/ pine undertone */
  --ink-2:         #58635F;                 /* secondary text */
  --ink-3:         rgba(23, 32, 31, 0.42);  /* faint metadata */
  --hairline:      rgba(23, 32, 31, 0.12);  /* 1px borders — the only elevation line */
  --hairline-soft: rgba(23, 32, 31, 0.07);

  /* ── Accent (pine) — CTA fill, links, active states. Never a background wash. ── */
  --accent:        #1D3D3D;
  --accent-hover:  #16302F;
  --accent-ink:    #F4F5F7;                 /* text on accent */
  --accent-soft:   #DBE7E3;                 /* selected chips, marker fills */

  /* ── Semantic ── */
  --good:          #1F6B3A;
  --warn:          #885500;
  --bad:           #B3261E;
  --event:         #7A5C2E;                 /* event markers/tags — warm bronze */

  /* ── Hero gradient — the ONE gradient moment. Warm daylight bleeding into
        pine: a deal starting warm and ending secured. Hero sections only. ── */
  --grad-hero: linear-gradient(118deg,
      #F7ECDD 0%, #F0EBDF 26%, #DCE7E1 58%, #BBD3CB 86%, #A8C6BD 100%);

  /* ── Type ── */
  --font-sans: 'DM Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;

  /* ── Radius roles ── */
  --r-ui:    10px;      /* inputs, small controls */
  --r-card:  20px;      /* cards */
  --r-panel: 28px;      /* large framed panels (map frame, hero panel) */
  --r-pill:  9999px;    /* buttons, nav, chips, markers */

  /* ── Motion ── */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}

/* Dark theme — ready to enable with <html data-theme="dark">. */
[data-theme="dark"] {
  --canvas:        #0F1514;
  --surface:       #182020;
  --surface-2:     #1F2928;
  --glass:         rgba(24, 32, 32, 0.72);
  --glass-strong:  rgba(24, 32, 32, 0.9);
  --scrim:         rgba(0, 0, 0, 0.6);
  --ink:           #ECEFEA;
  --ink-2:         #A7B2AC;
  --ink-3:         rgba(236, 239, 234, 0.42);
  --hairline:      rgba(236, 239, 234, 0.14);
  --hairline-soft: rgba(236, 239, 234, 0.07);
  --accent:        #9FC6BB;
  --accent-hover:  #B7D6CC;
  --accent-ink:    #0F1514;
  --accent-soft:   #24403A;
  --good:          #7DC79B;
  --warn:          #D9A84E;
  --bad:           #E58579;
  --event:         #CBA96B;
  --grad-hero: linear-gradient(118deg,
      #26211A 0%, #202220 30%, #172724 65%, #12312B 100%);
}

/* ── Reset & base ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
/* Anchored targets clear the floating nav when deep-linked (#pricing etc.) */
[id] { scroll-margin-top: 96px; }
/* overflow-x:hidden on body alone doesn't fully constrain the root scrolling
   element on mobile — <html> can still report a wider "ideal" layout width
   from off-screen transformed content (e.g. .preview-panel's closed-state
   translateX), inflating window.innerWidth once any reflow runs. Set it on
   both. */
html { overflow-x: hidden; }
body {
  font-family: var(--font-sans);
  font-weight: 400;
  background: var(--canvas);
  color: var(--ink);
  font-size: 18px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: var(--accent); }
h1, h2, h3 { text-wrap: balance; }
::selection { background: var(--accent-soft); }

a:focus-visible, button:focus-visible, input:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.skip-link {
  position: absolute; left: 16px; top: -52px; z-index: 10000;
  background: var(--ink); color: var(--canvas); padding: 10px 18px;
  border-radius: var(--r-pill); font-size: 14px; font-weight: 500;
  text-decoration: none; transition: top 160ms var(--ease-out);
}
.skip-link:focus { top: 16px; }

/* ── Type roles ───────────────────────────────────────────────────────────── */
/* Display type is weight 500 with tight tracking — authority through
   restraint, never bold-shouting. This is a locked trait. */
.display {
  font-size: clamp(44px, 6.4vw, 74px);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.032em;
}
.h-lg { font-size: clamp(34px, 4vw, 48px); font-weight: 500; line-height: 1.08; letter-spacing: -0.025em; }
.h-md { font-size: clamp(25px, 2.6vw, 31px); font-weight: 500; line-height: 1.2; letter-spacing: -0.015em; }
.kicker {
  font-family: var(--font-mono);
  font-size: 12px; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-2);
}
.kicker--accent { color: var(--accent); }
.sub { font-size: 19px; line-height: 1.65; color: var(--ink-2); max-width: 56ch; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ── Layout ───────────────────────────────────────────────────────────────── */
.wrap { max-width: 1400px; margin: 0 auto; padding: 0 24px; }
.wrap--narrow { max-width: 780px; }
.section { padding: 88px 0; }
.section + .section { padding-top: 0; }
.section-head { margin-bottom: 44px; display: flex; flex-direction: column; gap: 14px; }

/* ── Floating frosted nav — the signature component. Detached pill, glass
      blur, hairline edge. Never flush against the viewport. ── */
.nav-wrap {
  position: fixed; top: 8px; left: 0; right: 0; z-index: 900;
  display: flex; justify-content: center; padding: 0 16px;
  pointer-events: none;
}
nav.pillnav {
  pointer-events: auto;
  display: flex; align-items: center; gap: 4px;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--ink) 16%, transparent);
  border-radius: var(--r-pill);
  padding: 8px 10px 8px 20px;
  box-shadow: 0 10px 30px -14px rgba(23, 32, 31, 0.55), 0 0 26px -6px rgba(23, 32, 31, 0.4);
  max-width: 720px; width: 100%;
}
/* PACT / MARKETPLACE stacked wordmark — same treatment as the live site */
.nav-logo {
  font-family: 'Instrument Serif', Georgia, serif; font-weight: 400; font-size: 27px;
  letter-spacing: -0.5px; text-transform: uppercase; line-height: 1;
  color: var(--ink); text-decoration: none; margin-right: auto;
  display: inline-block;
}
.nav-logo-sub {
  display: block; font-family: var(--font-mono); font-size: 8.5px; font-weight: 600;
  letter-spacing: 0.3em; color: var(--ink-3); margin-top: 3px; text-transform: uppercase;
}
.nav-links { display: flex; align-items: center; gap: 2px; list-style: none; }
.nav-links a {
  font-size: 14.5px; font-weight: 500; color: var(--ink-2);
  text-decoration: none; padding: 8px 13px; border-radius: var(--r-pill);
  transition: color 140ms ease, background 140ms ease;
}
.nav-links a:hover { color: var(--ink); background: var(--hairline-soft); }
.nav-links a[aria-current="page"] { color: var(--ink); background: var(--surface-2); }
.nav-cta {
  font-size: 14.5px; font-weight: 500; text-decoration: none;
  background: var(--accent); color: var(--accent-ink) !important;
  padding: 9px 18px; border-radius: var(--r-pill); margin-left: 8px;
  transition: transform 140ms var(--ease-out), background 140ms ease;
}
.nav-cta:hover { background: var(--accent-hover); }
.nav-hamburger {
  display: none; background: none; border: none; cursor: pointer;
  padding: 10px; border-radius: var(--r-pill); flex-direction: column; gap: 4px;
}
.nav-hamburger span { display: block; width: 18px; height: 1.6px; background: var(--ink); border-radius: 2px; }
.nav-mobile {
  display: none; position: fixed; top: 76px; left: 16px; right: 16px; z-index: 899;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--hairline); border-radius: var(--r-card);
  padding: 8px; flex-direction: column;
  box-shadow: 0 18px 44px -20px rgba(23, 32, 31, 0.4);
}
.nav-mobile.open { display: flex; }
.nav-mobile a {
  font-size: 17px; font-weight: 500; color: var(--ink); text-decoration: none;
  padding: 13px 16px; border-radius: 12px;
}
.nav-mobile a:hover { background: var(--hairline-soft); }
.nav-mobile a[aria-current="page"] { background: var(--surface-2); }
/* Log in / account controls, moved here from the top bar on mobile — see the
   ≤720px rule hiding .nav-auth. Get the app stays in the top bar; only the
   auth control relocates, since fitting Log in + Get the app + hamburger in
   one row wraps their text awkwardly at this width. */
.nav-mobile-auth { border-bottom: 1px solid var(--hairline); margin-bottom: 6px; padding-bottom: 6px; }
.nav-mobile-auth button {
  display: block; width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  font-family: var(--font-sans); font-size: 17px; font-weight: 500; color: var(--ink);
  padding: 13px 16px; border-radius: 12px;
}
.nav-mobile-auth button:hover { background: var(--hairline-soft); }
.nav-mobile-email {
  font-family: var(--font-mono); font-size: 12px; color: var(--ink-3);
  padding: 8px 16px 2px; word-break: break-all;
}
@media (max-width: 720px) {
  .nav-links { display: none; }
  .nav-hamburger { display: flex; }
}

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-sans); font-size: 17px; font-weight: 500;
  border-radius: var(--r-pill); padding: 13px 26px;
  text-decoration: none; cursor: pointer; border: 1px solid transparent;
  transition: transform 150ms var(--ease-out), background 150ms ease,
              border-color 150ms ease, color 150ms ease;
}
.btn:active { transform: scale(0.97); }
.btn--primary { background: var(--accent); color: var(--accent-ink); }
.btn--primary:hover { background: var(--accent-hover); }
.btn--ghost {
  background: transparent; color: var(--ink); border-color: var(--hairline);
}
.btn--ghost:hover { border-color: var(--ink-3); background: var(--hairline-soft); }
.btn--on-glass { background: var(--glass-strong); color: var(--ink); border-color: var(--hairline);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.btn--on-glass:hover { background: var(--surface); }
@media (prefers-reduced-motion: reduce) {
  .btn:active { transform: none; }
}

/* ── Cards & panels ───────────────────────────────────────────────────────── */
.card {
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-card); padding: 28px;
}
.panel {
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-panel); overflow: hidden;
}
.glass-card {
  background: var(--glass); border-radius: var(--r-card);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid var(--hairline); padding: 28px;
}

/* ── Numbered editorial rows (steps, capabilities) — typographic structure,
      no boxes. Mono index digits do the anchoring. ── */
.step-rows { display: flex; flex-direction: column; }
.step-row {
  display: grid; grid-template-columns: 64px 1fr; gap: 20px;
  padding: 26px 0; border-top: 1px solid var(--hairline);
  align-items: baseline;
}
.step-row:last-child { border-bottom: 1px solid var(--hairline); }
.step-num {
  font-family: var(--font-mono); font-size: 14px; font-weight: 600;
  color: var(--ink-3); letter-spacing: 0.1em;
}
.step-title { font-size: 21px; font-weight: 500; margin-bottom: 6px; letter-spacing: -0.01em; }
.step-body { font-size: 17px; color: var(--ink-2); line-height: 1.65; max-width: 58ch; }

/* ── Ledger line — Pact's own move: money always in mono, on a thin rule,
      like an entry in a ledger. ── */
.ledger-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 11px 0; border-bottom: 1px solid var(--hairline-soft);
  font-size: 16px; color: var(--ink-2);
}
.ledger-row:last-child { border-bottom: none; }
.ledger-row strong { font-family: var(--font-mono); font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.ledger-row.total { border-top: 1px solid var(--hairline); font-weight: 500; color: var(--ink); }

/* ── Trust strip — mono metadata band ── */
.trust-strip {
  display: flex; flex-wrap: wrap; gap: 10px 28px;
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2);
}
.trust-strip li { list-style: none; display: flex; align-items: center; gap: 8px; }
.trust-strip li::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); flex-shrink: 0;
}

/* ── Tags / chips ─────────────────────────────────────────────────────────── */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 14px; font-weight: 500; color: var(--ink-2);
  border: 1px solid var(--hairline); border-radius: var(--r-pill);
  padding: 7px 14px; background: var(--surface); cursor: pointer;
  transition: background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.chip:hover { border-color: var(--ink-3); }
.chip.active { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.tag {
  display: inline-block; font-family: var(--font-mono); font-size: 11px;
  font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 4px 10px; border-radius: var(--r-pill);
  background: var(--accent-soft); color: var(--accent);
}
.tag--event { background: color-mix(in srgb, var(--event) 16%, var(--surface)); color: var(--event); }
.tag--plain { background: var(--surface-2); color: var(--ink-2); }

/* ── FAQ (native details) ─────────────────────────────────────────────────── */
.faq details {
  border-top: 1px solid var(--hairline); padding: 4px 0;
}
.faq details:last-child { border-bottom: 1px solid var(--hairline); }
.faq summary {
  font-size: 18.5px; font-weight: 500; padding: 18px 36px 18px 0;
  cursor: pointer; list-style: none; position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+'; position: absolute; right: 4px; top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-mono); font-size: 20px; color: var(--ink-3);
  transition: transform 160ms var(--ease-out);
}
.faq details[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.faq .faq-a { font-size: 17px; color: var(--ink-2); line-height: 1.7; padding: 0 0 20px; max-width: 62ch; }
.faq .faq-a a { color: var(--accent); }

/* ── Comparison table ─────────────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--surface); }
table.compare { width: 100%; border-collapse: collapse; font-size: 16px; }
table.compare thead th {
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-2);
  text-align: left; padding: 14px 18px; border-bottom: 1px solid var(--hairline);
  white-space: nowrap; background: var(--surface-2);
}
table.compare tbody td { padding: 14px 18px; color: var(--ink-2); border-bottom: 1px solid var(--hairline-soft); vertical-align: middle; }
table.compare tbody tr:last-child td { border-bottom: none; }
table.compare .num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
table.compare tr.is-pact td { color: var(--ink); font-weight: 500; background: var(--accent-soft); }
table.compare tr.is-pact td:first-child { border-left: 3px solid var(--accent); }
.platform-name { font-weight: 600; color: var(--ink); white-space: nowrap; }
.platform-name a { color: inherit; text-decoration: underline; text-decoration-color: var(--hairline); text-underline-offset: 3px; }

/* ── Footer ───────────────────────────────────────────────────────────────── */
footer.site-footer {
  border-top: 1px solid var(--hairline);
  padding: 44px 0 56px; margin-top: 40px;
}
.footer-inner { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 24px; justify-content: space-between; }
.footer-logo { font-family: var(--font-mono); font-weight: 600; font-size: 17px; letter-spacing: 0.06em; text-transform: uppercase; }
.footer-links { display: flex; flex-wrap: wrap; gap: 6px 22px; list-style: none; }
.footer-links a { font-size: 14.5px; color: var(--ink-2); text-decoration: none; }
.footer-links a:hover { color: var(--ink); }
.footer-copy { width: 100%; font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); letter-spacing: 0.06em; }

/* ── Hero band ────────────────────────────────────────────────────────────── */
.hero-band {
  background: var(--grad-hero); /* base fallback if the video never paints */
  border-radius: 0 0 var(--r-panel) var(--r-panel);
  padding: 168px 0 72px;
  position: relative;
  overflow: hidden;
}
/* Media (image or video) fills the band edge-to-edge */
.hero-media,
.hero-media img,
.hero-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* The frost blur is applied to the media itself (not backdrop-filter): Chromium
   ghosts/flickers backdrop-filter layers while the Leaflet map repaints during
   panning. scale(1.12) hides the blurred-out edges. */
.hero-media img,
.hero-media video {
  object-fit: cover;
  filter: blur(24px) saturate(1.15);
  transform: scale(1.12);
}
/* Crossfading clips: only .is-active is visible; 2.8s must match FADE in the JS */
.hero-media video {
  opacity: 0;
  transition: opacity 2.8s ease;
}
.hero-media video.is-active { opacity: 1; }
/* Light canvas wash over the (pre-blurred) media so ink text keeps contrast
   no matter what the footage does. No backdrop-filter here — see .hero-media. */
.hero-frost {
  position: absolute;
  inset: 0;
  background: linear-gradient(118deg,
    color-mix(in srgb, var(--canvas) 55%, transparent) 0%,
    color-mix(in srgb, var(--canvas) 35%, transparent) 55%,
    color-mix(in srgb, var(--canvas) 20%, transparent) 100%);
}
.hero-band .wrap { position: relative; z-index: 1; }
.hero-band .sub { color: color-mix(in srgb, var(--ink) 72%, transparent); }
@media (prefers-reduced-motion: reduce) {
  .hero-media video { display: none; }
}
.page-hero { padding: 150px 0 24px; }

/* ═══════════════════════════════════════════════════════════════════════════
   HOME — live map & list
   ═══════════════════════════════════════════════════════════════════════════ */
.map-shell {
  position: relative;
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  overflow: hidden;
  background: var(--surface);
  height: clamp(520px, 72vh, 760px);
  /* Two layers: the original bottom-heavy lift, plus a second shadow with no
     vertical offset so the left/right edges get real shadow too instead of
     just whatever the first layer's blur radius reaches around the sides. */
  box-shadow: 0 10px 30px -14px rgba(23, 32, 31, 0.55), 0 0 26px -6px rgba(23, 32, 31, 0.4);
}
#map { position: absolute; inset: 0; z-index: 1; }

/* Floating map toolbar (glass, top of the frame) */
.map-toolbar {
  position: absolute; top: 14px; left: 14px; right: 14px; z-index: 500;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  pointer-events: none;
}
.map-toolbar > * { pointer-events: auto; }
.toolbar-group {
  display: flex; gap: 4px; align-items: center;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid var(--hairline); border-radius: var(--r-pill);
  padding: 4px;
}
.toolbar-group .tbtn {
  font-family: var(--font-sans); font-size: 14px; font-weight: 500;
  color: var(--ink-2); background: transparent; border: none; cursor: pointer;
  padding: 7px 14px; border-radius: var(--r-pill);
  transition: background 130ms ease, color 130ms ease;
}
.toolbar-group .tbtn:hover { color: var(--ink); }
.toolbar-group .tbtn.active { background: var(--accent); color: var(--accent-ink); }
/* Keyword search over listing title/description — same glass-pill treatment
   as .toolbar-group, sized to hold a text input instead of button chips. */
/* height:42px matches .map-search's rendered height exactly (driven there by
   its "Go" button's padding) — box-sizing:border-box so the explicit height
   includes the border, same as every other box on the page. */
.listing-search {
  box-sizing: border-box; height: 42px;
  display: flex; align-items: center;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid var(--hairline); border-radius: var(--r-pill);
  padding: 4px 4px 4px 16px;
  flex: 1 1 200px; min-width: 140px; max-width: 260px;
}
.listing-search input {
  border: none; background: transparent; outline: none;
  flex: 1; min-width: 0;
  font-family: var(--font-sans); font-size: 16px; color: var(--ink);
}
.listing-search input::placeholder { color: var(--ink-3); }
.listing-search-clear {
  display: none; border: none; background: none; cursor: pointer;
  color: var(--ink-3); font-size: 14px; padding: 8px 10px; line-height: 1; flex-shrink: 0;
}
.listing-search-clear.show { display: block; }
.listing-count {
  margin-left: auto;
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-2);
  background: var(--glass-strong); border: 1px solid var(--hairline);
  border-radius: var(--r-pill); padding: 8px 14px;
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}

/* Search pill (bottom-left of frame) */
.map-search {
  position: absolute; left: 14px; bottom: 14px; z-index: 500;
  display: flex; align-items: center; gap: 4px;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid var(--hairline); border-radius: var(--r-pill);
  padding: 4px 4px 4px 16px; max-width: min(340px, calc(100% - 28px));
}
.map-search input {
  border: none; background: transparent; outline: none;
  font-family: var(--font-sans); font-size: 16px; color: var(--ink);
  width: 200px; min-width: 0;
}
.map-search input::placeholder { color: var(--ink-3); }
.map-search button {
  font-size: 14px; font-weight: 500; border: none; cursor: pointer;
  background: var(--accent); color: var(--accent-ink);
  border-radius: var(--r-pill); padding: 8px 16px;
}
.search-error {
  position: absolute; left: 14px; bottom: 64px; z-index: 500; display: none;
  font-size: 13px; color: var(--bad); background: var(--glass-strong);
  border: 1px solid var(--hairline); border-radius: var(--r-ui); padding: 8px 12px;
}

/* Filter dropdown panel */
.filter-panel {
  position: absolute; top: 62px; left: 14px; z-index: 600; display: none;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--hairline); border-radius: var(--r-card);
  box-shadow: 0 18px 44px -20px rgba(23, 32, 31, 0.4);
  padding: 18px; width: min(420px, calc(100% - 28px));
}
.filter-panel.open { display: block; }
.filter-panel-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.filter-panel-title { font-family: var(--font-mono); font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2); }
.filter-clear { font-size: 13.5px; color: var(--accent); background: none; border: none; cursor: pointer; font-weight: 500; }
.filter-section-label { font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); margin: 12px 0 8px; }
.filter-chip-row { display: flex; flex-wrap: wrap; gap: 6px; }
.recent-panel { min-width: 240px; max-width: 320px; }
.recent-item {
  display: block; width: 100%; text-align: left; background: none; border: none;
  font-family: var(--font-sans); font-size: 13.5px; font-weight: 500; color: var(--ink);
  padding: 8px 10px; border-radius: var(--r-ui); cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.recent-item:hover { background: var(--hairline-soft); }
.recent-empty { font-size: 13px; color: var(--ink-3); padding: 8px 10px; }
.fchip {
  font-family: var(--font-sans); font-size: 13.5px; font-weight: 500;
  color: var(--ink-2); background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-pill); padding: 6px 12px; cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.fchip.active { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }

/* List view overlay */
.list-view {
  position: absolute; inset: 0; z-index: 400; display: none;
  background: var(--canvas); overflow-y: auto;
  padding: 66px 14px 14px;
}
.list-view.active { display: block; }
.list-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
}
.list-card {
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-card); overflow: hidden; cursor: pointer;
  transition: border-color 140ms ease, transform 150ms var(--ease-out);
}
.list-card:hover { border-color: var(--ink-3); }
.list-card:active { transform: scale(0.985); }
.list-card.selected { border-color: var(--accent); }
.list-card-img { width: 100%; height: 140px; object-fit: cover; }
.list-card-ph {
  width: 100%; height: 140px; display: flex; align-items: center;
  justify-content: center; font-size: 38px; background: var(--surface-2); opacity: 0.6;
}
.list-card-body { padding: 14px 16px 16px; }
.list-card-tags { display: flex; gap: 6px; margin-bottom: 8px; }
.list-card-title { font-size: 17px; font-weight: 500; line-height: 1.35; margin-bottom: 8px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.list-card-price { font-family: var(--font-mono); font-size: 18px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.list-card-price span { font-family: var(--font-sans); font-size: 12px; font-weight: 400; color: var(--ink-3); margin-left: 6px; }
.list-card-loc { font-size: 13px; color: var(--ink-3); margin-top: 8px; }
.list-empty { grid-column: 1 / -1; text-align: center; color: var(--ink-3); font-size: 16px; padding: 60px 20px; }

/* Preview drawer */
.preview-panel {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 700;
  width: min(400px, 100%);
  background: var(--surface); border-left: 1px solid var(--hairline);
  transform: translateX(calc(100% + 20px));
  transition: transform 260ms var(--ease-out);
  display: flex; flex-direction: column;
}
.preview-panel.listing-open { transform: translateX(0); }
.preview-head {
  display: flex; justify-content: flex-end; padding: 12px;
  border-bottom: 1px solid var(--hairline-soft); flex-shrink: 0;
}
.preview-close {
  background: var(--surface-2); border: 1px solid var(--hairline);
  border-radius: var(--r-pill); width: 34px; height: 34px; cursor: pointer;
  font-size: 16px; color: var(--ink); display: flex; align-items: center; justify-content: center;
}
.preview-scroll { overflow-y: auto; flex: 1; }
.preview-gallery { position: relative; }
.preview-image { width: 100%; height: 220px; object-fit: cover; cursor: zoom-in; }
.preview-image-placeholder {
  width: 100%; height: 220px; display: flex; align-items: center;
  justify-content: center; font-size: 48px; background: var(--surface-2); opacity: 0.6;
}
/* Prev/next controls overlaid on the preview panel's gallery image — only
   rendered when a listing has more than one photo (see showPreview). */
.gallery-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; border-radius: var(--r-pill); border: none;
  background: rgba(0,0,0,0.45); color: #fff; font-size: 20px; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.gallery-arrow:hover { background: rgba(0,0,0,0.65); }
.gallery-arrow--prev { left: 10px; }
.gallery-arrow--next { right: 10px; }
.gallery-counter {
  position: absolute; bottom: 10px; right: 10px;
  background: rgba(0,0,0,0.55); color: #fff; font-family: var(--font-mono);
  font-size: 11px; padding: 3px 8px; border-radius: var(--r-pill);
}

/* Full-resolution lightbox — click the preview gallery image to open. Reuses
   the arrImageUrls originals (the gallery itself shows arrThumbUrls). */
.lightbox {
  position: fixed; inset: 0; z-index: 2200; display: none;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.9); padding: 40px;
}
.lightbox.open { display: flex; }
.lightbox-img { max-width: 100%; max-height: 100%; object-fit: contain; }
.lightbox-close {
  position: absolute; top: 20px; right: 20px;
  width: 40px; height: 40px; border-radius: var(--r-pill); border: none;
  background: rgba(255,255,255,0.15); color: #fff; font-size: 16px; cursor: pointer;
}
.lightbox-close:hover { background: rgba(255,255,255,0.28); }
.lightbox-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 48px; height: 48px; border-radius: var(--r-pill); border: none;
  background: rgba(255,255,255,0.15); color: #fff; font-size: 28px; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.lightbox-arrow:hover { background: rgba(255,255,255,0.28); }
.lightbox-arrow--prev { left: 20px; }
.lightbox-arrow--next { right: 20px; }
.lightbox-counter {
  position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);
  color: #fff; font-family: var(--font-mono); font-size: 12px;
  background: rgba(255,255,255,0.15); padding: 4px 12px; border-radius: var(--r-pill);
}
.preview-body { padding: 20px; }
.preview-tags { display: flex; align-items: center; gap: 6px; margin-bottom: 12px; }
.preview-title { font-size: 24px; font-weight: 500; line-height: 1.25; letter-spacing: -0.01em; margin-bottom: 10px; }
.preview-price { font-family: var(--font-mono); font-size: 27px; font-weight: 600; font-variant-numeric: tabular-nums; margin-bottom: 6px; }
.preview-price span { font-family: var(--font-sans); font-size: 13px; font-weight: 400; color: var(--ink-3); margin-left: 8px; }
.preview-actions { display: flex; flex-direction: column; gap: 8px; margin-bottom: 20px; }
.preview-cta {
  width: 100%; font-family: var(--font-sans); font-size: 17px; font-weight: 500;
  background: var(--accent); color: var(--accent-ink); border: none; cursor: pointer;
  border-radius: var(--r-pill); padding: 14px;
  transition: transform 150ms var(--ease-out), background 150ms ease;
}
.preview-cta:hover { background: var(--accent-hover); }
.preview-cta:active { transform: scale(0.98); }
.preview-share {
  width: 100%; font-family: var(--font-sans); font-size: 16px; font-weight: 500;
  background: transparent; color: var(--ink); border: 1px solid var(--hairline);
  cursor: pointer; border-radius: var(--r-pill); padding: 12px;
}
.preview-share:hover { border-color: var(--ink-3); }

/* Map markers — pill silhouettes, mono figures */
.pact-marker {
  font-family: var(--font-mono); font-size: 12.5px; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  padding: 5px 11px; border-radius: var(--r-pill);
  border: 1px solid var(--hairline);
  box-shadow: 0 4px 14px -6px rgba(23, 32, 31, 0.45);
  cursor: pointer; display: inline-block;
}
/* Matches the classic site's marker colors exactly, so both maps read the
   same regardless of which theme's page you're on. */
.pact-marker.buy   { background: #8CA352; color: #fff; border-color: #8CA352; }
.pact-marker.sell  { background: #D06A34; color: #fff; border-color: #D06A34; }
.pact-marker.event { background: #E3AC42; color: #fff; border-color: #E3AC42; }
/* Cluster circles: single-hue intensity scale — pale teal for a small
   cluster, full teal for a large one. Matches the classic site's cluster
   color exactly (its own accent teal), rather than porcelain's own pine
   accent, so both maps' clusters read as the same system. */
.marker-cluster-small, .marker-cluster-medium, .marker-cluster-large { background: transparent !important; }
.marker-cluster div {
  border: none !important;
  border-radius: 50% !important;
  font-family: var(--font-mono) !important; font-weight: 700 !important; font-size: 13px !important;
  box-shadow: 0 4px 14px -4px rgba(23, 32, 31, 0.5);
  width: 36px !important; height: 36px !important;
  display: flex; align-items: center; justify-content: center;
}
.marker-cluster-small div  { background: color-mix(in srgb, #006B7D 30%, var(--canvas)) !important; color: var(--ink) !important; }
.marker-cluster-medium div { background: color-mix(in srgb, #006B7D 60%, var(--canvas)) !important; color: #fff !important; }
.marker-cluster-large div  { background: #006B7D !important; color: #fff !important; }
.leaflet-container { font-family: var(--font-sans); background: var(--surface-2); }

/* App prompt modal */
.app-prompt {
  position: fixed; inset: 0; z-index: 2000; display: none;
  align-items: center; justify-content: center;
  background: var(--scrim); padding: 20px;
}
.app-prompt.open { display: flex; }
.app-prompt-card {
  position: relative; background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-panel); padding: 34px 30px; max-width: 380px; width: 100%;
}
.app-prompt-close {
  position: absolute; top: 14px; right: 14px;
  background: var(--surface-2); border: 1px solid var(--hairline);
  border-radius: var(--r-pill); width: 32px; height: 32px; cursor: pointer;
  color: var(--ink); font-size: 14px;
}
.app-prompt-title { font-size: 23px; font-weight: 500; letter-spacing: -0.01em; margin-bottom: 8px; }
.app-prompt-text { font-size: 16px; color: var(--ink-2); line-height: 1.6; margin-bottom: 20px; }
.app-prompt-qr { text-align: center; margin-bottom: 20px; }
.app-prompt-qr-code {
  display: inline-block; background: #fff; border: 1px solid var(--hairline);
  border-radius: var(--r-ui); padding: 10px;
}
.app-prompt-qr-code svg { display: block; width: 148px; height: 148px; }
.app-prompt-qr-hint { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); margin-top: 8px; letter-spacing: 0.04em; }
.app-prompt-btns { display: flex; flex-direction: column; gap: 8px; }
.app-prompt-store {
  display: block; text-align: center; font-size: 16px; font-weight: 500;
  text-decoration: none; border-radius: var(--r-pill); padding: 13px;
  background: var(--accent); color: var(--accent-ink);
}
.app-prompt-store + .app-prompt-store { background: transparent; color: var(--ink); border: 1px solid var(--hairline); }

/* ═══════════════════════════════════════════════════════════════════════════
   WHY — pricing calculator
   ═══════════════════════════════════════════════════════════════════════════ */
.calc-panel { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--surface); overflow: hidden; }
@media (max-width: 640px) { .calc-panel { grid-template-columns: 1fr; } }
.calc-col { padding: 30px 28px; }
.calc-col + .calc-col { border-left: 1px solid var(--hairline); }
@media (max-width: 640px) { .calc-col + .calc-col { border-left: none; border-top: 1px solid var(--hairline); } }
.calc-role { font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); margin-bottom: 12px; }
.calc-amount { font-family: var(--font-mono); font-size: clamp(31px, 4.4vw, 42px); font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1; margin-bottom: 6px; }
.calc-amount .amt-tax { font-family: var(--font-sans); font-size: 14px; font-weight: 400; color: var(--ink-3); }
.calc-note-sm { font-size: 13px; color: var(--ink-2); margin-bottom: 20px; }
.price-slider { max-width: 520px; margin: 0 0 30px; }
.price-slider-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 14px; }
.price-slider-label { font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2); }
.price-input-wrap { display: inline-flex; align-items: baseline; }
.price-dollar { font-family: var(--font-mono); font-size: 29px; font-weight: 600; }
.price-input {
  font-family: var(--font-mono); font-size: 29px; font-weight: 600; color: var(--ink);
  border: none; background: transparent; padding: 0 0 2px; width: 3ch;
  outline: none; border-bottom: 1.5px dashed var(--ink-3);
}
.price-input:focus { border-bottom-color: var(--accent); border-bottom-style: solid; }
.price-range { -webkit-appearance: none; appearance: none; width: 100%; height: 4px; background: var(--hairline); border-radius: var(--r-pill); outline: none; cursor: pointer; }
.price-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 26px; height: 26px;
  border-radius: 50%; background: var(--accent); border: 3px solid var(--surface);
  box-shadow: 0 2px 8px -2px rgba(23,32,31,0.4); cursor: pointer;
}
.price-range::-moz-range-thumb { width: 22px; height: 22px; border-radius: 50%; background: var(--accent); border: 3px solid var(--surface); cursor: pointer; }
.pricing-note { font-size: 13.5px; color: var(--ink-3); margin-top: 22px; line-height: 1.7; max-width: 68ch; }

/* vs blocks */
.vs-block { border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--surface); padding: 26px 28px; margin-bottom: 14px; }
.vs-block h3 { font-size: 21px; font-weight: 500; letter-spacing: -0.01em; margin-bottom: 10px; }
.vs-block p { font-size: 16.5px; color: var(--ink-2); line-height: 1.75; margin-bottom: 10px; }
.advantage-label { font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); margin: 14px 0 6px; }
.hold-block { border-left: 2px solid var(--accent); padding: 2px 0 2px 18px; margin: 14px 0; }
.hold-block p { font-size: 16.5px; color: var(--ink-2); line-height: 1.75; margin-bottom: 8px; }
.bottom-line {
  background: var(--accent); color: var(--accent-ink);
  border-radius: var(--r-panel); padding: 40px 36px; margin-top: 48px;
}
.bottom-line-title { font-size: clamp(27px, 3vw, 36px); font-weight: 500; letter-spacing: -0.02em; margin-bottom: 14px; }
/* .wrap prefix bumps specificity above .prose p/.prose strong (equal
   specificity otherwise, defined later in the file) — .bottom-line always
   sits inside .wrap.prose on why.html, so without this, .prose's sitewide
   --ink-2 gray silently wins and reads as barely-visible text over the dark
   --accent background it was never designed for. */
.wrap .bottom-line p { font-size: 17px; line-height: 1.75; color: color-mix(in srgb, var(--accent-ink) 82%, transparent); margin-bottom: 12px; }
.bottom-line p:last-child { margin-bottom: 0; }
.wrap .bottom-line strong { color: var(--accent-ink); }

/* ═══════════════════════════════════════════════════════════════════════════
   Shared content patterns
   ═══════════════════════════════════════════════════════════════════════════ */
.two-col { display: grid; grid-template-columns: 5fr 7fr; gap: 48px; align-items: start; }
@media (max-width: 860px) { .two-col { grid-template-columns: 1fr; gap: 28px; } }
.pillar-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 720px) { .pillar-grid { grid-template-columns: 1fr; } }
.pillar-card { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--r-card); padding: 26px; }
.pillar-card .tag { margin-bottom: 14px; }
.pillar-title { font-size: 21px; font-weight: 500; letter-spacing: -0.01em; margin-bottom: 8px; }
.pillar-desc { font-size: 16.5px; color: var(--ink-2); line-height: 1.65; margin-bottom: 14px; }
.pillar-examples { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; }
.pillar-examples li { font-family: var(--font-mono); font-size: 12px; color: var(--ink-2); background: var(--surface-2); border-radius: var(--r-pill); padding: 4px 11px; }

.cta-band {
  background: var(--accent); border-radius: var(--r-panel);
  padding: 64px 40px; text-align: center; color: var(--accent-ink);
}
.cta-band h2 { font-size: clamp(29px, 3.6vw, 42px); font-weight: 500; letter-spacing: -0.02em; margin-bottom: 10px; }
.cta-band p { font-size: 17.5px; color: color-mix(in srgb, var(--accent-ink) 78%, transparent); margin-bottom: 28px; }
.cta-band .btns { display: flex; align-items: center; gap: 10px; justify-content: center; flex-wrap: wrap; }
.cta-band .btn--primary { background: var(--accent-ink); color: var(--accent); }
.cta-band .btn--ghost { color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent-ink) 34%, transparent); }
.cta-band .btn--ghost:hover { border-color: var(--accent-ink); background: transparent; }
/* .hero-region-badge's margin-top:18px is for stacking below other hero
   content elsewhere — here it's a flex sibling of the store buttons, so that
   margin would just add unwanted top-alignment offset within the row. */
.cta-band .hero-region-badge { margin-top: 0; }

/* prose pages (flow) */
.prose h2 { font-size: clamp(25px, 3vw, 31px); font-weight: 500; letter-spacing: -0.015em; margin: 52px 0 14px; }
.prose p { font-size: 17.5px; color: var(--ink-2); line-height: 1.8; margin-bottom: 14px; max-width: 66ch; }
.prose strong { color: var(--ink); font-weight: 600; }
.prose ul { padding-left: 20px; margin-bottom: 16px; }
.prose li { font-size: 17px; color: var(--ink-2); line-height: 1.75; margin-bottom: 10px; }
.prose h3 { font-size: 18px; font-weight: 600; color: var(--ink); margin: 26px 0 8px; }
.prose a { color: var(--accent); }

/* legal / document pages */
.doc-meta {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-3); display: block; margin-bottom: 8px;
}
.back-link {
  display: inline-block; margin-top: 44px;
  font-family: var(--font-mono); font-size: 13px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--accent); text-decoration: none;
}
.back-link:hover { text-decoration: underline; }
.state-flow {
  font-family: var(--font-mono); font-size: 13.5px; line-height: 2.1;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-card); padding: 20px 24px; margin: 18px 0;
  color: var(--ink-2);
}
.state-flow b { color: var(--accent); font-weight: 600; }
.state-flow .arr { color: var(--ink-3); padding: 0 6px; }

@media (max-width: 640px) {
  .section { padding: 64px 0; }
  .hero-band { padding: 140px 0 56px; }

  /* Map bleeds to the viewport edges, past the .wrap's 24px padding. */
  .map-shell {
    margin-left: -24px; margin-right: -24px;
    width: calc(100% + 48px);
    border-radius: 0;
    border-left: none; border-right: none;
  }
  .listing-count { display: none; }

  /* View toggle rejoins the search bar as one bottom row instead of sitting
     in the top toolbar (matches the reference mobile layout). The toggle
     group itself is relocated into #mapBottomRow by JS at this breakpoint
     (see the script at the bottom of the page) — once it's here, it's just
     a normal flex child, same as .map-search. "Saved" always stays in the
     top toolbar next to Filter, regardless of width. */
  .map-bottom-row {
    position: absolute; left: 14px; right: 14px; bottom: 14px; z-index: 500;
    display: flex; align-items: center; gap: 8px;
  }
  .map-bottom-row #viewToggleGroup { flex-shrink: 0; }
  /* min-width:0 overrides the flex-item default of min-width:auto, which
     otherwise floors this at its content's intrinsic width (the input's
     fixed 200px) and pushes the Go button off the right edge of the row. */
  .map-bottom-row .map-search { position: static; flex: 1; max-width: none; min-width: 0; }
  /* flex:1 (not just width:auto) so the input actually grows to fill the row
     at any width — without it, the input keeps its own small content-based
     size, leaving the search bar's outer box (which does stretch via its
     own flex:1) to stretch empty past the button before the true edge. */
  .map-bottom-row .map-search input { flex: 1; width: auto; min-width: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   APP SHELL — home page (index.html): static (not floating)
   nav docked above a dismissible intro banner and the live map, followed by
   the same How-it-works/footer content as the marketing pages. Reuses every
   token/component above; only overrides nav positioning and map height.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Sticky-footer layout: main grows to consume exactly whatever vertical space
   the nav/banner/footer don't need, so the footer sits flush after the map
   with no dead gap — whether the viewport is short or very tall, and whether
   the banner is open or closed. */
body.app-shell { display: flex; flex-direction: column; min-height: 100vh; }
/* Nav floats the same way as every other page (position:fixed, see the base
   .nav-wrap rule) instead of being docked in flow — .home-hero below carries
   its own margin-top to clear it, same pattern as .hero-band/.page-hero. */
body.app-shell .site-footer { flex-shrink: 0; }
/* The map page's footer is chrome, not a destination — compact it at every
   width (the marketing pages keep the full-size footer). */
body.app-shell .site-footer { margin-top: 4px; padding: 14px 0 16px; }
body.app-shell .site-footer .footer-inner { gap: 6px 16px; align-items: baseline; }
body.app-shell .site-footer .footer-logo { font-size: 14px; }
body.app-shell .site-footer .footer-links a,
body.app-shell .site-footer .footer-links .footer-link-btn { font-size: 12.5px; }
body.app-shell .site-footer .footer-copy { font-size: 10.5px; }
body.app-shell .app-main { flex: 1; display: flex; padding: 16px; }
/* Cap the map at the same width as .wrap/.home-hero-inner (1400px) and
   center it, instead of stretching edge-to-edge — keeps it visually aligned
   with the hero/footer content above and below it. */
body.app-shell .app-main .map-shell { flex: 1; height: auto; min-height: 520px; max-width: 1400px; margin: 0 auto; }
/* The map bleeds edge-to-edge below 640px (existing .map-shell mobile rule),
   so the surrounding gutter that separates it from the footer above should
   shrink to match — otherwise the padding + footer's margin-top stack into
   a much more noticeable dead band on a short mobile screen. */
@media (max-width: 640px) {
  body.app-shell .app-main { padding-bottom: 0; }
  /* On a narrow mobile screen the links wrap onto 3 lines and the row-gaps
     compound, so tighten further than the all-width compact rules above. */
  body.app-shell .site-footer { padding: 10px 0 12px; }
  /* Un-wrap the <ul> so each <li> becomes a direct flex item next to
     .footer-logo instead of the whole list moving to its own line first. */
  body.app-shell .site-footer .footer-inner { gap: 4px 10px; justify-content: flex-start; }
  body.app-shell .site-footer .footer-logo { font-size: 13px; }
  body.app-shell .site-footer .footer-links { display: contents; }
  body.app-shell .site-footer .footer-links a,
  body.app-shell .site-footer .footer-links .footer-link-btn { font-size: 11.5px; }
  body.app-shell .site-footer .footer-copy { font-size: 10px; }
}

/* Collapsible intro banner above the map — split into the pitch (left) and a
   compact How-it-works recap (right) via .two-col. Collapsing hides
   .home-hero-inner but keeps the banner itself (and the toggle) on screen as
   a slim strip, so it's never fully gone — just one click to bring back. */
/* margin-top clears the floating nav (position:fixed, top:18px — see the
   base .nav-wrap rule) the same way .hero-band/.page-hero's padding-top does
   on every other page — kept separate from the padding below so clearing the
   nav doesn't also throw off the collapsed row's own internal centering. */
/* TEST: dark accent background with text flipped light — same color-flip
   convention .cta-band already uses elsewhere for accent-background blocks. */
.home-hero { border-bottom: 1px solid var(--hairline); background: var(--accent); position: relative; margin-top: 74px; padding: 26px 16px 20px; flex-shrink: 0; transition: padding 160ms var(--ease-out); }
.home-hero-inner h1 { color: var(--accent-ink); }
.home-hero .step-num { color: color-mix(in srgb, var(--accent-ink) 55%, transparent); }
.home-hero .step-title { color: var(--accent-ink); }
.home-hero .kicker { color: var(--accent-ink); }
.home-hero-btns .btn--primary { background: var(--accent-ink); color: var(--accent); }
.home-hero-btns .btn--primary:hover { background: color-mix(in srgb, var(--accent-ink) 88%, transparent); }
.home-hero-btns .btn--ghost { background: transparent; color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent-ink) 34%, transparent); }
.home-hero-btns .btn--ghost:hover { border-color: var(--accent-ink); background: color-mix(in srgb, var(--accent-ink) 12%, transparent); }
/* .home-hero-controls is position:absolute, so it doesn't contribute to this
   container's height on its own — without a min-height, collapsing (which
   hides the only in-flow content, .home-hero-inner) would shrink .home-hero
   to just its padding and clip the toggle button. The controls' top offset is
   pulled in to match the collapsed padding (was still using the expanded
   state's 14px, leaving a lopsided gap below the button); min-height is sized
   to exactly padding + button height, no extra buffer. */
.home-hero.collapsed { padding-top: 10px; padding-bottom: 10px; min-height: 50px; }
.home-hero.collapsed .home-hero-inner { display: none; }
.home-hero-inner { max-width: 1400px; margin: 0 auto; padding-right: 140px; }
/* Override the default 5fr/7fr split with even columns, so the pitch and the
   How-it-works recap grow together and stay visually balanced as the banner
   widens, instead of one side stretching far past the other. */
.home-hero-inner.two-col { grid-template-columns: 1fr 1fr; gap: 56px; }
.home-hero-sub { margin: 10px 0 18px; color: color-mix(in srgb, var(--accent-ink) 82%, transparent); }
.home-hero .step-body { color: color-mix(in srgb, var(--accent-ink) 82%, transparent); }
.home-hero-btns { display: flex; gap: 10px; flex-wrap: wrap; }
.home-hero-controls { position: absolute; top: 14px; right: 16px; display: flex; align-items: center; gap: 12px; }
/* Collapsed: stretch the controls row edge-to-edge so the tagline can sit at
   the far left, opposite the toggle, instead of huddled together at right:16. */
.home-hero.collapsed .home-hero-controls { top: 10px; left: 16px; justify-content: space-between; }
.home-hero-collapsed-tagline {
  display: none; flex: 1; font-family: var(--font-sans); font-size: 15px; font-weight: 500; color: var(--accent-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; text-align: center;
}
.home-hero.collapsed .home-hero-collapsed-tagline { display: block; }
.home-hero-toggle {
  height: 30px; border: 1px solid var(--hairline); background: var(--surface-2);
  border-radius: var(--r-pill); color: var(--ink); cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 0 14px; flex-shrink: 0;
}
/* Opaque darken instead of var(--hairline-soft) (a transparent dark tint) —
   this button sits on the dark --accent hero background, where a transparent
   overlay just blends into the backdrop instead of visibly darkening the
   button's own opaque --surface-2 fill. */
.home-hero-toggle:hover { background: color-mix(in srgb, var(--surface-2), var(--ink) 10%); }
.home-hero-toggle-label { font-family: var(--font-sans); font-size: 13.5px; font-weight: 500; }
.home-hero-toggle-icon { font-size: 12px; line-height: 1; }
@media (max-width: 900px) {
  .home-hero-inner.two-col { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .home-hero-controls { position: static; justify-content: flex-end; margin-bottom: 12px; }
  .home-hero.collapsed .home-hero-controls { margin-bottom: 0; }
  .home-hero-inner { padding-right: 0; }
  .home-hero { padding: 16px 16px 18px; }
  /* "Get the app" / "How a Pact works" / the region badge were three
     different widths stacked with gaps between them — reads as clutter at
     this width. Full-width + consistent alignment turns them into one clean
     button stack instead. */
  .home-hero-btns { flex-direction: column; }
  .home-hero-btns .btn { width: 100%; justify-content: center; }
  .hero-region-badge { width: 100%; }
}

/* Compact How-it-works variant — used wherever the full-size .step-row/.two-col
   spacing (about/flow/why's own sections) would be too tall. */
.hiw-compact .step-row { padding: 12px 0; }
.hiw-compact .step-row:first-child { border-top: none; padding-top: 0; }
/* step-body matches .sub (the pitch description's font-size) exactly per
   request; title/kicker scaled up by the same ratio (19/14) to keep the
   same relative hierarchy rather than flattening everything to one size. */
.hiw-compact .kicker { font-size: 16px; }
.hiw-compact .step-title { font-size: 22px; margin-bottom: 3px; }
.hiw-compact .step-body { font-size: 19px; line-height: 1.5; }

/* ═══════════════════════════════════════════════════════════════════════════
   TEST: web login + saved listings (sandbox — not on the live site)
   ═══════════════════════════════════════════════════════════════════════════ */

/* Nav auth pill — its own detached glass pill on the right, same visual
   language as nav.pillnav (glass blur, hairline border, shadow). position:fixed
   with its own right:16px anchor keeps it fully independent of .nav-wrap's
   flex centering, so adding/removing it never shifts nav.pillnav off-center —
   the two pills float independently instead of being centered as a group. */
.nav-auth-pill {
  position: fixed; top: 8px; right: 16px; z-index: 900;
  pointer-events: auto;
  display: flex; align-items: center;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--ink) 16%, transparent);
  border-radius: var(--r-pill);
  padding: 4px;
  box-shadow: 0 10px 30px -14px rgba(23, 32, 31, 0.55), 0 0 26px -6px rgba(23, 32, 31, 0.4);
}
/* Hidden below 720px — Log in moves into the hamburger menu (.nav-mobile-auth)
   there instead, since Log in + Get the app + hamburger all fitting in one
   row at that width wraps their button text awkwardly. This rule must stay
   after the .nav-auth-pill definition above: same specificity, source order wins. */
@media (max-width: 720px) {
  .nav-auth-pill { display: none; }
}
.nav-auth-btn {
  font-size: 14.5px; font-weight: 500; color: var(--ink); background: none;
  border: none; border-radius: var(--r-pill);
  padding: 8px 16px; cursor: pointer;
  transition: background 140ms ease;
}
.nav-auth-btn:hover { background: var(--hairline-soft); }
.nav-saved-btn {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 14.5px; font-weight: 500; color: var(--ink); background: var(--surface-2);
  border: 1px solid var(--hairline); border-radius: var(--r-pill);
  padding: 8px 16px; cursor: pointer;
}
.nav-saved-btn.active { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.nav-saved-btn .heart { color: var(--bad); }
.nav-account {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  font-size: 13px; font-weight: 600; cursor: pointer; border: none;
}
.nav-account-menu {
  display: none; position: absolute; top: 64px; right: 16px; z-index: 950;
  pointer-events: auto;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid var(--hairline); border-radius: var(--r-card);
  padding: 8px; min-width: 180px;
  box-shadow: 0 18px 44px -20px rgba(23, 32, 31, 0.4);
}
.nav-account-menu.open { display: block; }
.nav-account-menu .email {
  font-size: 12.5px; color: var(--ink-3); padding: 8px 12px; word-break: break-all;
}
.nav-account-menu button {
  display: block; width: 100%; text-align: left; background: none; border: none;
  font-size: 15px; color: var(--ink); padding: 10px 12px; border-radius: 10px; cursor: pointer;
}
.nav-account-menu button:hover { background: var(--hairline-soft); }

/* Auth modal — same shape language as .app-prompt */
.auth-modal {
  position: fixed; inset: 0; z-index: 2100; display: none;
  align-items: center; justify-content: center;
  background: var(--scrim); padding: 20px;
}
.auth-modal.open { display: flex; }
.auth-modal-card {
  position: relative; background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-panel); padding: 34px 30px; max-width: 380px; width: 100%;
}
.auth-modal-close {
  position: absolute; top: 14px; right: 14px;
  background: var(--surface-2); border: 1px solid var(--hairline);
  border-radius: var(--r-pill); width: 32px; height: 32px; cursor: pointer;
  color: var(--ink); font-size: 14px;
}
.auth-modal-title { font-size: 23px; font-weight: 500; letter-spacing: -0.01em; margin-bottom: 8px; }
.auth-modal-text { font-size: 14.5px; color: var(--ink-2); line-height: 1.6; margin-bottom: 20px; }
.auth-field { margin-bottom: 12px; }
.auth-field label {
  display: block; font-size: 12px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 6px;
}
.auth-field input, .auth-field select {
  width: 100%; font-family: var(--font-sans); font-size: 15px; color: var(--ink);
  background: var(--surface-2); border: 1px solid var(--hairline);
  border-radius: var(--r-ui); padding: 11px 14px; outline: none;
}
.auth-field input:focus, .auth-field select:focus { border-color: var(--accent); }

/* Region-request triggers. The hero one is a filled pill below the CTA
   buttons — an announcement, not fine print. Deliberately orange rather than
   the site's teal --accent: this is a one-off attention-grabbing status
   callout, not a recurring UI role, so it doesn't borrow (and dilute) an
   existing token. The footer one stays a plain quiet link like its neighbors. */
.hero-region-badge {
  display: inline-flex; flex-direction: column; align-items: center; gap: 1px;
  margin-top: 18px; background: #E4650A; color: #fff; border: 1px solid transparent;
  border-radius: var(--r-pill); padding: 11px 26px;
  font-family: var(--font-sans); cursor: pointer; text-align: center;
  text-decoration: none;
  transition: transform 150ms var(--ease-out), background 150ms ease;
}
.hero-region-badge:hover { background: #C6560A; }
.hero-region-badge-status { font-size: 12px; font-weight: 500; opacity: 0.9; }
.hero-region-badge-cta { font-size: 15px; font-weight: 500; }
.hero-region-badge:active { transform: scale(0.97); }
.footer-link-btn {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: var(--font-sans); font-size: 14.5px; color: var(--ink-2);
}
.footer-link-btn:hover { color: var(--ink); }
.auth-error {
  display: none; font-size: 13px; color: var(--bad);
  background: color-mix(in srgb, var(--bad) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--bad) 30%, var(--surface));
  border-radius: var(--r-ui); padding: 9px 12px; margin-bottom: 12px;
}
.auth-error.show { display: block; }
/* Info variant of .auth-error — explains why the modal opened (e.g. a
   logged-out save attempt), so it's accent-tinted rather than alarming. */
.auth-notice {
  display: none; font-size: 13px; color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--surface));
  border-radius: var(--r-ui); padding: 9px 12px; margin-bottom: 12px;
}
.auth-notice.show { display: block; }

/* === Idea machine (index.html, .home-hero right column) ===
   Whole feature is toggled via IdeaBank's ENABLED flag in idea-bank.js; kept
   as one contiguous block here (rather than merged into unrelated rules above)
   so it stays easy to find, tweak, or delete wholesale. Base rules use the
   normal page inks; the .home-hero overrides at the end of this block flip
   them for the pine banner, same pattern as .home-hero .step-* above. */
.idea-machine-sub { color: var(--ink-2); margin-bottom: 20px; }

.idea-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; }
.idea-chip {
  font-family: var(--font-sans); font-size: 13.5px; font-weight: 500;
  padding: 8px 15px; border-radius: var(--r-pill);
  border: 1px solid var(--hairline); background: var(--surface); color: var(--ink-2);
  cursor: pointer; transition: color 160ms var(--ease-out), border-color 160ms var(--ease-out), background 160ms var(--ease-out), transform 160ms var(--ease-out);
}
/* Hover gated to real pointers — on touch, tap-hover sticks after the finger lifts. */
@media (hover: hover) and (pointer: fine) {
  .idea-chip:hover { color: var(--ink); }
}
.idea-chip:active { transform: scale(0.97); }
.idea-chip.is-active { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }

/* One card holds everything the machine outputs (reel, tag, description) so
   the result reads as a single unit instead of fragments around the button.
   min-height reserves room for the reveal, so the card (and the hero) doesn't
   grow when the tag/description fade in. */
.idea-result {
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-card); padding: 10px 18px 16px;
  max-width: 520px; min-height: 134px;
}
/* Recessed well: gives the reels a visible track to spin through instead of
   clipping against the bare card background. */
.idea-slot {
  display: flex; gap: 10px; align-items: center; margin-bottom: 8px;
  background: var(--surface-2); border: 1px solid var(--hairline-soft);
  border-radius: var(--r-ui); padding: 0 12px;
}
.idea-reel-window {
  overflow: hidden; height: 40px;
  /* The reel rows are white-space:nowrap, and a long title's intrinsic width
     would otherwise propagate up the flex/grid chain and stretch the hero's
     column past the viewport on mobile (spin-dependent, since each spin loads
     random titles). inline-size containment stops the contents from
     influencing layout width at all — the window sizes purely from flex. */
  contain: inline-size;
  /* Rows fade out at the well's top/bottom edges rather than hard-clipping. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 8px, #000 calc(100% - 8px), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 8px, #000 calc(100% - 8px), transparent 100%);
}
.idea-reel-window--icon { flex: 0 0 28px; }
.idea-reel-window--title { flex: 1 1 auto; min-width: 0; }
/* Reel motion is driven by the Web Animations API in index.html's idea-machine
   IIFE (durations, easing, and the reduced-motion fallback all live there). */
.idea-reel { list-style: none; margin: 0; padding: 0; }
.idea-reel li {
  height: 40px; line-height: 40px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: var(--font-sans); font-size: 16px; font-weight: 500; color: var(--ink);
}
.idea-reel-window--icon .idea-reel li { text-align: center; font-size: 20px; }

.idea-tag, .idea-desc {
  opacity: 0; transform: translateY(4px);
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
}
.idea-tag.is-visible, .idea-desc.is-visible { opacity: 1; transform: translateY(0); }
/* Tag leads, description follows 60ms behind — a small cascade instead of one
   blob. The delay lives on the enter state only, so hiding is still instant. */
.idea-desc.is-visible { transition-delay: 60ms; }
/* Plain mono label, not a pill — pill-shaped it read as an eighth mood chip. */
.idea-tag {
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3);
  margin-bottom: 6px;
}
.idea-desc { color: var(--ink-2); font-size: 15px; max-width: 52ch; }

.idea-actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-bottom: 14px; }

/* On the pine hero banner, flip the inks the way the hero's other content
   does. The result card keeps its light face (its own inks already work on
   it) — one bright "machine face" is where the contrast should pop. */
.home-hero .idea-machine-sub { color: color-mix(in srgb, var(--accent-ink) 82%, transparent); }
.home-hero .idea-chip {
  background: transparent; color: color-mix(in srgb, var(--accent-ink) 82%, transparent);
  border-color: color-mix(in srgb, var(--accent-ink) 34%, transparent);
}
@media (hover: hover) and (pointer: fine) {
  .home-hero .idea-chip:hover { color: var(--accent-ink); border-color: var(--accent-ink); }
}
.home-hero .idea-chip.is-active { background: var(--accent-ink); color: var(--accent); border-color: var(--accent-ink); }
.home-hero .idea-actions .btn--primary { background: var(--accent-ink); color: var(--accent); }
.home-hero .idea-actions .btn--primary:hover { background: color-mix(in srgb, var(--accent-ink) 88%, transparent); }

@media (max-width: 640px) {
  .idea-result { max-width: 100%; }
  /* Titles run up to ~55 characters filled; single-line nowrap plus ellipsis
     was cutting most of them off on a narrow phone. Let the title wrap up to
     two lines instead — taller row height, no more nowrap/ellipsis. Icon row
     stays single-line/centered; JS reads each window's real height at spin
     time (see index.html), so this doesn't need to touch the animation math. */
  .idea-reel-window { height: 58px; }
  .idea-reel-window--title .idea-reel li {
    height: 58px; line-height: 1.3; padding: 5px 0;
    white-space: normal; text-overflow: clip;
    display: flex; align-items: center; font-size: 14.5px;
  }
  .idea-reel-window--icon .idea-reel li { height: 58px; }
}
@media (prefers-reduced-motion: reduce) {
  /* Keep the color fades (they aid comprehension); drop only the movement. */
  .idea-chip:active { transform: none; }
}
/* === /Idea machine === */
.auth-submit {
  width: 100%; font-family: var(--font-sans); font-size: 15px; font-weight: 500;
  background: var(--accent); color: var(--accent-ink); border: none; cursor: pointer;
  border-radius: var(--r-pill); padding: 13px; margin-top: 6px;
}
.auth-submit:hover { background: var(--accent-hover); }
.auth-submit:disabled { opacity: 0.6; cursor: default; }
.auth-divider {
  display: flex; align-items: center; gap: 12px; margin: 16px 0;
  color: var(--ink-3); font-family: var(--font-mono); font-size: 11px;
  letter-spacing: 0.1em; text-transform: uppercase;
}
.auth-divider::before, .auth-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--hairline);
}
.auth-oauth-btn {
  width: 100%; font-family: var(--font-sans); font-size: 14.5px; font-weight: 500;
  background: var(--surface); color: var(--ink); border: 1px solid var(--hairline);
  cursor: pointer; border-radius: var(--r-pill); padding: 12px;
  display: flex; align-items: center; justify-content: center; gap: 9px;
  margin-bottom: 8px;
}
.auth-oauth-btn:hover { background: var(--hairline-soft); }
.auth-modal-footnote { font-size: 12.5px; color: var(--ink-3); margin-top: 16px; line-height: 1.6; }

/* Save (heart) buttons on list cards + the preview drawer */
.list-card { position: relative; }
.save-heart-btn {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid var(--hairline);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; cursor: pointer; color: var(--ink-2);
}
.save-heart-btn.saved { color: var(--bad); }
.save-heart-btn:hover { background: var(--surface); }
/* Sits at the right end of the .preview-tags badge row */
.preview-save-btn {
  margin-left: auto; font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  background: transparent; color: var(--ink); border: 1px solid var(--hairline);
  cursor: pointer; border-radius: var(--r-pill); padding: 4px 12px;
  display: flex; align-items: center; gap: 6px;
}
.preview-save-btn.saved { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 40%, var(--hairline)); }
.preview-save-btn:hover { background: var(--hairline-soft); }
