/*
 * Praeter web.
 *
 * The glass here is a web approximation of the iOS app's Liquid Glass
 * (backdrop-filter, a hairline border and an inner highlight). Apple ships no
 * CSS for Liquid Glass; this only borrows the look. Under
 * prefers-reduced-transparency every glass surface becomes a solid fill.
 *
 * Tokens mirror DS.swift: the green accent with taupe and blush highlights, the 8/12/16/20 radius scale with
 * pill buttons, and the system font. The page backdrop is the app's dusk
 * gradient (FloatingBackgroundView: the Circus1-2 image under a 72%
 * system-background wash), rebuilt in CSS from colours sampled off that image
 * so it can reflow to any aspect ratio.
 */

:root {
  color-scheme: light dark;

  /* Dusk, sampled from the app background. Top to bottom, then the cool
     top-right and warm left-hand light. */
  --dusk-1: #8faee2;
  --dusk-2: #c2c8d9;
  --dusk-3: #e9d8c7;
  --dusk-4: #f1ceb2;
  --dusk-5: #e6b8a1;
  --dusk-6: #c19496;
  --dusk-7: #65649c;
  --dusk-sky: #6296db;
  --dusk-glow: #feeacf;
  --dusk-night: #575891;
  /* The app washes the image with systemBackground at 0.72. 0.62 keeps more
     colour and still holds every text token at 4.5:1 or better. */
  --wash: rgb(255 255 255 / 0.62);

  --bg: #e8e4ec;
  --surface: rgb(255 255 255 / 0.62);
  --surface-solid: #ffffff;
  --surface-2: rgb(255 255 255 / 0.42);
  --card-edge: inset 0 1px 0 rgb(255 255 255 / 0.7);
  --text: #16161d;
  --text-2: #454659;
  --hairline: rgb(22 22 29 / 0.12);
  --accent: #152925;
  /* Dark enough to double as text: 8.5:1 or better on the whole backdrop. */
  --accent-text: #152925;
  --accent-ink: #fbfbfe;
  --accent-soft: rgb(21 41 37 / 0.1);
  --btn-shadow: rgb(16 30 27 / 0.5);
  --focus: #152925;
  /* Contrasting highlights. Light enough that in light mode they are fills
     (with dark text on them), never text. */
  --highlight: #c5afa0;
  --highlight-2: #e9bcb7;
  --wordmark: var(--accent-text);

  /* Glass opacity. Level 3 is the default; the Glass control sets
     data-glass on <html> to pick 1-5 (see the level rules below). */
  --glass-a: 0.66;
  --glass-strong-a: 0.74;
  --stage-a: 22%;
  --glass-fill: rgb(255 255 255 / var(--glass-a));
  --glass-strong: rgb(255 255 255 / var(--glass-strong-a));
  --glass-edge: rgb(255 255 255 / 0.7);
  --glass-highlight: rgb(255 255 255 / 0.9);
  --glass-shadow: 0 18px 50px -12px rgb(28 44 40 / 0.28);
  --glass-solid: #f7f7fa;

  --scrim: linear-gradient(180deg, rgb(10 10 16 / 0) 30%, rgb(10 10 16 / 0.55) 100%);

  --r-s: 8px;
  --r-m: 12px;
  --r-l: 16px;
  --r-xl: 20px;
  --r-pill: 999px;

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --gutter: 16px;
  --max: 1240px;
  --nav-h: 64px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  /* Layers: content < sticky nav < mobile menu. */
  --z-nav: 20;
  --z-menu: 30;
}

@media (prefers-color-scheme: dark) {
  :root {
    --wash: rgb(14 14 19 / 0.76);

    --bg: #16161e;
    --surface: rgb(30 30 40 / 0.55);
    --surface-solid: #262632;
    --surface-2: rgb(255 255 255 / 0.07);
    --card-edge: inset 0 1px 0 rgb(255 255 255 / 0.06);
    --text: #ececf2;
    --text-2: #b4b4c6;
    --hairline: rgb(255 255 255 / 0.1);
    --accent: #94a187;
    /* A lighter tint of the accent for text: #94a187 itself reaches 3.6:1
       over the brightest part of the dark backdrop. */
    --accent-text: #b1bca6;
    --accent-ink: #121611;
    --accent-soft: rgb(148 161 135 / 0.16);
    /* Blush reads at 5.8:1 or better on the dark backdrop. */
    --wordmark: #e9bcb7;
    --btn-shadow: rgb(0 0 0 / 0.6);
    --focus: #b1bca6;

    --glass-a: 0.6;
    --glass-strong-a: 0.7;
    --glass-fill: rgb(24 24 32 / var(--glass-a));
    --glass-strong: rgb(24 24 32 / var(--glass-strong-a));
    --glass-edge: rgb(255 255 255 / 0.14);
    --glass-highlight: rgb(255 255 255 / 0.18);
    --glass-shadow: 0 18px 50px -12px rgb(0 0 0 / 0.55);
    --glass-solid: #1b1b24;
  }
}

@media (min-width: 768px) {
  :root {
    --gutter: 32px;
    --nav-h: 72px;
  }
}

/* Glass levels. Only the alphas change, so every glass surface moves
   together and the light/dark colours stay as defined above. */
:root[data-glass="1"] { --glass-a: 0.3; --glass-strong-a: 0.4; --stage-a: 6%; }
:root[data-glass="2"] { --glass-a: 0.48; --glass-strong-a: 0.58; --stage-a: 14%; }
:root[data-glass="4"] { --glass-a: 0.8; --glass-strong-a: 0.86; --stage-a: 34%; }
:root[data-glass="5"] { --glass-a: 0.9; --glass-strong-a: 0.94; --stage-a: 48%; }

@media (prefers-color-scheme: dark) {
  :root[data-glass="1"] { --glass-a: 0.28; --glass-strong-a: 0.38; }
  :root[data-glass="2"] { --glass-a: 0.44; --glass-strong-a: 0.54; }
  :root[data-glass="4"] { --glass-a: 0.74; --glass-strong-a: 0.82; }
  :root[data-glass="5"] { --glass-a: 0.86; --glass-strong-a: 0.92; }
}

/* Brand faces, self-hosted from @fontsource (both SIL OFL 1.1): Bellefair for
   the name, standing in for CoFo Cinema1909, and Sacramento for the tagline,
   standing in for Ballare. */
@font-face {
  font-family: "Bellefair";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/bellefair-latin-400-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Sacramento";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/sacramento-latin-400-normal.woff2") format("woff2");
}

/* ---------- Base ---------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--nav-h) + 16px);
  background: var(--bg);
  accent-color: var(--accent);
  caret-color: var(--accent);
  scrollbar-color: color-mix(in srgb, var(--accent) 45%, transparent) transparent;
}

::selection {
  background: color-mix(in srgb, var(--highlight-2) 60%, transparent);
  color: inherit;
}

/* The dusk backdrop. A fixed layer, not a background on a scrolling box, so it
   never repaints on scroll; content scrolls over it like the app's sheets. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(var(--wash), var(--wash)),
    radial-gradient(120% 70% at 100% 0%, var(--dusk-sky) 0%, transparent 60%),
    radial-gradient(90% 60% at 0% 45%, var(--dusk-glow) 0%, transparent 70%),
    radial-gradient(110% 50% at 50% 115%, var(--dusk-night) 0%, transparent 70%),
    linear-gradient(180deg, var(--dusk-1) 0%, var(--dusk-2) 20%, var(--dusk-3) 40%, var(--dusk-4) 55%, var(--dusk-5) 70%, var(--dusk-6) 85%, var(--dusk-7) 100%);
}

body {
  margin: 0;
  color: var(--text);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: inherit;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  margin: 0;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--r-s);
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: var(--z-menu);
  padding: 10px 16px;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  text-decoration: none;
}

.skip-link:focus {
  top: 12px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

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

.icon {
  width: 1.15em;
  height: 1.15em;
  flex: none;
}

/* ---------- Glass ---------- */

.glass {
  position: relative;
  background: linear-gradient(135deg, var(--glass-highlight) -60%, transparent 45%), var(--glass-fill);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  border: 1px solid var(--glass-edge);
  box-shadow: inset 0 1px 0 var(--glass-highlight), var(--glass-shadow);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass {
    background: var(--glass-solid);
  }
}

@media (prefers-reduced-transparency: reduce) {
  .glass {
    background: var(--glass-solid);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 12px 22px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font: inherit;
  font-weight: 600;
  font-size: 0.975rem;
  line-height: 1.2;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform 0.25s var(--ease), background-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.btn:active {
  transform: scale(0.98);
}

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.25), 0 8px 20px -10px var(--btn-shadow);
}

.btn-primary:hover {
  background: color-mix(in srgb, var(--accent) 88%, var(--text));
}

.btn-glass {
  color: var(--text);
}

.btn-glass:hover {
  background: var(--glass-strong);
}

/* The App Store link doesn't exist yet: same shape, not interactive. */
.btn-soon {
  cursor: default;
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--hairline);
  box-shadow: none;
}

.btn-soon:active {
  transform: none;
}

.btn-soon .soon-tag {
  font-weight: 500;
  color: var(--text-2);
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--accent-text);
  font-weight: 600;
  text-decoration: none;
  text-underline-offset: 4px;
}

.text-link:hover {
  text-decoration: underline;
}

/* ---------- Navigation ---------- */

.site-nav {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  padding-top: 10px;
  margin-bottom: calc(-1 * (var(--nav-h) + 10px));
}

.site-nav .bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: calc(var(--nav-h) - 12px);
  padding: 0 8px 0 10px;
  border-radius: var(--r-pill);
}

.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 12px;
  padding: 4px 6px 4px 8px;
  text-decoration: none;
}

.brand-name {
  font-family: "Bellefair", "Didot", "Bodoni 72", Georgia, serif;
  font-size: 1.65rem;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--wordmark);
}

.brand-tag {
  font-family: "Sacramento", "Snell Roundhand", "Apple Chancery", cursive;
  font-size: 1.5rem;
  line-height: 1;
  white-space: nowrap;
  color: var(--text-2);
}

/* The icon artwork carries its own rounded corners. Fixed size, never
   squeezed by the links beside it. */
.brand-icon {
  flex: none;
  width: 34px;
  height: 34px;
  min-width: 34px;
  object-fit: contain;
}

.site-nav .brand {
  flex: none;
}

/* With the icon in front, centre the row on the icon rather than the text
   baseline. */
.brand:has(.brand-icon) {
  align-items: center;
}

.footer-brand .brand {
  flex-wrap: wrap;
  padding-left: 0;
}

/* The tagline needs room beside Cities, Language and Contact; below this
   the name stands alone in the bar (the footer keeps it). */
@media (max-width: 1179px) {
  .site-nav .brand-tag {
    display: none;
  }
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-links > a,
.nav-menu > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 8px 12px;
  border-radius: var(--r-pill);
  text-decoration: none;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  -webkit-user-select: none;
  user-select: none;
}

.nav-links > a:hover,
.nav-menu > summary:hover,
.nav-menu[open] > summary {
  background: var(--accent-soft);
}

.nav-links > a[aria-current="page"] {
  background: var(--accent-soft);
  color: var(--accent-text);
}

.nav-links > a:focus-visible,
.nav-menu > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- Header menus (Cities, Language) ---------- */

.nav-menu {
  position: relative;
}

.nav-menu > summary {
  list-style: none;
}

.nav-menu > summary::-webkit-details-marker {
  display: none;
}

.nav-caret {
  width: 0.9em;
  height: 0.9em;
  transition: rotate 0.25s var(--ease);
}

.nav-menu[open] .nav-caret {
  rotate: 180deg;
}

.nav-code {
  display: none;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.nav-menu .menu {
  position: absolute;
  top: calc(100% + 12px);
  left: 0;
  z-index: var(--z-menu);
  min-width: 250px;
  max-height: min(70dvh, 520px);
  overflow-y: auto;
  padding: 8px;
  border-radius: var(--r-l);
  /* Opens over busy photos, so nearly solid: the glass shows only at the
     edge and highlight, and the list stays readable on any picture. */
  background:
    linear-gradient(135deg, var(--glass-highlight) -60%, transparent 45%),
    color-mix(in srgb, var(--glass-solid) 94%, transparent);
  -webkit-backdrop-filter: blur(30px) saturate(160%);
  backdrop-filter: blur(30px) saturate(160%);
}

.nav-menu.is-end .menu {
  left: auto;
  right: 0;
}

.menu ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.menu-title {
  margin: 4px 10px 6px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-2);
}

.menu li > a,
.menu-soon {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 44px;
  padding: 10px 12px;
  border-radius: var(--r-m);
  text-decoration: none;
  color: var(--text);
  font-weight: 500;
}

.menu li > a:hover,
.menu li > a:focus-visible {
  background: var(--accent-soft);
  outline: none;
}

.menu li > a[aria-current] {
  color: var(--accent-text);
  font-weight: 650;
}

.menu-soon {
  color: var(--text-2);
}

.menu-meta {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-2);
  white-space: nowrap;
}

.menu-check {
  color: var(--accent);
}

.menu-all {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0;
  padding: 10px 12px;
  border-top: 1px solid var(--hairline);
  color: var(--accent-text);
  font-weight: 600;
  text-decoration: none;
}

.menu-all:hover {
  text-decoration: underline;
}

/* Narrow screens: the words give way to icons and the language code, and an
   open menu spans the screen under the bar instead of hanging off an edge. */
@media (max-width: 600px) {
  .nav-menu.is-end .nav-label,
  .nav-links > a .nav-label {
    display: none;
  }

  .nav-menu.is-end .nav-code {
    display: inline;
  }

  .nav-menu .menu,
  .nav-menu.is-end .menu {
    position: fixed;
    top: calc(var(--nav-h) + 4px);
    left: var(--gutter, 16px);
    right: var(--gutter, 16px);
    min-width: 0;
  }
}

/* Phones: the logo alone in the bar. */
@media (max-width: 430px) {
  .site-nav .brand-name {
    display: none;
  }
}

/* ---------- Header: the burger menu (phones) ---------- */

/* Below 860px Cities and Contact fold into one menu with Support, leaving
   the logo, Language, the store and the burger, which always fit. (With
   everything in the bar, the longest languages need about 780px.) */
.nav-burger {
  display: none;
}

.nav-burger .menu-title:not(:first-child) {
  margin-top: 12px;
}

.menu-links {
  margin-top: 8px !important;
  padding-top: 8px !important;
  border-top: 1px solid var(--hairline);
}

.menu-links .icon {
  color: var(--text-2);
}



@media (max-width: 859px) {
  .nav-burger {
    display: block;
  }

  .nav-burger .menu {
    position: fixed;
    top: calc(var(--nav-h) + 4px);
    left: auto;
    right: var(--gutter, 16px);
    width: min(360px, calc(100vw - 2 * var(--gutter, 16px)));
    min-width: 0;
  }

  .nav-links > :not(.nav-buy):not(.nav-lang):not(.nav-burger) {
    display: none;
  }

  /* Language, then the store, then the burger. */
  .nav-links > .nav-buy {
    order: 1;
  }

  .nav-links > .nav-burger {
    order: 2;
  }

  /* The store as a filled rounded square the size of the logo, its corners
     close to the icon artwork's. */
  .nav-links > a.nav-buy {
    justify-content: center;
    width: 34px;
    min-height: 34px;
    height: 34px;
    margin-inline: 4px;
    padding: 0;
    border-radius: 9px;
  }

  .nav-links > a.nav-buy .nav-label {
    display: none !important;
  }
}

.nav-cta {
  display: none;
}

.nav-cta .btn {
  min-height: 40px;
  padding: 8px 16px;
  font-size: 0.9rem;
}

/* With Cities, Language and Contact in the bar, the store button only fits
   on wide screens; everywhere else it's on the pages themselves. */
@media (min-width: 1000px) {
  .nav-cta {
    display: flex;
  }
}

/* ---------- Photo hero (home + tour) ---------- */

.photo-hero {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: flex-end;
  min-height: min(100dvh, 880px);
  padding-top: calc(var(--nav-h) + 32px);
  padding-bottom: 32px;
  overflow: hidden;
  background: #2b2a33;
}

.photo-hero > picture,
.photo-hero > picture img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
}

.photo-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--scrim);
  pointer-events: none;
}

.hero-panel {
  max-width: 600px;
  padding: 28px 24px;
  border-radius: var(--r-xl);
}

.hero-panel h1 {
  font-size: clamp(2.4rem, 5.4vw, 4.2rem);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.035em;
}

.hero-panel .lede {
  margin-top: 16px;
  max-width: 44ch;
  font-size: 1.1rem;
  color: var(--text-2);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 28px;
}

@media (max-width: 479px) {
  .hero-actions .btn {
    width: 100%;
    white-space: normal;
  }
}

@media (min-width: 768px) {
  .photo-hero {
    padding-bottom: 56px;
  }

  .hero-panel {
    padding: 40px;
  }
}

/* Tour hero is shorter: the page has work to do below it. */
.photo-hero.is-tour {
  min-height: min(88dvh, 760px);
}

.crumbs {
  display: flex;
  gap: 6px;
  margin: 0 0 14px;
  padding: 0;
  list-style: none;
  font-size: 0.9rem;
  color: var(--text-2);
}

.crumbs a {
  text-decoration: none;
}

.crumbs a:hover {
  text-decoration: underline;
}

.crumbs li + li::before {
  content: "/";
  margin-right: 6px;
  opacity: 0.6;
}

.facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}

.facts li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: var(--accent-soft);
  font-size: 0.9rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.facts .icon {
  color: var(--accent);
}

/* ---------- Sections ---------- */

.section {
  padding-block: 72px;
}

@media (min-width: 1024px) {
  .section {
    padding-block: 112px;
  }
}

.section.is-flush-top {
  padding-top: 0;
}

.section-title {
  font-size: clamp(1.9rem, 3.6vw, 2.9rem);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.03em;
  max-width: 20ch;
}

.section-lede {
  margin-top: 14px;
  max-width: 60ch;
  font-size: 1.075rem;
  color: var(--text-2);
}

/* ---------- Tour page: routes ---------- */

.routes {
  display: grid;
  gap: 40px;
}

.route-card {
  padding: 8px;
  border-radius: var(--r-xl);
  background: var(--surface);
  border: 1px solid var(--hairline);
  box-shadow: var(--card-edge);
}

.route-tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
  padding: 4px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
}

.route-tabs button {
  min-height: 44px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease);
}

.route-tabs button {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.route-tabs button[aria-selected="true"]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  padding: 2px;
  border-radius: inherit;
  background:
    linear-gradient(115deg, transparent 28%, rgb(255 255 255 / 0.55) 44%, transparent 58%),
    linear-gradient(135deg, var(--m1) 0%, var(--m2) 40%, var(--m2) 60%, var(--m3) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}

/* The selected route: liquid glass inside, its metal as the outline. */
.route-tabs button[aria-selected="true"] {
  color: var(--text);
  background:
    linear-gradient(135deg, var(--glass-highlight) -60%, transparent 45%),
    var(--glass-fill);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  box-shadow:
    inset 0 1px 0 var(--glass-highlight),
    0 4px 14px -6px var(--m3);
}

.route-tabs button[aria-selected="true"] .metal-dot {
  display: none;
}

/* Metallic outline, as the app draws its route badges (RouteTier.swift):
   the route colour lifted towards white at the top left, shaded at the bottom
   right, with a soft specular streak. Only a ring is painted (the gradient is
   masked to the border), so whatever is inside, glass included, shows
   through unchanged. Colours come from --m1/--m2/--m3 set on the element. */
.metal {
  position: relative;
  isolation: isolate;
}

.metal::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  padding: var(--ring, 2px);
  border-radius: inherit;
  background:
    linear-gradient(115deg, transparent 28%, rgb(255 255 255 / 0.55) 44%, transparent 58%),
    linear-gradient(135deg, var(--m1) 0%, var(--m2) 40%, var(--m2) 60%, var(--m3) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}

.metal-dot {
  --ring: 2px;
  flex: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
}

.route-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin-bottom: 18px;
}

.metal-chip {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 4px 14px;
  border-radius: var(--r-pill);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--text);
  background:
    linear-gradient(135deg, var(--glass-highlight) -60%, transparent 45%),
    var(--glass-fill);
  box-shadow: inset 0 1px 0 var(--glass-highlight);
}

.route-head .route-sub {
  font-weight: 600;
  color: var(--text);
}

@media (forced-colors: active) {
  .metal::before,
  .route-tabs button[aria-selected="true"]::before {
    display: none;
  }

  .metal,
  .route-tabs button[aria-selected="true"] {
    border: 2px solid CanvasText;
  }
}

.route-panel {
  padding: 24px 20px 20px;
}

.route-panel[hidden] {
  display: none;
}

.route-stats {
  display: flex;
  gap: 32px;
  margin-bottom: 16px;
}

.route-stats div {
  display: flex;
  flex-direction: column;
}

.route-stats strong {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.route-stats span {
  color: var(--text-2);
  font-size: 0.9rem;
}

.route-panel p {
  color: var(--text-2);
  max-width: 56ch;
}

@media (min-width: 900px) {
  .routes {
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 72px;
  }
}

/* ---------- Tour page: stops ---------- */

.stops {
  display: grid;
  gap: 16px;
  margin: 40px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: stop;
}

.stop {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  padding: 12px;
  border-radius: var(--r-l);
  background: var(--surface);
  border: 1px solid var(--hairline);
  box-shadow: var(--card-edge);
  counter-increment: stop;
}

.stop .frame {
  display: block;
  aspect-ratio: 1;
  border-radius: var(--r-m);
  overflow: hidden;
  background: var(--surface-2);
}

.stop img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.stop h3 {
  margin-top: 2px;
  font-size: 1.2rem;
  font-weight: 650;
  letter-spacing: -0.015em;
}

.stop h3::before {
  content: counter(stop) ".";
  margin-right: 6px;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}

.stop p {
  margin-top: 6px;
  font-size: 0.95rem;
  color: var(--text-2);
}

@media (min-width: 768px) {
  .stops {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .stop {
    grid-template-columns: 148px minmax(0, 1fr);
    gap: 20px;
    padding: 14px;
  }
}

/* Grouped by route: each route's stops under its chip. */
.stops-route {
  margin-top: 40px;
}

.stops-route .route-head {
  margin-bottom: 0;
}

.stops-route + .stops {
  margin-top: 16px;
}

/* The routes after Highlights: small cards, image and name, that flip over
   to the snippet on hover (mouse) or tap. */
.flips {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.flip {
  position: relative;
  perspective: 1000px;
  counter-increment: stop;
}

.flip-inner {
  display: grid;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.6s var(--ease);
}

.flip-front,
.flip-back {
  grid-area: 1 / 1;
  padding: 8px;
  border-radius: var(--r-l);
  background: var(--surface);
  border: 1px solid var(--hairline);
  box-shadow: var(--card-edge);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.flip .frame {
  display: block;
  aspect-ratio: 1;
  border-radius: var(--r-m);
  overflow: hidden;
  background: var(--surface-2);
}

.flip img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.flip h3 {
  margin: 8px 4px 2px;
  font-size: 0.98rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.25;
}

.flip h3::before {
  content: counter(stop) ".";
  margin-right: 5px;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}

.flip-back {
  display: flex;
  align-items: center;
  padding: 14px;
  transform: rotateY(180deg);
  overflow: auto;
}

.flip-back p {
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--text-2);
}

/* Over the whole card, so a tap anywhere flips it. */
.flip-toggle {
  position: absolute;
  inset: 0;
  border: 0;
  padding: 0;
  background: none;
  border-radius: var(--r-l);
  cursor: pointer;
}

.flip-toggle:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.flip.is-flipped .flip-inner {
  transform: rotateY(180deg);
}

@media (hover: hover) {
  .flip:hover .flip-inner {
    transform: rotateY(180deg);
  }
}

/* No turning under reduced motion: the back fades in instead. */
@media (prefers-reduced-motion: reduce) {
  .flip-inner,
  .flip:hover .flip-inner,
  .flip.is-flipped .flip-inner {
    transform: none;
  }

  .flip-back {
    transform: none;
    opacity: 0;
  }

  .flip.is-flipped .flip-back {
    opacity: 1;
  }

  @media (hover: hover) {
    .flip:hover .flip-back {
      opacity: 1;
    }
  }
}

@media (min-width: 640px) {
  .flips {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
  }
}

@media (min-width: 900px) {
  .flips {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .flips {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

/* ---------- Tour page: highlights (masonry) ---------- */

.gallery {
  columns: 1;
  column-gap: 14px;
  margin-top: 40px;
}

.gallery figure {
  break-inside: avoid;
  margin: 0 0 22px;
}

.gallery .frame {
  border-radius: var(--r-l);
  overflow: hidden;
  background: var(--surface-2);
}

.gallery img {
  width: 100%;
}

.gallery figcaption {
  margin-top: 10px;
  font-size: 0.9rem;
  color: var(--text-2);
  max-width: 52ch;
}

@media (min-width: 640px) {
  .gallery {
    columns: 2;
  }
}

/* ---------- CTA band ---------- */

.cta-band {
  position: relative;
  isolation: isolate;
  display: grid;
  min-height: 420px;
  padding: 16px;
  border-radius: var(--r-xl);
  overflow: hidden;
  align-items: end;
  background: #2b2a33;
}

.cta-band picture,
.cta-band picture img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -1;
}

.cta-band .glass {
  max-width: 520px;
  padding: 28px;
  border-radius: var(--r-l);
}

.cta-band h2 {
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.08;
}

.cta-band p {
  margin: 10px 0 22px;
  color: var(--text-2);
}

@media (min-width: 768px) {
  .cta-band {
    padding: 28px;
    min-height: 480px;
  }
}

/* ---------- Preview clips ---------- */

/* One liquid-glass button that plays a tour's preview and stops it again.
   A round icon on the cards, a pill with words in the tour page's hero. */
.preview-btn {
  display: inline-grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border-radius: var(--r-pill);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform 0.2s var(--ease), background-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.preview-btn:hover {
  background: var(--glass-strong);
}

.preview-btn:active {
  transform: scale(0.96);
}

.preview-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.preview-btn .icon {
  width: 22px;
  height: 22px;
}

.preview-btn .icon-stop,
.preview-btn .when-playing,
.preview-btn.is-playing .icon-play,
.preview-btn.is-playing .when-stopped {
  display: none;
}

.preview-btn.is-playing .icon-stop {
  display: block;
}

.preview-btn.is-playing .when-playing {
  display: inline;
}

/* Playing: a soft ring in the cards' hover highlight, gently breathing.
   Not the accent: it is near-black, and vanishes on a dark photo. */
.preview-btn.is-playing {
  box-shadow: inset 0 1px 0 var(--glass-highlight), 0 0 0 2px var(--highlight-2), var(--glass-shadow);
}

@media (prefers-reduced-motion: no-preference) {
  .preview-btn.is-playing {
    animation: preview-breathe 2.4s var(--ease) infinite;
  }
}

@keyframes preview-breathe {
  50% {
    box-shadow: inset 0 1px 0 var(--glass-highlight), 0 0 0 5px color-mix(in srgb, var(--highlight-2) 45%, transparent), var(--glass-shadow);
  }
}

.preview-btn.is-wide {
  display: inline-flex;
  gap: 10px;
  width: auto;
  min-height: 48px;
  padding: 12px 20px;
  font-weight: 600;
  font-size: 0.975rem;
  line-height: 1.2;
  white-space: nowrap;
}

.preview-btn .preview-length {
  font-weight: 500;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}

/* On a card the length shows only while playing: the round button grows
   into a pill with the seconds left counting down. */
.preview-btn:not(.is-wide) .preview-length {
  display: none;
}

.preview-btn:not(.is-wide).is-playing {
  display: inline-flex;
  gap: 6px;
  width: auto;
  padding: 0 14px 0 12px;
}

.preview-btn:not(.is-wide).is-playing .preview-length {
  display: inline;
  font-weight: 600;
  color: var(--text);
}

/* On a card: over the photo's top right corner, beside (not inside) the
   card's link, so it can be pressed without opening the tour. */
.tour-grid > li {
  position: relative;
}

.tour-grid > li > .preview-btn {
  position: absolute;
  top: 20px;
  right: 20px;
  z-index: 1;
}

/* Playing needs JavaScript: without it the button would do nothing. */
html:not(.js) .preview-btn {
  display: none;
}

@media (max-width: 479px) {
  .hero-actions .preview-btn.is-wide {
    width: 100%;
    justify-content: center;
  }
}

/* ---------- Tour cards ---------- */

.tour-grid {
  display: grid;
  gap: 16px;
  margin: 32px 0 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 700px) {
  .tour-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .tour-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.tour-card {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: flex-end;
  min-height: 460px;
  padding: 10px;
  border-radius: var(--r-xl);
  overflow: hidden;
  text-decoration: none;
  background: #2b2a33;
}

.tour-card picture,
.tour-card picture img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -1;
  transition: transform 0.9s var(--ease);
}

.tour-card {
  transition: box-shadow 0.3s var(--ease);
}

.tour-card:hover {
  box-shadow: 0 0 0 2px var(--highlight-2), 0 20px 40px -24px var(--btn-shadow);
}

.tour-card:hover picture img {
  transform: scale(1.04);
}

.tour-card .glass {
  width: 100%;
  padding: 18px;
  border-radius: var(--r-l);
}

.tour-card h3 {
  font-size: 1.35rem;
  font-weight: 650;
  letter-spacing: -0.02em;
}

.tour-card .meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 8px;
  font-size: 0.9rem;
  color: var(--text-2);
}

.tour-card .meta span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.tour-card .go {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 14px;
  color: var(--accent-text);
  font-weight: 600;
}

.empty {
  margin-top: 32px;
  padding: 40px 24px;
  border-radius: var(--r-xl);
  border: 1px dashed var(--hairline);
  text-align: center;
}

.empty[hidden] {
  display: none;
}

.empty p {
  color: var(--text-2);
  margin: 8px auto 20px;
  max-width: 40ch;
}

.coming {
  margin-top: 48px;
  color: var(--text-2);
}

.photo-hero + .section-end {
  margin-top: 72px;
}

/* ---------- Home: floating tour tiles ----------
 * Pure CSS: each tile crosses the screen on a transform-only animation, with
 * its lane, depth, direction and phase baked in at build time. They sit just
 * above the dusk backdrop and below everything else.
 */

.floaters {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.floater {
  position: absolute;
  top: 0;
  left: var(--x);
  width: calc(150px * var(--s));
  padding: 5px;
  border-radius: 14px;
  background: var(--glass-fill);
  border: 1px solid var(--glass-edge);
  box-shadow: 0 14px 30px -18px var(--btn-shadow);
  opacity: 0;
}

/* A tile with a narrow crop comes wrapped in <picture>: lay it out as if it
   weren't there. */
.floater picture {
  display: contents;
}
.floater img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 10px;
}

.floater span {
  display: block;
  padding: 5px 3px 1px;
  font-size: calc(0.8rem * var(--s));
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (prefers-reduced-motion: no-preference) {
  .floater {
    animation: float-up var(--dur) linear var(--delay) infinite;
    will-change: transform, opacity;
  }

  /* Up from below the screen to above it, with a little sideways sway. */
  @keyframes float-up {
    0% {
      transform: translate3d(0, 105vh, 0) rotate(var(--tilt));
      opacity: 0;
    }
    12%,
    86% {
      opacity: calc(var(--s) * 0.42);
    }
    100% {
      transform: translate3d(var(--sway), -30vh, 0) rotate(calc(var(--tilt) * -1));
      opacity: 0;
    }
  }
}

/* Still: the tiles rest where they are, faint, like a pinboard behind the page. */
@media (prefers-reduced-motion: reduce) {
  .floater {
    top: var(--ys);
    opacity: calc(var(--s) * 0.45);
    transform: rotate(var(--tilt));
  }
}

/* ---------- Home: city carousel ---------- */

/* --picker-gap is the space both above the word (from the bottom of the
   header bar) and below it (to the cards), so the word sits exactly midway.
   The page starts 12px under the top of the sticky header and the bar ends
   2px short of --nav-h, hence nav-h + 10px to reach the bar's bottom edge. */
.city-picker {
  --picker-gap: 28px;
  display: grid;
  align-content: start;
  gap: 0;
  min-height: 100vh;
  min-height: 100dvh;
  padding: calc(var(--nav-h) + 10px + var(--picker-gap)) 0 16px;
  overflow: hidden;
}

.picker-head {
  position: relative;
  margin-bottom: var(--picker-gap);
  text-align: center;
}

/* A soft pool of page colour behind the heading, so tiles drifting past
   never sit directly under the text. */
.picker-head::before {
  content: "";
  position: absolute;
  inset: -70px -5% -60px;
  z-index: -1;
  background: radial-gradient(55% 60% at 50% 50%, var(--bg) 45%, transparent);
  opacity: 0.92;
  pointer-events: none;
}

/* One word at a time sweeps up into place and out again. 2.5 s each; the
   carousel's pause button stops it too. */
.word-swap {
  font-size: clamp(1.35rem, 2.6vw, 1.85rem);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--accent-text);
}

.word-swap-track {
  display: grid;
  justify-items: center;
  height: 1.4em;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 25%, #000 75%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 25%, #000 75%, transparent);
}

.word-swap-track > span {
  grid-area: 1 / 1;
  line-height: 1.4;
  opacity: 0;
  animation: word-swap 7.5s var(--ease) infinite;
}

.word-swap-track > span:nth-child(2) {
  animation-delay: 2.5s;
}

.word-swap-track > span:nth-child(3) {
  animation-delay: 5s;
}

@keyframes word-swap {
  0% {
    opacity: 0;
    transform: translateY(80%) skewX(-10deg);
    filter: blur(6px);
  }
  7%,
  28% {
    opacity: 1;
    transform: none;
    filter: blur(0);
  }
  34%,
  100% {
    opacity: 0;
    transform: translateY(-80%) skewX(10deg);
    filter: blur(6px);
  }
}

/* Paused carousel, or reduced motion: the three words sit still in a row. */
.city-picker:has(.carousel.is-stopped) .word-swap-track {
  display: flex;
  justify-content: center;
  gap: 0.6em;
  height: auto;
  -webkit-mask-image: none;
  mask-image: none;
}

.city-picker:has(.carousel.is-stopped) .word-swap-track > span {
  opacity: 1;
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .word-swap-track {
    display: flex;
    justify-content: center;
    gap: 0.6em;
    height: auto;
    -webkit-mask-image: none;
    mask-image: none;
  }

  .word-swap-track > span {
    opacity: 1;
    animation: none;
  }
}

.carousel {
  /* Card width: as big as the screen height allows once the nav, the word
     and the controls are placed (about 280px of them), capped for wide
     screens. */
  --w: min(400px, 78vw, calc((100vh - 280px) * 0.8));
  position: relative;
  height: calc(var(--w) * 1.25 + 68px);
  perspective: 1400px;
  touch-action: pan-y;
}

/* A frosted band the width of the screen behind the cards: tiles drifting
   behind it go soft, so the cards are the only sharp thing in that strip.
   Its top and bottom fade out rather than ending on a line. */
.carousel-floor {
  position: absolute;
  left: 50%;
  bottom: 62px;
  width: calc(var(--w) * 2.4);
  height: 46px;
  translate: -50% 0;
  pointer-events: none;
  background: radial-gradient(closest-side, var(--btn-shadow), transparent);
  opacity: 0.55;
}

@supports (height: 100dvh) {
  .carousel {
    --w: min(400px, 78vw, calc((100dvh - 280px) * 0.8));
  }
}

.slides {
  position: absolute;
  inset: 0 0 68px;
  margin: 0;
  padding: 0;
  list-style: none;
  transform-style: preserve-3d;
}

/* Positions: 0 is the open card, ±1 and ±2 lean back into stacks either
   side, "far" waits invisibly behind the middle. Without JS every slide is
   at 0 except as set below, so the list falls back to a row. */
.slide {
  --x: 0%;
  --z: 0px;
  --ry: 0deg;
  --o: 1;
  position: absolute;
  left: 50%;
  top: 0;
  width: var(--w);
  height: 100%;
  transform: translateX(-50%) translateX(var(--x)) translateZ(var(--z)) rotateY(var(--ry));
  opacity: var(--o);
  transition: transform 0.9s var(--ease), opacity 0.6s var(--ease), filter 0.6s var(--ease);
}

.slide[data-pos="-1"] { --x: -52%; --z: -170px; --ry: 42deg; --o: 0.95; }
.slide[data-pos="1"] { --x: 52%; --z: -170px; --ry: -42deg; --o: 0.95; }
.slide[data-pos="-2"] { --x: -84%; --z: -320px; --ry: 52deg; --o: 0.8; }
.slide[data-pos="2"] { --x: 84%; --z: -320px; --ry: -52deg; --o: 0.8; }
.slide[data-pos="-3"] { --x: -108%; --z: -460px; --ry: 58deg; --o: 0.5; }
.slide[data-pos="3"] { --x: 108%; --z: -460px; --ry: -58deg; --o: 0.5; }
.slide[data-pos="far"] { --z: -520px; --o: 0; pointer-events: none; }

.slide:not([data-pos="0"]) {
  cursor: pointer;
}

.slide-art img {
  transition: filter 0.6s var(--ease);
}

.slide:not([data-pos="0"]) .slide-art img {
  filter: saturate(0.8) brightness(0.88);
}

.slide-card {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: flex-end;
  height: 100%;
  padding: 12px;
  border-radius: var(--r-xl);
  overflow: hidden;
  text-decoration: none;
  color: var(--text);
  background: #2b2a33;
  box-shadow: 0 40px 70px -30px var(--btn-shadow), inset 0 0 0 1px var(--glass-edge);
}

.slide-art,
.slide-art picture,
.slide-art img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}

.slide-art img {
  object-fit: cover;
  object-position: 70% 50%;
}

.slide.is-soon .slide-card {
  background:
    radial-gradient(120% 80% at 100% 0%, var(--highlight-2), transparent 65%),
    linear-gradient(180deg, var(--highlight-2), var(--highlight) 60%, color-mix(in srgb, var(--highlight) 70%, var(--accent)));
}

.slide-blank {
  position: absolute;
  inset: 0 0 40%;
  display: grid;
  place-items: center;
}

.slide-blank-icon {
  width: 72px;
  height: 72px;
  color: rgb(255 255 255 / 0.8);
}

/* Kept to two lines so it never covers more than a quarter of the photo. */
.slide-label {
  display: grid;
  gap: 2px;
  width: 100%;
  padding: 12px 16px;
  border-radius: var(--r-l);
}

.slide-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  min-width: 0;
}

/* Side cards show just the name and count; the rest returns when the card
   comes to the front. */
.slide:not([data-pos="0"]) .slide-go {
  display: none;
}

.slide-name {
  font-family: var(--font-display);
  font-size: 1.55rem;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.slide-meta {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-2);
}

.slide-go {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 4px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent-text);
}

/* The dwell, drawn as a line along the top of the open card. */
.slide-card::after {
  content: "";
  position: absolute;
  left: 18px;
  right: 18px;
  top: 12px;
  height: 3px;
  border-radius: 3px;
  background: var(--highlight-2);
  transform: scaleX(0);
  transform-origin: left;
  opacity: 0;
}

.carousel.is-playing .slide.is-timing .slide-card::after {
  opacity: 1;
  animation: dwell var(--dwell, 3s) linear forwards;
}

.carousel.is-held .slide.is-timing .slide-card::after {
  animation-play-state: paused;
}

@keyframes dwell {
  to {
    transform: scaleX(1);
  }
}

.carousel-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  gap: 12px;
}

.carousel-controls button {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: var(--r-pill);
  color: var(--text);
  cursor: pointer;
  transition: transform 0.2s var(--ease);
}

.carousel-controls button:hover {
  background: var(--glass-strong);
}

.carousel-controls button:active {
  transform: scale(0.96);
}

.carousel-toggle .icon-play,
.carousel.is-stopped .carousel-toggle .icon-pause {
  display: none;
}

.carousel.is-stopped .carousel-toggle .icon-play {
  display: block;
}

/* No JS: the slides sit in a scrollable row instead. */
html:not(.js) .slides {
  position: static;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: var(--w);
  gap: 16px;
  overflow-x: auto;
  padding: 0 var(--gutter);
  height: calc(var(--w) * 1.3);
}

html:not(.js) .slide {
  position: relative;
  left: auto;
  transform: none;
}

html:not(.js) .carousel-controls {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .slide {
    transition: opacity 0.2s linear;
  }
}

/* ---------- City page ---------- */

.photo-hero.is-city {
  min-height: min(72dvh, 640px);
}

.city-tours-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px 32px;
}


.tour-grid > li[hidden] {
  display: none;
}

/* ---------- Glass control ---------- */

.glass-control {
  position: fixed;
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 6px 6px 14px;
  border-radius: var(--r-pill);
}

.glass-control-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-right: 4px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-2);
}

.glass-control label {
  position: relative;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--r-pill);
  font-size: 0.85rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  cursor: pointer;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}

.glass-control input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.glass-control label:hover {
  background: var(--accent-soft);
}

.glass-control label:has(input:checked) {
  background: var(--accent);
  color: var(--accent-ink);
}

.glass-control label:has(input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* ---------- Footer ---------- */

.site-footer {
  margin-top: 40px;
  padding-block: 24px 32px;
  font-size: 0.95rem;
}

/* Liquid glass behind the footer, so its small print reads cleanly over the
   backdrop (and over the drifting tiles on the home page). */
.footer-grid.glass,
.footer-legal.glass {
  border-radius: var(--r-xl);
  background:
    linear-gradient(160deg, var(--glass-highlight) -40%, transparent 40%),
    var(--glass-strong);
}

.footer-grid.glass {
  padding: 28px;
}

.footer-grid {
  display: grid;
  gap: 36px;
}

.footer-grid h2 {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-2);
  margin-bottom: 12px;
  font-family: var(--font);
}

.footer-grid ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
}

.footer-grid a {
  text-decoration: none;
}

.footer-grid a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.footer-brand p {
  margin-top: 12px;
  max-width: 34ch;
  color: var(--text-2);
}

.footer-legal {
  margin-top: 12px;
  padding: 18px 28px;
  display: grid;
  gap: 6px;
  font-size: 0.85rem;
  color: var(--text-2);
}

/* Unset legal details: visible on purpose, so nobody ships them by accident. */
.placeholder {
  padding: 1px 6px;
  border-radius: 6px;
  border: 1px dashed currentColor;
  font-style: normal;
}

@media (min-width: 768px) {
  .footer-grid {
    grid-template-columns: 2fr 1fr 1fr 1.4fr;
  }
}

/* ---------- 404 ---------- */

.not-found {
  min-height: 70dvh;
  display: grid;
  align-content: center;
  gap: 16px;
  padding-top: calc(var(--nav-h) + 40px);
}

.not-found h1 {
  font-size: clamp(2.2rem, 5vw, 3.4rem);
  letter-spacing: -0.035em;
}

.not-found p {
  color: var(--text-2);
  max-width: 48ch;
}

/* ---------- Legal pages (privacy, terms, support) ---------- */

.legal-page {
  padding-top: calc(var(--nav-h) + 32px);
  padding-bottom: 56px;
}

.legal-doc {
  max-width: 46rem;
  margin-inline: auto;
  padding: clamp(22px, 5vw, 48px);
  border-radius: var(--r-l);
  /* Long reading: a touch more solid than the default glass. */
  background: linear-gradient(135deg, var(--glass-highlight) -60%, transparent 45%), var(--glass-strong);
  font-size: 1.0625rem;
  line-height: 1.65;
  overflow-wrap: anywhere;
}

.legal-doc h1 {
  font-size: clamp(2.1rem, 6vw, 3rem);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.legal-doc h2 {
  font-size: clamp(1.45rem, 4vw, 1.75rem);
  margin-top: 2.2em;
  line-height: 1.2;
}

.legal-doc h3 {
  font-family: var(--font);
  font-size: 1.0625rem;
  font-weight: 700;
  margin-top: 1.6em;
}

.legal-doc p,
.legal-doc ul {
  margin: 0.8em 0 0;
}

.legal-doc ul {
  padding-left: 1.25em;
}

.legal-doc li + li {
  margin-top: 0.45em;
}

.legal-doc a {
  color: var(--accent-text);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.legal-doc code {
  font-size: 0.92em;
  padding: 0.05em 0.35em;
  border-radius: 6px;
  background: var(--accent-soft);
}

.legal-doc .updated {
  margin-top: 0.4em;
  color: var(--text-2);
  font-size: 0.95rem;
}

.legal-nav {
  margin-top: 2.6em;
  padding-top: 1.2em;
  border-top: 1px solid var(--hairline);
}

.legal-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.95rem;
}

.legal-nav a[aria-current="page"] {
  color: var(--text-2);
  text-decoration: none;
}

/* ---------- Motion ---------- */

@media (prefers-reduced-motion: no-preference) {
  /* Starts readable, so a stalled observer never leaves text hidden. */
  .js .reveal {
    opacity: 0.45;
    transform: translateY(20px);
    transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
    transition-delay: calc(var(--i, 0) * 70ms);
  }

  .js .reveal.is-in {
    opacity: 1;
    transform: none;
  }

  .hero-panel {
    animation: rise 0.9s var(--ease) both;
  }

  .photo-hero > picture img {
    animation: settle 1.6s var(--ease) both;
  }

  @keyframes rise {
    from {
      opacity: 0;
      transform: translateY(28px);
    }
  }

  @keyframes settle {
    from {
      transform: scale(1.06);
    }
  }
}

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

/* ---------- City page: the same city in other languages ---------- */

.also-in {
  margin: 0;
  color: var(--text-2);
}

.also-in .count {
  font-size: 0.85em;
  color: var(--text-2);
}

/* "(in English)" after a link to a page only in English. */
.link-note {
  font-size: 0.85em;
  color: var(--text-2);
}

/* ---------- Contact ---------- */

.contact-page {
  padding-top: calc(var(--nav-h) + 32px);
  padding-bottom: 56px;
}

.contact-card {
  display: grid;
  gap: clamp(24px, 4vw, 48px);
  max-width: 64rem;
  margin-inline: auto;
  padding: clamp(22px, 5vw, 48px);
  border-radius: var(--r-xl);
  background: linear-gradient(135deg, var(--glass-highlight) -60%, transparent 45%), var(--glass-strong);
}

@media (min-width: 860px) {
  .contact-card {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    align-items: start;
  }
}

.contact-intro h1 {
  font-size: clamp(2rem, 4.5vw, 3rem);
  letter-spacing: -0.035em;
  line-height: 1.05;
}

.contact-intro .lede {
  margin-top: 16px;
  font-size: 1.1rem;
  color: var(--text-2);
}

.contact-points {
  display: grid;
  gap: 10px;
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
}

.contact-points li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 500;
}

.contact-points .icon {
  color: var(--accent);
}

.contact-form {
  display: grid;
  gap: 18px;
}

.field {
  display: grid;
  gap: 6px;
}

.field-label {
  font-weight: 600;
}

.field-hint,
.form-note {
  font-size: 0.875rem;
  color: var(--text-2);
}

.form-note {
  margin: 0;
}

.field input,
.field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-m);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  /* 16px or more, so iOS doesn't zoom into the field. */
  font-size: max(1rem, 16px);
}

.field textarea {
  resize: vertical;
  min-height: 9rem;
}

.field input:focus-visible,
.field textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: transparent;
}

.contact-form .btn {
  justify-self: start;
}

/* Netlify's honeypot: real people never see it, bots fill it in. */
.hp {
  display: none;
}

/* ---------- web store ---------- */

/* Needs main.js to talk to the API, so it only shows with JavaScript. */
.buy-box {
  display: none;
}

.js .buy-box {
  display: grid;
  gap: 14px;
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--hairline);
}

.buy-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-weight: 600;
}

.buy-price {
  margin: 0;
  font-size: 1.25rem;
}

.buy-price [data-buy-was] {
  color: var(--text-2);
  text-decoration: line-through;
  font-size: 1rem;
}

.buy-off {
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: var(--accent-soft);
  color: var(--accent-text);
  font-size: 0.875rem;
  font-weight: 600;
}

.buy-code summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  color: var(--accent-text);
  font-weight: 600;
}

.buy-code-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 10px;
  margin-top: 10px;
}

.buy-consent {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px;
  align-items: start;
  font-size: 0.9375rem;
  cursor: pointer;
}

.buy-consent input {
  width: 18px;
  height: 18px;
  margin: 2px 0 0;
  accent-color: var(--accent, currentColor);
}

.buy-status {
  margin: 0;
  min-height: 1.4em;
  font-size: 0.9375rem;
}

.buy-status.is-error {
  color: #a3261c;
}

.buy-box .btn-primary {
  justify-self: start;
}

.buy-box .btn:disabled {
  opacity: 0.6;
  cursor: progress;
}

/* ---------- Checkout thank-you: where to listen ---------- */

.listen {
  display: grid;
  gap: 12px;
  margin-top: 16px;
}

.listen h2 {
  font-size: clamp(1.4rem, 3vw, 1.8rem);
  letter-spacing: -0.02em;
}

.listen-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}

.listen-option {
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: 10px;
  padding: 20px;
  border-radius: var(--r-l);
}

.listen-option h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 1.125rem;
}

.not-found .listen-option p {
  margin: 0;
  max-width: none;
}

.listen-option .listen-note {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px;
  align-items: start;
  padding: 10px 12px;
  border-radius: var(--r-m);
  background: var(--accent-soft);
  color: var(--text);
  font-size: 0.875rem;
}

.listen-note .icon {
  margin-top: 2px;
}

.listen-action {
  align-self: end;
}

/* ---------- Header: Buy here ---------- */

/* The one filled item in the bar, so the way to buy is always in sight. */
.nav-links > a.nav-buy {
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 650;
}

.nav-links > a.nav-buy:hover,
.nav-links > a.nav-buy[aria-current="page"] {
  background: color-mix(in srgb, var(--accent) 86%, var(--text));
  color: var(--accent-ink);
}

/* It keeps its words when the other links shrink to icons, until phone
   widths, where the filled bag alone has to do (the link keeps its name for
   screen readers in aria-label). */
@media (max-width: 600px) {
  .nav-links > a.nav-buy .nav-label {
    display: inline;
  }
}

@media (max-width: 480px) {
  .nav-links > a.nav-buy .nav-label {
    display: none;
  }
}

/* ---------- Store ---------- */

.section.store {
  padding-top: calc(var(--nav-h) + 40px);
}

.store-head h1 {
  font-size: clamp(2.2rem, 5vw, 3.4rem);
  letter-spacing: -0.035em;
}

.store-head .lede {
  max-width: 56ch;
  color: var(--text-2);
}

.store-filters {
  display: none;
}

/* Filtering needs JavaScript; without it the whole list shows. */
.js .store-filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  align-items: end;
  gap: 12px 16px;
  margin-top: 24px;
  padding: 16px;
  border-radius: var(--r-l);
}

.store-filters .field-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.9rem;
}

.store-filters select {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-m);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: max(1rem, 16px);
}

.store-filters select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.store-count {
  margin: 0;
  padding-bottom: 10px;
  color: var(--text-2);
  font-weight: 600;
}

.store-list {
  display: grid;
  gap: 14px;
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}

/* A tour: its square tile, then name and summary, then the price and the
   button. On phones the price and button take their own row underneath. */
.store-row {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  gap: 14px 16px;
  padding: 14px;
  border-radius: var(--r-l);
}

.store-row[hidden] {
  display: none;
}

@media (min-width: 768px) {
  .store-row {
    grid-template-columns: 168px minmax(0, 1fr) auto;
    align-items: center;
    padding: 16px;
  }
}

.store-row-media {
  position: relative;
  align-self: start;
}

.store-row-media img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--r-m);
}

.store-row-media .preview-btn {
  position: absolute;
  right: 6px;
  bottom: 6px;
}

.store-row-city {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 0 0 4px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-2);
}

.store-row-text h2 {
  margin: 0;
  font-size: 1.2rem;
  letter-spacing: -0.01em;
}

.store-row-text h2 a {
  color: inherit;
  text-decoration: none;
}

.store-row-text h2 a:hover {
  text-decoration: underline;
}

.store-row-summary {
  display: -webkit-box;
  margin: 6px 0 0;
  overflow: hidden;
  color: var(--text-2);
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
}

.store-row .meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 8px;
  font-size: 0.9rem;
  color: var(--text-2);
}

.store-row .meta span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.store-row-buy {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

@media (min-width: 768px) {
  .store-row-buy {
    grid-column: auto;
    flex-direction: column;
    align-items: flex-end;
    min-width: 150px;
  }
}

.store-row-price {
  font-size: 1.25rem;
  white-space: nowrap;
}

.store .empty[hidden] {
  display: none;
}

/* ---------- Store: the buy dialog ---------- */

.buy-dialog {
  width: min(720px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  margin: auto;
  padding: 0;
  overflow: auto;
  border-radius: var(--r-xl);
  background: var(--glass-solid);
  color: var(--text);
}

.buy-dialog::backdrop {
  background: rgb(10 14 20 / 0.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.buy-dialog-media img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.buy-dialog-body {
  display: grid;
  gap: 12px;
  padding: 20px clamp(16px, 4vw, 28px) 24px;
}

.buy-dialog-body h2 {
  margin: 0;
  font-size: clamp(1.5rem, 4vw, 2rem);
  letter-spacing: -0.02em;
}

.buy-dialog-body > p {
  margin: 0;
}

.buy-dialog .hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
}

.buy-dialog .buy-box {
  margin-top: 4px;
}

.dialog-close {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-pill);
  background: var(--glass-solid);
  color: var(--text);
  cursor: pointer;
}

.dialog-close:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- Tour times: the note under them ---------- */

.duration-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 16px 0 0;
  max-width: 70ch;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--text-2);
}

.duration-note .icon {
  flex: none;
  margin-top: 0.15em;
}

.route-card > .duration-note {
  margin: 4px 12px 12px;
}

.buy-dialog-body > .duration-note {
  margin: 0;
}

/* ---------- Checkout: Paddle inline, on the site's own page ---------- */

.checkout-pay-section {
  padding-top: calc(var(--nav-h) + 32px);
}

.checkout-head {
  display: grid;
  gap: 10px;
  margin-bottom: 24px;
}

.checkout-back {
  justify-self: start;
}

.checkout-head h1 {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: clamp(1.75rem, 5vw, 2.5rem);
  letter-spacing: -0.02em;
}

.checkout-head h1 .icon {
  width: 0.8em;
  height: 0.8em;
  color: var(--text-2);
}

.checkout-head p {
  margin: 0;
  color: var(--text-2);
}

.checkout-grid {
  display: grid;
  gap: 16px;
  align-items: start;
}

.checkout-summary,
.checkout-frame {
  border-radius: var(--r-xl);
}

.checkout-summary {
  padding: 20px clamp(16px, 4vw, 24px);
}

.checkout-summary[hidden],
.checkout-frame[hidden] {
  display: none;
}

.checkout-summary h2 {
  margin: 0 0 6px;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-2);
}

.checkout-item {
  margin: 0 0 14px;
  font-size: 1.15rem;
  font-weight: 650;
}

.checkout-summary dl {
  display: grid;
  gap: 8px;
  margin: 0;
}

.checkout-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  color: var(--text-2);
}

.checkout-row[hidden] {
  display: none;
}

.checkout-row dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.checkout-row[data-pay-row="total"] {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--hairline);
  font-size: 1.15rem;
  font-weight: 650;
  color: var(--text);
}

/* Paddle's frame is transparent; the card behind it is solid enough for its
   fields to read on any background. */
.checkout-frame {
  padding: 8px;
  background: var(--glass-solid);
  min-height: 466px;
}

@media (min-width: 860px) {
  .checkout-grid {
    grid-template-columns: minmax(0, 1fr) 320px;
  }

  .checkout-summary {
    order: 2;
    position: sticky;
    top: calc(var(--nav-h) + 16px);
  }
}
