@font-face {
    font-family: "WanderScript";
    src: url("/assets/pacifico.ttf") format("truetype");
    font-weight: 400;
    font-display: swap;
  }

  :root {
    --ground:    #E3ECF6;
    --ground-2:  #F4F8FC;
    --surface:   #FFFFFF;
    --ink:       #0E1620;
    --ink-2:     #47586C;
    --ink-3:     #6E8299;
    --line:      #C7D7E8;
    --blue:      #1B6BE0;
    --blue-ink:  #0F4CA8;
    --chalk:     #B8861F;
    --chalk-mark:#E8B84B;
    --shot-filter: none;

    --sans: system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, "SF Mono", SFMono-Regular, "Cascadia Mono", Consolas, "Liberation Mono", monospace;
    --script: "WanderScript", "Brush Script MT", cursive;

    --pad: clamp(20px, 5vw, 64px);
    --shell: 1180px;
  }

  @media (prefers-color-scheme: dark) {
    :root {
      --ground:    #080D14;
      --ground-2:  #0D151F;
      --surface:   #131E2B;
      --ink:       #E9F0F8;
      --ink-2:     #9CB0C6;
      --ink-3:     #75899F;
      --line:      #223142;
      --blue:      #6BA8FF;
      --blue-ink:  #A8CBFF;
      --chalk:     #EFC463;
      --chalk-mark:#EFC463;
      --shot-filter: saturate(0.88) brightness(0.86);
    }
  }

  :root[data-theme="dark"] {
    --ground:    #080D14;
    --ground-2:  #0D151F;
    --surface:   #131E2B;
    --ink:       #E9F0F8;
    --ink-2:     #9CB0C6;
    --ink-3:     #75899F;
    --line:      #223142;
    --blue:      #6BA8FF;
    --blue-ink:  #A8CBFF;
    --chalk:     #EFC463;
    --chalk-mark:#EFC463;
    --shot-filter: saturate(0.88) brightness(0.86);
  }

  :root[data-theme="light"] {
    --ground:    #E3ECF6;
    --ground-2:  #F4F8FC;
    --surface:   #FFFFFF;
    --ink:       #0E1620;
    --ink-2:     #47586C;
    --ink-3:     #6E8299;
    --line:      #C7D7E8;
    --blue:      #1B6BE0;
    --blue-ink:  #0F4CA8;
    --chalk:     #B8861F;
    --chalk-mark:#E8B84B;
    --shot-filter: none;
  }

  body {
    background: var(--ground);
    color: var(--ink);
    font-family: var(--sans);
    font-size: 17px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
  }

  .shell {
    width: 100%;
    max-width: var(--shell);
    margin-inline: auto;
    padding-inline: var(--pad);
  }

  h1, h2, h3 { text-wrap: balance; letter-spacing: -0.028em; line-height: 1.04; font-weight: 760; }
  h1 { font-size: clamp(2.7rem, 7.4vw, 5.4rem); }
  h2 { font-size: clamp(1.9rem, 4.2vw, 3rem); }
  h3 { font-size: clamp(1.4rem, 2.5vw, 1.9rem); letter-spacing: -0.024em; }

  .script { font-family: var(--script); font-weight: 400; letter-spacing: 0; }

  .eyebrow {
    font-family: var(--mono);
    font-size: 0.7rem;
    letter-spacing: 0.19em;
    text-transform: uppercase;
    color: var(--ink-3);
  }

  .lede { font-size: clamp(1.1rem, 1.8vw, 1.32rem); color: var(--ink-2); max-width: 46ch; }

  a { color: var(--blue-ink); text-underline-offset: 3px; }
  :focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 3px; }

  /* ---------- masthead ---------- */

  .masthead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding-block: 20px;
  }
  .brand { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--ink); }
  .brand img { width: 34px; height: 34px; border-radius: 9px; display: block; }
  .brand span { font-family: var(--script); font-size: 1.6rem; line-height: 1; padding-bottom: 5px; }
  .masthead nav { display: flex; align-items: center; gap: clamp(16px, 2.4vw, 30px); }
  .masthead nav a { font-size: 0.88rem; font-weight: 560; color: var(--ink-2); text-decoration: none; }
  .masthead nav a:hover { color: var(--ink); }
  /* The App Store button reuses .btn-primary's fill but at masthead scale, and
     keeps its button ink instead of the nav-link grey. */
  .masthead nav a.btn-store { padding: 10px 18px; font-size: 0.88rem; color: #fff; }
  @media (prefers-color-scheme: dark) { .masthead nav a.btn-store { color: #06101D; } }
  :root[data-theme="dark"] .masthead nav a.btn-store { color: #06101D; }
  :root[data-theme="light"] .masthead nav a.btn-store { color: #fff; }
  /* On narrow phones the three nav items plus a pill overflow the row — let the
     text links go, keep the button. */
  @media (max-width: 560px) { .masthead nav a:not(.btn-store) { display: none; } }

  /* ---------- hero ---------- */

  .hero { padding-block: clamp(26px, 5vw, 56px) clamp(40px, 6vw, 76px); }
  .hero-grid { display: grid; gap: clamp(32px, 5vw, 56px); align-items: center; }
  @media (min-width: 940px) { .hero-grid { grid-template-columns: 1fr 1fr; } }

  .hero-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 24px; }
  .hero h1 { margin: 0; }
  .hero .lede { margin: 0; }

  .scrawl-word { position: relative; display: inline-block; }
  .scrawl-word svg {
    position: absolute;
    left: -3%; bottom: -0.2em;
    width: 106%; height: 0.4em;
    overflow: visible; pointer-events: none;
  }
  .scrawl-word path { fill: none; stroke: var(--chalk-mark); stroke-width: 7; stroke-linecap: round; }

  .cta-row { display: flex; flex-wrap: wrap; gap: 12px; }
  .btn {
    display: inline-flex; align-items: center;
    padding: 14px 24px; border-radius: 999px;
    font-size: 0.96rem; font-weight: 640; text-decoration: none;
    border: 1px solid transparent;
    transition: transform 0.16s ease;
  }
  .btn:hover { transform: translateY(-1px); }
  .btn-primary { background: var(--blue); color: #fff; }
  @media (prefers-color-scheme: dark) { .btn-primary { color: #06101D; } }
  :root[data-theme="dark"] .btn-primary { color: #06101D; }
  :root[data-theme="light"] .btn-primary { color: #fff; }
  .btn-ghost { border-color: var(--line); color: var(--ink); }
  .btn-ghost:hover { background: var(--surface); }

  .hero-shot { border-radius: 22px; overflow: hidden; box-shadow: 0 26px 60px -30px rgba(9, 24, 45, 0.62); }
  .hero-shot img { width: 100%; height: auto; display: block; filter: var(--shot-filter); }

  /* ---------- big numbers ---------- */

  .numbers { padding-block: clamp(56px, 8vw, 110px); }
  .numbers h2 { max-width: 16ch; margin: 0 0 clamp(36px, 5vw, 60px); }

  .num-grid { display: grid; gap: clamp(34px, 5vw, 20px); }
  @media (min-width: 760px) { .num-grid { grid-template-columns: repeat(3, 1fr); } }

  .num { display: flex; flex-direction: column; gap: 10px; }
  .num b {
    font-size: clamp(4.4rem, 13vw, 8.5rem);
    font-weight: 780;
    letter-spacing: -0.055em;
    line-height: 0.82;
    font-variant-numeric: tabular-nums;
  }
  .num.hit b { color: var(--chalk); }
  .num span { font-size: clamp(1rem, 1.5vw, 1.12rem); color: var(--ink-2); max-width: 24ch; line-height: 1.4; }

  .num-note {
    font-family: var(--mono);
    font-size: 0.66rem;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin: clamp(34px, 5vw, 54px) 0 0;
  }

  /* ---------- quote ---------- */

  .quote-band { padding-block: clamp(44px, 6vw, 88px); }
  .quote-band blockquote {
    margin: 0;
    font-size: clamp(1.5rem, 3.6vw, 2.6rem);
    line-height: 1.24;
    letter-spacing: -0.026em;
    font-weight: 620;
    max-width: 20ch;
    text-wrap: balance;
  }
  .quote-band .attrib {
    display: block;
    margin-top: 20px;
    font-family: var(--mono);
    font-size: 0.7rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--ink-3);
  }

  /* ---------- meander ---------- */

  .meander { display: block; width: 100%; height: clamp(48px, 6vw, 82px); overflow: visible; }
  .meander path { fill: none; stroke: var(--chalk-mark); stroke-width: 2.4; stroke-linecap: round; }

  /* ---------- modes ---------- */

  .band { padding-block: clamp(52px, 7vw, 96px); }
  .band > h2 { margin: 0 0 clamp(30px, 4vw, 50px); }

  .modes { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 20px; overflow: hidden; }
  @media (min-width: 800px) { .modes { grid-template-columns: 1fr 1fr; } }

  .mode {
    background: var(--ground-2);
    padding: clamp(26px, 3.4vw, 40px);
    display: flex;
    flex-direction: column;
    gap: 14px;
  }
  .mode h3 { margin: 0; }
  .mode > p { margin: 0; color: var(--ink-2); font-size: 1.02rem; max-width: 34ch; }
  .mode ul { margin: 6px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 9px; }
  .mode li { font-size: 0.94rem; color: var(--ink-2); padding-left: 18px; position: relative; }
  .mode li::before {
    content: "";
    position: absolute;
    left: 0; top: 0.62em;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--chalk-mark);
  }
  .mode li b { color: var(--ink); font-weight: 640; }

  /* ---------- screenshots ---------- */

  .strip {
    display: flex; gap: 18px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding: 0 var(--pad) 18px;
    margin-inline: calc(var(--pad) * -1);
    scrollbar-width: thin;
  }
  .shot { flex: 0 0 auto; width: min(252px, 66vw); scroll-snap-align: start; }
  .shot img {
    width: 100%; height: auto; display: block;
    border-radius: 16px; border: 1px solid var(--line);
    filter: var(--shot-filter);
  }

  /* ---------- details ---------- */

  .details { display: grid; gap: 22px; }
  @media (min-width: 760px) { .details { grid-template-columns: repeat(3, 1fr); } }
  .detail b { font-weight: 660; display: block; }
  .detail span { color: var(--ink-2); font-size: 0.94rem; }

  /* ---------- support ---------- */

  .support-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 20px;
    padding: clamp(26px, 4vw, 44px);
    display: flex; flex-direction: column; gap: 24px;
  }
  .support-card > p { margin: 0; font-size: 1.05rem; }
  .support-grid { display: grid; gap: 22px; }
  @media (min-width: 720px) { .support-grid { grid-template-columns: 1fr 1fr; } }
  .qa { display: flex; flex-direction: column; gap: 16px; }
  .qa div { display: flex; flex-direction: column; gap: 3px; }
  .qa b { font-weight: 640; font-size: 0.95rem; }
  .qa p { margin: 0; color: var(--ink-2); font-size: 0.9rem; }

  /* ---------- footer ---------- */

  footer { border-top: 1px solid var(--line); margin-top: clamp(40px, 6vw, 76px); padding-block: 30px 44px; }
  .foot-row {
    display: flex; flex-wrap: wrap; gap: 14px 28px;
    align-items: center; justify-content: space-between;
    font-family: var(--mono); font-size: 0.74rem;
    letter-spacing: 0.06em; color: var(--ink-3); text-transform: uppercase;
  }
  .foot-row a { color: var(--ink-3); text-decoration: none; }
  .foot-row a:hover { color: var(--ink); }

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

  .reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.7s ease, transform 0.7s ease; }
  .reveal.in { opacity: 1; transform: none; }
  .draw path { stroke-dasharray: var(--len); stroke-dashoffset: var(--len); }
  .draw.in path { transition: stroke-dashoffset 1.5s cubic-bezier(0.4, 0, 0.2, 1); stroke-dashoffset: 0; }

  @media (prefers-reduced-motion: reduce) {
    .reveal { opacity: 1; transform: none; transition: none; }
    .draw path, .draw.in path { stroke-dasharray: none; stroke-dashoffset: 0; transition: none; }
    .btn:hover { transform: none; }
    html { scroll-behavior: auto; }
  }
  html { scroll-behavior: smooth; }


/* ══════════════════════════════════════════════════════════════════════════
   Added pages. Homepage CSS above is extracted verbatim from src/template.html.
   ══════════════════════════════════════════════════════════════════════════ */

.crumbs { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-3); padding-block: 22px 0; }
.crumbs a { color: var(--ink-3); text-decoration: none; }
.crumbs a:hover { color: var(--ink); }

.page-head { padding-block: clamp(28px, 4vw, 52px) clamp(18px, 3vw, 30px); }
.page-head h1 { margin: 0 0 18px; }
.page-head .lede { margin: 0; }

.tiles { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line);
  border-radius: 20px; overflow: hidden; }
@media (min-width: 720px) { .tiles.two { grid-template-columns: 1fr 1fr; } }
@media (min-width: 860px) { .tiles.three { grid-template-columns: repeat(3, 1fr); } }
.tile { background: var(--ground-2); padding: clamp(22px, 3vw, 32px);
  display: flex; flex-direction: column; gap: 10px; }
.tile h3 { margin: 0; }
.tile p { margin: 0; color: var(--ink-2); font-size: 0.97rem; }
.tile a { text-decoration: none; }
.tile a:hover { text-decoration: underline; }

.rule { border: 0; border-top: 1px solid var(--line); margin: 0; }

.chip { display: inline-block; font-family: var(--mono); font-size: 0.63rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3);
  border: 1px solid var(--line); border-radius: 999px; padding: 4px 11px; }
.chip.mark { color: var(--chalk); border-color: var(--chalk); }

.listing { list-style: none; margin: 0; padding: 0; }
.listing li { border-top: 1px solid var(--line); }
.listing li:last-child { border-bottom: 1px solid var(--line); }
.listing a { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: baseline;
  padding: 18px 2px; text-decoration: none; color: var(--ink); }
.listing a:hover { color: var(--blue-ink); }
.listing .name { font-weight: 640; font-size: 1.05rem; letter-spacing: -0.018em; }
.listing .meta { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-3); margin-left: auto; }

ol.stops { list-style: none; counter-reset: s; padding: 0; margin: 0; }
ol.stops li { counter-increment: s; display: grid; grid-template-columns: 40px 1fr;
  gap: 18px; padding: 22px 0; border-top: 1px solid var(--line); }
ol.stops li:last-child { border-bottom: 1px solid var(--line); }
ol.stops li::before { content: counter(s); font-family: var(--mono); font-size: 0.8rem;
  color: var(--chalk); width: 34px; height: 34px; border: 1px solid var(--line);
  border-radius: 50%; display: flex; align-items: center; justify-content: center; }
ol.stops h3 { margin: 0 0 4px; }
ol.stops p { margin: 0; color: var(--ink-2); font-size: 0.96rem; }
ol.stops .where { font-family: var(--mono); font-size: 0.67rem; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-3); margin: 0 0 8px; }

table.data { width: 100%; border-collapse: collapse; }
table.data th, table.data td { text-align: left; padding: 13px 14px 13px 0;
  border-bottom: 1px solid var(--line); vertical-align: top; }
table.data th { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-3); font-weight: 400; white-space: nowrap; }
table.data td { color: var(--ink-2); font-size: 0.96rem; }
.scroll { overflow-x: auto; }

/* Deck slide 24 */
table.vs { width: 100%; border-collapse: collapse; table-layout: fixed; }
table.vs th { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--ink-3); font-weight: 400;
  text-align: left; padding: 0 14px 14px 0; }
table.vs th:last-child { color: var(--chalk); }
table.vs td { font-size: clamp(1rem, 1.7vw, 1.22rem); font-weight: 620;
  letter-spacing: -0.022em; padding: 0 14px 6px 0; border: 0; }
table.vs td.them { color: var(--ink-3); }
table.vs td.us { color: var(--ink); }
table.vs tr.ev td { font-size: 0.88rem; font-weight: 400; color: var(--ink-2);
  padding-bottom: 22px; border-bottom: 1px solid var(--line); }
@media (max-width: 620px) {
  table.vs, table.vs tbody, table.vs tr, table.vs td, table.vs th { display: block; }
  table.vs thead { display: none; }
  table.vs td.them::before { content: "Every other app"; display: block; }
  table.vs td.us::before { content: "Wander"; display: block; color: var(--chalk); }
  table.vs td.them::before, table.vs td.us::before { font-family: var(--mono);
    font-size: 0.6rem; letter-spacing: 0.15em; text-transform: uppercase;
    color: var(--ink-3); margin-bottom: 3px; }
  table.vs td.them { margin-bottom: 14px; }
}

dl.faq { margin: 0; }
dl.faq dt { font-weight: 660; font-size: 1.06rem; margin-top: 28px; letter-spacing: -0.015em; }
dl.faq dd { margin: 8px 0 0; color: var(--ink-2); font-size: 0.98rem; }

.foot-nav { display: flex; flex-wrap: wrap; gap: 10px; margin-top: clamp(34px, 5vw, 56px); }

/* The homepage stylesheet has no box-sizing reset, so .shell (width:100% plus
   side padding) is two gutters wider than its container: on a phone, and on any
   window between 1180 and 1308px, its right edge (the App Store pill, the end of
   every line) is clipped by body's overflow-x:hidden. Border-box, with max-width
   widened by the same two gutters, fixes that and leaves the desktop measure
   exactly as it was. */
.shell { box-sizing: border-box; max-width: calc(var(--shell) + 2 * var(--pad)); }

/* The template never resets the browser's 8px body margin, so every full-bleed
   section starts eight pixels down and eight pixels in — and on the homepage that
   pushed the ride off the top of the document, where its first scroll step had
   nothing to hold on to. */
body { margin: 0; }

.masthead nav a[aria-current="page"] { color: var(--ink); }
/* Two tabs on a phone too. The template hides every text link under 560px; here
   the wordmark gives way to its icon instead, the tabs shrink, and the store pill
   keeps its name. */
@media (max-width: 560px) {
  .masthead nav a:not(.btn-store) { display: inline; font-size: 0.82rem; }
  .masthead nav { gap: 14px; }
  .brand span { display: none; }
}
/* Brand plus the full pill overflows a 390px phone; the pill keeps its store name. */
@media (max-width: 440px) { .masthead .btn-store .bl { display: none; } }

/* Footer: every hub, so no page is more than a click from any other. */
.foot-links { display: flex; flex-wrap: wrap; gap: 8px 20px; }

/* Homepage: the masthead floats over the street. */
body.home .mast { position: absolute; left: 0; right: 0; top: 0; z-index: 90; }
body.home .brand, body.home .masthead nav > a:not(.btn-store), body.home .navmenu > a {
  color: #fff; text-shadow: 0 1px 12px rgba(0, 0, 0, 0.55); }
body.home .masthead nav > a:not(.btn-store):hover, body.home .navmenu > a:hover { color: #fff; opacity: 0.85; }

/* ── Detail pages: Custom Tours, the two tours, food, Hidden Gems ─────────── */
a.mode.go { text-decoration: none; color: inherit; transition: background 0.2s ease; }
a.mode.go:hover { background: var(--surface); }
a.mode.go .arrow { margin-top: auto; padding-top: 6px; font-weight: 660; font-size: 0.95rem; color: var(--blue-ink); }

.steps { list-style: none; counter-reset: st; margin: 0; padding: 0; display: grid; gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: 20px; overflow: hidden; }
@media (min-width: 760px) { .steps { grid-template-columns: repeat(4, 1fr); } }
.steps li { counter-increment: st; background: var(--ground-2); padding: clamp(20px, 2.6vw, 28px);
  display: flex; flex-direction: column; gap: 8px; }
.steps li::before { content: counter(st, decimal-leading-zero); font-family: var(--mono); font-size: 0.7rem;
  letter-spacing: 0.14em; color: var(--chalk); }
.steps b { font-size: 1.08rem; letter-spacing: -0.015em; }
.steps span { color: var(--ink-2); font-size: 0.95rem; }

.photo { margin: 0; border-radius: 18px; overflow: hidden; background: var(--surface); border: 1px solid var(--line); }
.photo img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; filter: var(--shot-filter); }
.photo.wide img { aspect-ratio: 16 / 8; }
.photo figcaption { font-family: var(--mono); font-size: 0.56rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-3); padding: 8px 12px; line-height: 1.5; }
.photo figcaption a { color: inherit; }

.tour-cards { display: grid; gap: clamp(18px, 3vw, 28px); }
@media (min-width: 820px) { .tour-cards { grid-template-columns: 1fr 1fr; } }
.tour-card { display: flex; flex-direction: column; text-decoration: none; color: var(--ink);
  background: var(--ground-2); border: 1px solid var(--line); border-radius: 22px; overflow: hidden;
  transition: transform 0.2s ease, box-shadow 0.2s ease; }
.tour-card:hover { transform: translateY(-2px); box-shadow: 0 24px 50px -30px rgba(9, 24, 45, 0.55); }
.tour-card img { width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; display: block; filter: var(--shot-filter); }
.tour-card .tc { padding: clamp(20px, 2.6vw, 28px); display: flex; flex-direction: column; gap: 10px; }
.tour-card h3 { margin: 0; }
.tour-card p { margin: 0; color: var(--ink-2); font-size: 0.98rem; }
.tour-card .meta { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); }
.tour-card .arrow { font-weight: 660; font-size: 0.95rem; color: var(--blue-ink); }

ol.stops .stop { display: grid; gap: 16px; min-width: 0; }
@media (min-width: 760px) { ol.stops .stop { grid-template-columns: minmax(0, 1fr) minmax(0, 320px); align-items: start; } }
ol.stops .walk { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--chalk); margin: 0 0 8px; }

/* Both maps are baked Google Static Maps images (prototype/lib/staticmap.js), so
   they are sized like any other picture. The width/height attributes on the tags
   are the real pixel dimensions, which reserves the right box before the bytes
   arrive and keeps the page from jumping. Google draws its own attribution into
   the image — which is also the only compliant way to carry it. */
.tour-map { display: block; width: 100%; height: auto; border-radius: 22px;
  border: 1px solid var(--line); background: #16212C; }

.crave { display: flex; flex-wrap: wrap; gap: 8px; }
.crave span { font-size: 0.9rem; font-weight: 600; padding: 8px 14px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--ground-2); color: var(--ink-2); }
.crave span.on { background: #ff9500; border-color: #ff9500; color: #fff; }

.gem-cards { display: grid; gap: 14px; }
@media (min-width: 760px) { .gem-cards { grid-template-columns: repeat(3, 1fr); } }
.gem-card { background: linear-gradient(160deg, rgba(107, 76, 255, 0.16), transparent 62%), var(--ground-2);
  border: 1px solid var(--line); border-radius: 18px; padding: clamp(20px, 2.4vw, 26px); display: flex; flex-direction: column; gap: 10px; }
.gem-card .lock { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.14em; text-transform: uppercase; color: #6b4cff; }
@media (prefers-color-scheme: dark) { .gem-card .lock { color: #b9a6ff; } }
:root[data-theme="dark"] .gem-card .lock { color: #b9a6ff; }
.gem-card .teaser { margin: 0; font-size: 1.06rem; font-weight: 620; letter-spacing: -0.012em; line-height: 1.35; }
.gem-card .where { margin: 0; color: var(--ink-3); font-size: 0.9rem; }

.riddle { background: var(--surface); border: 1px solid var(--line); border-radius: 20px; padding: clamp(22px, 3vw, 32px); }
.riddle blockquote { margin: 0 0 16px; font-size: clamp(1.15rem, 2vw, 1.45rem); font-style: italic; line-height: 1.42;
  letter-spacing: -0.012em; }
.riddle summary { cursor: pointer; font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--blue-ink); }
.riddle details p { margin: 12px 0 0; font-weight: 660; }
.riddle .hint { color: var(--ink-2); font-size: 0.95rem; margin: 0 0 14px; }



/* ══════════════════════════════════════════════════════════════════════════
   Dark glass — the pages with a backdrop photograph. lib/glass-css.js.
   ══════════════════════════════════════════════════════════════════════════ */

body.bd {
  --glass:        rgba(24, 32, 46, 0.50);
  --glass-solid:  rgba(18, 25, 36, 0.96);   /* no backdrop-filter — see @supports */
  --glass-deep:   rgba(12, 18, 27, 0.70);   /* the quieter surfaces: maps, wells */
  --glass-edge:   rgba(255, 255, 255, 0.17);
  --glass-under:  rgba(0, 0, 0, 0.42);
  --glass-blur:   blur(22px) saturate(150%);

  /* THE EDGE IS ONE PIXEL, NOT A GRADIENT.
     This started as the app's soft 9px specular band across the top, and on a
     web page at web sizes it reads as a bubble — a blurred white smear inside a
     rounded rectangle, which is the "bubbly" look and the opposite of glass. A
     real glass edge is SPECULAR: light catches the physical edge of the pane and
     nothing behind it, so it is a hard bright line exactly one pixel wide, with a
     matching dark line underneath where the far edge refracts. Sharp lines, soft
     fill — the soft part is the blur, and that is the only soft part. */
  --lens: inset 0 1px 0 rgba(255, 255, 255, 0.26),
          inset 0 -1px 0 rgba(0, 0, 0, 0.34);
  /* Tight and close, not a big soft cloud: a wide blurry drop shadow rounds
     a card's apparent edge off again and undoes the line above. */
  --glass-shadow: var(--lens),
                  0 1px 2px rgba(0, 0, 0, 0.45),
                  0 16px 34px -22px rgba(0, 0, 0, 0.85);

  /* LENS.sheen from the app, at its own four locations. The fill stays soft. */
  --sheen: linear-gradient(180deg,
      rgba(255,255,255,0.055) 0%, rgba(255,255,255,0.015) 35%,
      rgba(255,255,255,0) 78%, rgba(255,255,255,0.03) 100%);

  /* Tighter corners. A 22px radius on a 300px card is a lozenge, and a lozenge
     is the other half of "bubbly" — the eye reads the curve before it reads the
     pane. Small enough to be a cut edge, not a rounded one. */
  --r:    13px;   /* cards */
  --r-sm: 10px;   /* the small tiles, chips' neighbours */

  /* Defaults for a dark page with no photograph. shell.js overrides these inline
     from data/backdrops.json when there is one; without them, a page that asks
     for "dark" instead of "backdrop" would resolve rgba(var(--bd-tint), …) to
     nothing and lose its ambient light entirely. The value is the average of the
     six toned photographs — so a page with no photograph is lit by the set. */
  --bd-tint: 51, 51, 41;
  --bd-scrim: 1;
}

/* ── the ambient light ───────────────────────────────────────────────────────
   The photograph's own colour, measured at build time, washed into the page
   ground. This is the half of the blend that has nothing to do with the image
   element: the page below the photograph is not neutral ground the photograph
   stopped at, it is the same light continuing. It is also what the glass below
   the band has left to refract.

   Two layers, because they are anchored to different things. The wash from the
   top belongs to the DOCUMENT — it is the photograph's light spilling down from
   where the photograph is, and it has to scroll away with it. The low glow
   belongs to the VIEWPORT, and it exists because these pages are long: a tour
   page is six screens, and five of them were flat black once the document-
   anchored light had run out. Fixed, it means there is no scroll position
   anywhere on the site where a glass card has nothing behind it. */
body.bd {
  background:
    radial-gradient(120rem 66rem at 50% -14rem,
      rgba(var(--bd-tint), 0.32) 0%, rgba(var(--bd-tint), 0.11) 44%, rgba(var(--bd-tint), 0) 74%),
    var(--ground);
  color: var(--ink);
  color-scheme: dark;
}
/* Fixed, so it costs one composited layer and never repaints on scroll —
   background-attachment: fixed on the body would repaint the whole page. */
body.bd::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(58rem 40rem at 82% 6%, rgba(var(--bd-tint), 0.11), transparent 68%),
    radial-gradient(64rem 34rem at 26% 104%, rgba(var(--bd-tint), 0.13), transparent 70%);
}

/* Grain over the whole page, not just the band. Two jobs, and the second is the
   one that matters: the ambient washes above are radial gradients 120rem across,
   which is the exact case 8-bit colour cannot represent smoothly — they band
   into visible onion rings on a large display. Noise dithers the steps below the
   threshold where the eye assembles them into a ring. It also gives the plain
   dark pages, the ones with no photograph, something to be other than flat. */
body.bd::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.035;
  mix-blend-mode: overlay;
}

/* No photograph, so the light has to come from somewhere: the ambient is the
   page's only source and it is turned up to carry the head on its own. */
body.bd-plain {
  background:
    radial-gradient(110rem 60rem at 28% -16rem,
      rgba(var(--bd-tint), 0.34) 0%, rgba(var(--bd-tint), 0.13) 42%, rgba(var(--bd-tint), 0) 72%),
    radial-gradient(70rem 40rem at 92% 4rem, rgba(120, 150, 200, 0.09), transparent 66%),
    var(--ground);
}

/* ── the backdrop ────────────────────────────────────────────────────────────
   THE PHOTOGRAPH IS FIXED TO THE VIEWPORT AND THE PAGE SCROLLS OVER IT.
   It used to be an absolutely positioned band at the top of the DOCUMENT, masked
   so it dissolved into the page a screen or so down. Now it is pinned: it never
   moves, and every section slides up across it.

   A FIXED ELEMENT, NOT background-attachment: fixed. They look identical on a
   desktop and only one of them works: iOS Safari has never implemented
   background-attachment:fixed properly — it either behaves like a scrolling
   background or repaints the whole layer every frame — whereas position:fixed is
   composited correctly there.

   THE MASK IS GONE, AND HAD TO GO. It faded the band's bottom edge, which was a
   position in the DOCUMENT and therefore scrolled away with it. Against the
   viewport that same fade is a horizontal soft line sitting across the screen at
   all times, which is the one thing the mask existed to prevent. The scrim's
   downward ramp does the work now: it is what the copy lower down the page is
   read against, so it is stronger than it was.

   The scrim and the grain are still its pseudo-elements, so they are pinned with
   it and cover the viewport rather than the old band. */
.backdrop {
  position: fixed;
  inset: 0;
  height: 100vh;
  /* Large-viewport unit: on mobile the URL bar collapsing changes 100vh mid
     scroll, which would resize the photograph while the page moves under it. */
  height: 100lvh;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  /* --bd-focus is a two-value position, so it is the whole position here: an
     extra 50% in front made the shorthand a three-value position, which is
     invalid, and an invalid shorthand drops the placeholder silently. */
  background: var(--bd-lqip) var(--bd-focus) / cover no-repeat;
}
/* The three layers are stacked EXPLICITLY. ::before is the band's first child
   in the box tree, so with every layer at z-index auto the photograph paints
   over the scrim rather than under it — the scrim is there, doing nothing, and
   the only reason the band still looks roughly right is the mask. Silent, and
   invisible in the CSS, which is why the order is written down here. */
.backdrop picture, .backdrop img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
}
.backdrop::before { z-index: 1; }
.backdrop::after  { z-index: 2; }
.backdrop img {
  object-fit: cover;
  object-position: var(--bd-focus);
  /* Slow enough to never be caught moving, present enough that the page is not
     a still. It also covers the scale the drift needs headroom for. */
  transform: scale(1.06);
  animation: bd-drift 38s ease-in-out infinite alternate;
}
@keyframes bd-drift {
  from { transform: scale(1.06) translate3d(0, 0, 0); }
  to   { transform: scale(1.13) translate3d(0, -1.4%, 0); }
}

/* The scrim. Four gradients doing four jobs: a top wash so the masthead is
   legible over whatever the photograph happens to be doing up there, a wedge
   down the side the copy is on, a body ramp to the page ground, and a vignette
   that darkens the corners so the measure down the middle carries the eye.

   THE WEDGE IS NOT OPTIONAL, AND IT CANNOT BE A FLAT SCRIM
   Every one of these photographs has a bright region somewhere, and the one on
   /features/hidden-gems/ has it exactly where the headline lands: a cave mouth
   opening onto a white sky, with "to be earned" sitting on it in white. A scrim
   strong enough everywhere to fix that would throw away the photograph — which
   is the whole reason a flat page was a problem.

   So the darkening is where the words are and nowhere else. Copy is set from the
   left margin to roughly half the measure, so the wedge is opaque at the left
   edge and clear by 84%, and the photograph keeps its right-hand two-fifths at
   full strength. This is the same move a film poster makes, for the same reason.
   The angle is off-vertical so it does not read as a panel with an edge. */
.backdrop::before {
  content: "";
  position: absolute;
  inset: 0;
  --k: var(--bd-scrim, 1);
  background:
    /* the pool the copy sits in — soft, edgeless, exactly where the words are */
    radial-gradient(76% 58% at 24% 46%,
      rgba(8,13,20,calc(0.52 * var(--k))) 0%,
      rgba(8,13,20,calc(0.28 * var(--k))) 46%,
      rgba(8,13,20,0) 78%),
    /* the masthead */
    linear-gradient(180deg, rgba(8,13,20,0.74) 0%, rgba(8,13,20,0.34) 17%, rgba(8,13,20,0) 40%),
    /* the wedge down the copy side */
    linear-gradient(99deg,
      rgba(8,13,20,calc(0.72 * var(--k))) 0%,
      rgba(8,13,20,calc(0.52 * var(--k))) 30%,
      rgba(8,13,20,calc(0.24 * var(--k))) 54%,
      rgba(8,13,20,calc(0.05 * var(--k))) 72%,
      rgba(8,13,20,0) 86%),
    /* Down the page. This used to hand off to the page ground a screen down; now
       it is the ground for everything below the head, so it finishes near-opaque —
       the photograph is strongest where the headline is and quietest where the
       body copy and the lists are. */
    linear-gradient(180deg,
      rgba(8,13,20,0) 18%,
      rgba(8,13,20,0.42) 52%,
      rgba(8,13,20,0.78) 78%,
      rgba(8,13,20,0.92) 100%),
    /* the corners */
    radial-gradient(125% 88% at 50% 30%, rgba(8,13,20,0) 40%, rgba(8,13,20,0.50) 100%);
}
.backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.055;
  mix-blend-mode: overlay;
}

@media (prefers-reduced-motion: reduce) {
  .backdrop img { animation: none; transform: scale(1.04); }
}

/* Everything the page draws sits above the band. */
body.bd .mast, body.bd .crumbs, body.bd main, body.bd footer { position: relative; z-index: 1; }

/* ── the head, on the photograph ─────────────────────────────────────────── */
body.bd .page-head { padding-block: clamp(42px, 8vw, 104px) clamp(26px, 4vw, 50px); }
/* With no photograph the head does not need room to sit IN one, and that much
   empty dark above the headline reads as a page that failed to load. */
body.bd-plain .page-head { padding-block: clamp(30px, 5vw, 62px) clamp(22px, 3.5vw, 40px); }

/* Stop and dish photographs are daylight documentary frames — bright skies,
   full saturation — and dropped unaltered into a dark page each one is a lit
   window that pulls the eye off the copy. The site already has one lever for
   this; on these pages it is turned up. */
body.bd { --shot-filter: saturate(0.80) brightness(0.76) contrast(1.05); }
/* Two shadows, not one. The tight one is contact — it keeps a letter's own edge
   crisp against whatever is immediately behind it; the wide soft one is the
   halo that carries the word as a whole across a bright patch. One shadow can
   do either job but not both: tight alone disappears over a sky, wide alone
   turns the type to smoke. */
body.bd .page-head h1 {
  color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,0.42), 0 4px 38px rgba(0,0,0,0.62);
}
body.bd .page-head .eyebrow { color: rgba(255,255,255,0.72); text-shadow: 0 1px 8px rgba(0,0,0,0.6); }
/* Pacifico inside a letter-spaced uppercase mono eyebrow is unreadable — the
   wordmark is a script, and neither transform belongs to it. */
body.bd .page-head .eyebrow .script { text-transform: none; letter-spacing: 0; font-size: 1.2em; }
body.bd .page-head .lede {
  color: rgba(255,255,255,0.86); max-width: 52ch;
  text-shadow: 0 1px 2px rgba(0,0,0,0.4), 0 2px 22px rgba(0,0,0,0.55);
}
body.bd .page-head .scrawl-word path { stroke: var(--chalk-mark); }

/* The masthead and the breadcrumb ride the photograph, so they take the
   homepage's treatment: white, with enough shadow to survive a bright frame. */
body.bd .brand,
body.bd .masthead nav a:not(.btn-store) { color: #fff; text-shadow: 0 1px 12px rgba(0,0,0,0.55); }
body.bd .masthead nav a:not(.btn-store):hover { color: #fff; opacity: 0.82; }
body.bd .crumbs, body.bd .crumbs a { color: rgba(255,255,255,0.62); text-shadow: 0 1px 10px rgba(0,0,0,0.5); }
body.bd .crumbs a:hover { color: #fff; }

/* ── the glass recipe ────────────────────────────────────────────────────────
   Background layers, never pseudo-elements: ::before and ::after are already
   spoken for by the list counters and bullets these same elements carry. */
body.bd .mode,
body.bd .tile,
body.bd .steps li,
body.bd .tour-card,
body.bd .guide-card,
body.bd .gem-card,
body.bd .riddle,
body.bd .photo,
body.bd .support-card,
body.bd .arrival-card,
body.bd .earned,
body.bd .detail,
body.bd .num,
body.bd .dish,
body.bd .pick {
  background: var(--sheen), var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
          backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-edge);
  border-bottom-color: var(--glass-under);
  border-radius: var(--r);
  box-shadow: var(--glass-shadow);
}

/* Every surface that asked for a blur, and nothing else. The App Store pill and
   the primary button are NOT in this list and must not be: they were never
   glass — they are solid --blue — and sweeping them in here turned the page's
   one call to action into another dark rectangle on exactly the browsers least
   able to spare it. The lit craving chip is safe by specificity: .crave span.on
   outranks .crave span, so it keeps its orange. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  body.bd .mode, body.bd .tile, body.bd .steps li, body.bd .tour-card, body.bd .guide-card,
  body.bd .gem-card,
  body.bd .riddle, body.bd .photo, body.bd .support-card, body.bd .arrival-card,
  body.bd .earned, body.bd .detail, body.bd .num, body.bd .dish, body.bd .pick,
  body.bd .crave span, body.bd .chip, body.bd .btn-ghost {
    background: var(--glass-solid);
  }
}

/* ── the grids stop being one ruled box ──────────────────────────────────────
   .modes, .tiles and .steps are a single bordered rectangle with 1px gaps
   showing the background through as rules. That reads as a table, and it is the
   flatness being removed: every cell shares one plane, so nothing can sit in
   front of anything. Real gaps, and each cell becomes its own pane with its own
   shadow. */
body.bd .modes, body.bd .tiles, body.bd .steps {
  background: none;
  border: 0;
  border-radius: 0;
  overflow: visible;
  gap: clamp(12px, 1.6vw, 18px);
}
body.bd .steps li, body.bd .detail, body.bd .num,
body.bd .dish, body.bd .pick { border-radius: var(--r-sm); }

/* A pane lifts toward the light when you point at it. */
body.bd .mode.go, body.bd .tour-card, body.bd .guide-card {
  transition: transform 0.22s ease, box-shadow 0.22s ease, background-color 0.22s ease;
}
body.bd a.mode.go:hover, body.bd .tour-card:hover, body.bd .guide-card:hover {
  transform: translateY(-3px);
  background: var(--sheen), rgba(30, 40, 56, 0.60);
  box-shadow: 0 40px 70px -34px rgba(0, 0, 0, 0.95), 0 0 0 1px rgba(255, 255, 255, 0.05);
}

/* ── the smaller surfaces ────────────────────────────────────────────────── */
body.bd .detail, body.bd .num, body.bd .dish, body.bd .pick {
  padding: clamp(18px, 2.2vw, 24px);
}
body.bd .details, body.bd .num-grid { gap: clamp(12px, 1.6vw, 18px); }

/* The homepage holds .mode copy to 34ch because there it is one column beside a
   screenshot. Here it is a card in a two-up grid and 34ch breaks three-word
   lines off the end of every paragraph. */
body.bd .mode > p { max-width: 44ch; }

/* Bands can breathe less now that the cards are separate objects with their own
   shadows: the 1px-ruled grid needed the space around it to read as a unit, and
   96px between two floating rows is a hole. */
body.bd .band { padding-block: clamp(40px, 5vw, 70px); }

body.bd .chip, body.bd .crave span, body.bd .btn-ghost {
  background: var(--sheen), rgba(18, 25, 36, 0.5);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
          backdrop-filter: blur(14px) saturate(140%);
  border-color: var(--glass-edge);
  color: rgba(255, 255, 255, 0.86);
  box-shadow: var(--lens);
}
body.bd .crave span:hover, body.bd .btn-ghost:hover { background: var(--sheen), rgba(30, 40, 55, 0.62); color: #fff; }
/* The one lit chip keeps the app's orange — it is the state, not a surface. */
body.bd .crave span.on {
  background: var(--sheen), #ff9500;
  border-color: rgba(255, 175, 60, 0.9);
  color: #241300;
  box-shadow: 0 8px 26px -10px rgba(255, 149, 0, 0.75);
}

/* The map is a window, not a pane: it darkens rather than frosts, because
   there is a photograph behind it that would otherwise compete with the tiles. */
body.bd .tour-map {
  background: var(--glass-deep);
  border-color: var(--glass-edge);
  border-radius: var(--r);
  box-shadow: var(--glass-shadow);
}

body.bd .photo { border-radius: var(--r); }
body.bd .photo figcaption { color: rgba(255, 255, 255, 0.46); }

body.bd .riddle { border-radius: var(--r); }
body.bd .gem-card {
  background: linear-gradient(162deg, rgba(107, 76, 255, 0.22), transparent 60%), var(--sheen), var(--glass);
}

/* ── ruled things become hairlines of light, not of ink ──────────────────── */
body.bd { --line: rgba(255, 255, 255, 0.11); }
body.bd .listing li { border-color: rgba(255, 255, 255, 0.09); }
body.bd .listing a { color: rgba(255, 255, 255, 0.92); padding-inline: 14px; border-radius: var(--r-sm); }
body.bd .listing a:hover { background: rgba(255, 255, 255, 0.05); color: #fff; }
body.bd table.data th, body.bd table.data td { border-color: rgba(255, 255, 255, 0.09); }
body.bd ol.stops li { border-color: rgba(255, 255, 255, 0.09); }
body.bd ol.stops li::before { border-color: rgba(255, 255, 255, 0.18); background: rgba(255, 255, 255, 0.04); }
body.bd hr.rule { border-top-color: rgba(255, 255, 255, 0.09); }
body.bd footer { border-top-color: rgba(255, 255, 255, 0.09); }

/* ── type over all of it ─────────────────────────────────────────────────── */
body.bd h1, body.bd h2, body.bd h3 { color: #fff; }
body.bd .mode > p, body.bd .mode li, body.bd .tile p { color: rgba(255, 255, 255, 0.74); }
body.bd .mode li b, body.bd .steps b { color: #fff; }
body.bd .steps span { color: rgba(255, 255, 255, 0.74); }
body.bd .lede { color: rgba(255, 255, 255, 0.78); }
body.bd .detail span, body.bd .num span { color: rgba(255, 255, 255, 0.72); }
body.bd .eyebrow, body.bd .meta, body.bd .where { color: rgba(255, 255, 255, 0.54); }

/* ── the foot ────────────────────────────────────────────────────────────── */
body.bd .bd-credit {
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: rgba(255, 255, 255, 0.34);
  flex-basis: 100%; order: 9; margin: 0;
}
body.bd .bd-credit a { color: inherit; text-decoration: none; }
body.bd .bd-credit a:hover { color: rgba(255, 255, 255, 0.7); }

/* ── narrow screens ──────────────────────────────────────────────────────────
   The band is shorter, so the head still fills it rather than floating in the
   middle of a photograph, and the blur radius comes down: a 22px backdrop-filter
   over a full-width card is the single most expensive thing on the page and a
   phone is the device least able to pay for it. */
@media (max-width: 700px) {
  body.bd { --glass-blur: blur(16px) saturate(140%); }
  body.bd .page-head { padding-block: clamp(30px, 9vw, 56px) clamp(20px, 4vw, 34px); }
}
