/* =====================================================================
   SegwayBP — design tokens
   Palette built from Japanese traditional colours (日本の伝統色).
   Guiding principle from that tradition: neutral base, raised lightness,
   subdued saturation — which reads as calm rather than corporate.
     生成り  kinari        unbleached silk   #FBF8F1
     柳鼠    yanaginezumi  willow-grey       #C8D5BB
     青磁色  seiji         celadon           #7EBEA5
     木賊色  tokusa        scouring-rush     #3B7960
     千歳緑  chitose-midori ancient pine     #316745
     洗柿    araigaki      washed persimmon  #EE9A82
     玉子色  tamago        egg yellow        #F2C46D
     墨      sumi          ink               #1C1C1C
   ===================================================================== */
:root {
  /* Light theme rebuilt for a crisper, current feel: the base moved off the
     warm cream (which read dated) onto a cool near-white, text contrast went
     up sharply, and the accents are more saturated. Every foreground/background
     pair below was contrast-checked — all clear WCAG AA. */
  /* The page itself is tinted, not white — white pages with white cards read
     clinical. Cards stay white so they lift off the coloured ground. */
  --bg: #E7F0E9;
  --surface: #FFFFFF;
  --surface-alt: #D8E8DD;
  --text-primary: #0F1714;          /* 15:1 on the tinted background */
  --text-secondary: #4E5D57;
  --text-muted: #6E7D76;
  --border: #C6DBCE;
  --brand: #0C8060;                 /* white text 4.9:1 */
  --brand-dark: #096349;            /* 7.3:1 */
  --brand-contrast: #FFFFFF;
  --accent: #CC4522;                /* white text 4.7:1 */
  --accent-contrast: #FFFFFF;
  --accent-tint: #FDE8E1;
  --gold: #EBA92C;                  /* dark text 8.0:1 */
  --gold-contrast: #2B1D06;
  --gold-tint: #FCF1D8;
  --brand-tint: #E1F1EA;
  /* 藍色 ai-iro — indigo, the fourth hue that breaks the green monotony */
  --indigo: #20657F;                /* 6.5:1 as text */
  --indigo-tint: #E3EFF4;
  --success: #0C8060;
  --success-tint: #E1F1EA;
  --danger: #C0392B;
  --glass-bg: linear-gradient(135deg, rgba(255,255,255,.70), rgba(255,255,255,.35));
  --glass-border: rgba(255,255,255,.65);
  --shadow: 0 1px 2px rgba(12,60,42,0.06), 0 10px 30px rgba(12,60,42,0.09);
  --shadow-lg: 0 24px 60px rgba(12,60,42,0.16);
  --radius: 18px;
  --radius-sm: 12px;
  --radius-pill: 999px;
  --font-head: "Space Grotesk", sans-serif;
  --font-body: "Inter", sans-serif;
  --header-h: 76px;
  /* The Segway mark hides its own overlaps by painting them in the page colour,
     the way the parts of a real machine occlude each other. This is that colour. */
  --mark-bg: #FFFFFF;
}

[data-theme="dark"] {
  --mark-bg: #101714;
  /* Near-black base so the aurora glow reads like light in a dark room */
  --bg: #080C0A;
  --surface: #101714;
  --surface-alt: #16201B;
  --text-primary: #F4F2EA;
  --text-secondary: #B4C1B6;
  --text-muted: #7E8C81;
  --border: #22302A;
  --brand: #7EBEA5;
  --brand-dark: #9BD1BB;
  --brand-contrast: #06120E;
  --accent: #EE9A82;
  --accent-contrast: #2B1000;
  --accent-tint: #2E1F1A;
  --gold: #F2C46D;
  --gold-contrast: #2B1D06;
  --gold-tint: #2C2312;
  --brand-tint: #142823;
  --indigo: #7FB3C8;
  --indigo-tint: #16262E;
  --success: #7EBEA5;
  --success-tint: #142823;
  --danger: #E0907E;
  --shadow: 0 1px 2px rgba(0,0,0,0.5), 0 8px 28px rgba(0,0,0,0.55);
  --shadow-lg: 0 24px 60px rgba(0,0,0,0.7);
  --glass-bg: linear-gradient(135deg, rgba(255,255,255,.10), rgba(255,255,255,.03));
  --glass-border: rgba(255,255,255,.14);
}

/* =====================================================================
   Aurora background — slow drifting mesh gradient behind the whole page.
   Sits on a fixed layer at z-index -2 so every section floats above it.
   ===================================================================== */
.aurora-bg {
  position: fixed;
  /* deliberately larger than the viewport so the scroll parallax below can
     move it without ever exposing an edge */
  inset: -30vh -14vw;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
  background: var(--bg);
  transform: translate3d(var(--aur-x, 0px), var(--aur-y, 0px), 0);
  will-change: transform;
}
.aurora-bg span {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(90px);
  will-change: transform, opacity;
  transition: opacity .4s linear;
}
/* Scroll drives these four, so different colours take the lead as you move
   down the page. Defaults mirror the JS resting state at scroll=0 (see
   main.js's aurora crossfade PHASE/FLOOR) so reduced-motion/no-JS visitors
   get the same single-lead-colour hero seam instead of all four at once. */
.aurora-bg .a1 { opacity: var(--o1, 1); }
.aurora-bg .a2 { opacity: var(--o2, .14); }
.aurora-bg .a3 { opacity: var(--o3, .1); }
.aurora-bg .a4 { opacity: var(--o4, .18); }
/* Light mode: soft celadon / persimmon washes on unbleached-silk base */
.aurora-bg .a1 {
  width: 62vw; height: 62vw; min-width: 520px; min-height: 520px;
  top: -18vw; left: -12vw;
  background: radial-gradient(circle, rgba(38,196,142,.58) 0%, rgba(38,196,142,0) 70%);
  animation: auroraDrift1 26s ease-in-out infinite alternate;
}
.aurora-bg .a2 {
  width: 55vw; height: 55vw; min-width: 460px; min-height: 460px;
  top: 22vh; right: -16vw;
  background: radial-gradient(circle, rgba(46,160,212,.40) 0%, rgba(46,160,212,0) 70%);
  animation: auroraDrift2 32s ease-in-out infinite alternate;
}
.aurora-bg .a3 {
  width: 48vw; height: 48vw; min-width: 400px; min-height: 400px;
  bottom: -14vh; left: 18vw;
  background: radial-gradient(circle, rgba(255,126,80,.42) 0%, rgba(255,126,80,0) 70%);
  animation: auroraDrift3 38s ease-in-out infinite alternate;
}
.aurora-bg .a4 {
  width: 40vw; height: 40vw; min-width: 340px; min-height: 340px;
  top: 55vh; left: 38vw;
  /* Amber, not near-white: at .38 this blob washed the upper page to a cream
     that read as a white band right where the hero fade lands. */
  background: radial-gradient(circle, rgba(242,166,52,.20) 0%, rgba(242,166,52,0) 70%);
  animation: auroraDrift4 30s ease-in-out infinite alternate;
}
/* Dark mode: deeper jade glow, higher intensity so it reads on near-black */
/* Dark: brighter, more saturated blobs so they glow against near-black */
[data-theme="dark"] .aurora-bg .a1 { background: radial-gradient(circle, rgba(96,214,175,.44) 0%, rgba(96,214,175,0) 68%); }
[data-theme="dark"] .aurora-bg .a2 { background: radial-gradient(circle, rgba(42,168,133,.50) 0%, rgba(42,168,133,0) 68%); }
[data-theme="dark"] .aurora-bg .a3 { background: radial-gradient(circle, rgba(238,154,130,.26) 0%, rgba(238,154,130,0) 70%); }
[data-theme="dark"] .aurora-bg .a4 { background: radial-gradient(circle, rgba(80,170,205,.26) 0%, rgba(80,170,205,0) 70%); }

@keyframes auroraDrift1 {
  0%   { transform: translate3d(0,0,0) scale(1); }
  100% { transform: translate3d(8vw, 10vh, 0) scale(1.15); }
}
@keyframes auroraDrift2 {
  0%   { transform: translate3d(0,0,0) scale(1.1); }
  100% { transform: translate3d(-10vw, -8vh, 0) scale(1); }
}
@keyframes auroraDrift3 {
  0%   { transform: translate3d(0,0,0) scale(1); }
  100% { transform: translate3d(12vw, -12vh, 0) scale(1.2); }
}
@keyframes auroraDrift4 {
  0%   { transform: translate3d(0,0,0) scale(1.05); }
  100% { transform: translate3d(-14vw, 8vh, 0) scale(.9); }
}
@media (prefers-reduced-motion: reduce) {
  .aurora-bg span { animation: none !important; }
}

* { box-sizing: border-box; }
/* Safety net: if the aurora layer is ever offset, the page behind it must
   still be the theme colour and never the browser's default white. */
html { scroll-behavior: smooth; background: var(--bg); }
body {
  margin: 0;
  font-family: var(--font-body);
  background: transparent; /* aurora layer shows through */
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
  transition: color .25s ease;
  overflow-x: hidden;
  width: 100%;
}
/* Light theme: a soft tint separates alternating bands.
   Dark theme: no band at all. Stacking translucent tints over a near-black
   base produced visible horizontal stripes — worse where two tinted sections
   sit back to back — so the aurora alone carries the depth instead. */
/* No section paints its own band any more, in either theme. A flat tint has
   hard top and bottom edges, which is exactly what made the page read as a
   stack of separate blocks. Depth comes from the aurora layer and from the
   cards floating on it instead. */
.section-tint { background: none; }
/* Nothing may push the page wider than the viewport on phones */
img, video, iframe, table { max-width: 100%; }
h1, h2, h3, h4, p, span, a, li { overflow-wrap: break-word; }
/* Grid/flex children default to min-width:auto, which lets long words blow out
   the track. Reset it so every layout can actually shrink to phone widths. */
.tour-grid > *, .tour-grid-4 > *, .related-row > *, .feature-grid > *,
.testimonial-grid > *, .split > *, .detail-grid > *, .mb-grid > *,
.grid-2 > *, .grid-3 > *, .quick-facts > *, .opt-grid > *,
.footer-grid > *, .mb-rental-grid > * { min-width: 0; }

/* Scroll-reveal: cards/grid items fade + rise into place once as they enter
   the viewport (main.js observes .reveal-up and adds .in, then unobserves —
   same one-shot IntersectionObserver pattern as .awards-strip). Stagger is a
   handful of nth-child delays, not JS-computed, so it stays cheap. Excludes
   the hero/stat rail on purpose — that element has its own documented
   entrance-animation history (see CLAUDE.md); do not add .reveal-up there. */
.reveal-up { opacity: 0; transform: translateY(18px); transition: opacity .6s cubic-bezier(.16,1,.3,1), transform .6s cubic-bezier(.16,1,.3,1); }
.reveal-up.in { opacity: 1; transform: none; }
.reveal-up:nth-child(2) { transition-delay: .08s; }
.reveal-up:nth-child(3) { transition-delay: .16s; }
.reveal-up:nth-child(4) { transition-delay: .24s; }
.reveal-up:nth-child(n+5) { transition-delay: .3s; }
@media (prefers-reduced-motion: reduce) {
  .reveal-up { opacity: 1; transform: none; transition: none; }
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 700;
  line-height: 1.12;
  margin: 0 0 .5rem;
  letter-spacing: -0.01em;
}
.hl-accent {
  color: var(--accent); /* fallback if background-clip:text unsupported */
  background: linear-gradient(100deg, var(--accent) 0%, var(--accent) 42%, var(--gold) 50%, var(--accent) 58%, var(--accent) 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: hl-shimmer 2.5s linear infinite;
}
@keyframes hl-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -100% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .hl-accent { animation: none; background: none; -webkit-text-fill-color: currentColor; color: var(--accent); }
}
p { line-height: 1.7; color: var(--text-secondary); margin: 0 0 1rem; }
.container { max-width: 1180px; margin: 0 auto; padding: 0 24px; }
/* Wider track for the tour showcase so cards read large on big laptops */
.container-wide { max-width: 1560px; margin: 0 auto; padding: 0 40px; }
/* 96 -> 128. The single change with the biggest effect on how expensive a page
   feels: premium sites give sections noticeably more air than this was giving
   them, and generous whitespace also measurably improves comprehension. */
.section { padding: 128px 0; }
.section-tight { padding: 56px 0; }
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--brand-dark);
  margin-bottom: 16px;
}
[data-theme="dark"] .eyebrow { color: var(--brand); }
.eyebrow::before {
  content: "";
  width: 22px; height: 2px;
  background: var(--accent);
  display: inline-block;
  border-radius: 2px;
}
.section-head { max-width: 640px; margin-bottom: 52px; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head.center .eyebrow::before { display: none; }
h1 { font-size: clamp(2.1rem, 6vw, 4.6rem); text-wrap: balance; max-width: 22ch; }
h2 { font-size: clamp(1.7rem, 4vw, 2.75rem); text-wrap: balance; max-width: 24ch; }
.section-head.center h2 { margin-left: auto; margin-right: auto; }
h3 { font-size: 1.35rem; text-wrap: balance; }
.lead { font-size: 1.13rem; color: var(--text-secondary); max-width: 52ch; text-wrap: pretty; }
.section-head.center .lead { margin-left: auto; margin-right: auto; }

/* ===== Buttons ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 15px;
  padding: 14px 26px;
  border-radius: var(--radius-pill);
  border: none;
  cursor: pointer;
  transition: transform .15s ease, background .2s ease, box-shadow .2s ease;
  white-space: nowrap;
}
.btn:active { transform: scale(.97); }
.btn-primary { background: var(--brand); color: var(--brand-contrast); box-shadow: 0 8px 20px -8px var(--brand); }
.btn-primary:hover { background: var(--brand-dark); transform: translateY(-1px); }
.btn-accent { background: var(--accent); color: var(--accent-contrast); box-shadow: 0 8px 20px -8px var(--accent); }
.btn-accent:hover { filter: brightness(1.06); transform: translateY(-1px); box-shadow: 0 12px 28px -8px var(--accent); }
.btn-ghost { background: transparent; color: var(--text-primary); border: 1.5px solid var(--border); }
.btn-ghost:hover { border-color: var(--brand); color: var(--brand-dark); }
[data-theme="dark"] .btn-ghost:hover { color: var(--brand); }
.btn-dark { background: var(--text-primary); color: var(--bg); }
.btn-dark:hover { opacity: .88; }
.btn-whatsapp { background: #22B559; color: #fff; box-shadow: 0 8px 20px -8px #22B559; }
.btn-whatsapp:hover { background: #1B9C4A; transform: translateY(-1px); }
.btn-block { width: 100%; }
.btn-sm { padding: 10px 18px; font-size: 13px; }

/* ===== Header ===== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  transition: background .35s ease, border-color .35s ease, backdrop-filter .35s ease;
}
/* Over the hero video: glass-free, fully transparent, light type */
.site-header.at-top {
  background: transparent;
  backdrop-filter: none;
  border-bottom-color: transparent;
}
.site-header.at-top .logo,
.site-header.at-top .nav-links a { color: #fff; text-shadow: 0 1px 10px rgba(0,0,0,.45); }
.site-header.at-top .nav-links a:hover,
.site-header.at-top .nav-links a.active { color: var(--gold); }
.site-header.at-top .logo span.bp { color: var(--accent); }
.site-header.at-top .theme-toggle,
.site-header.at-top .hamburger {
  background: rgba(255,255,255,.14);
  border-color: rgba(255,255,255,.28);
  color: #fff;
  backdrop-filter: blur(6px);
}
.site-header .container { display: flex; align-items: center; justify-content: space-between; gap: 28px; }
.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: -0.02em;
  flex: none;
}
.logo img { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; }
.logo span.bp { color: var(--accent); }
/* Flex `gap` needs Chrome 84+; old TV WebViews (Hisense VIDAA <84) ignore it and
   jam the nav into "HomeOur proposals…". Adjacent-sibling margins give identical
   spacing on modern browsers AND work on old engines — no double-spacing. */
.nav-links { display: flex; align-items: center; flex: 1; justify-content: center; }
.nav-links > * + * { margin-left: 30px; }
.nav-links a {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-secondary);
  transition: color .15s;
  white-space: nowrap;
}
.nav-links a { display: inline-flex; align-items: center; }
.nav-links a > * + * { margin-left: 7px; }
.mb-icon { width: 18px; height: 18px; flex: none; }
.eyebrow .mb-icon { width: 20px; height: 20px; color: var(--accent); }
.nav-links a:hover, .nav-links a.active { color: var(--brand-dark); }
[data-theme="dark"] .nav-links a:hover, [data-theme="dark"] .nav-links a.active { color: var(--brand); }
.header-actions { display: flex; align-items: center; flex: none; }
.header-actions > * + * { margin-left: 14px; }
.theme-toggle {
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--text-primary);
  font-size: 18px;
}
.theme-toggle:hover { border-color: var(--brand); }
.icon-sun, .icon-moon { display: none; font-size: 18px; line-height: 0; }
[data-theme="light"] .icon-sun { display: block; }
[data-theme="dark"] .icon-moon { display: block; }
.hamburger { display: none; width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--border); background: var(--surface); color: var(--text-primary); font-size: 18px; align-items: center; justify-content: center; cursor: pointer; }

/* ===== Hero — minimal, centred, video-ready =====
   Pulled up under the sticky header so the video runs edge-to-edge behind
   it — no separate band above the media. Pages without a hero are unaffected. */
.hero {
  position: relative;
  margin-top: calc(var(--header-h) * -1);
  min-height: 88vh;                 /* fallback for old TV (<Chrome 79, no min()) */
  min-height: min(94vh, 880px);
  /* svh = small viewport height: locked to the toolbar-VISIBLE state, never
     resizes as the address bar hides/shows during scroll. (dvh is the wrong
     fix here — it's the "dynamic" unit that DOES track the toolbar and was
     what caused the hero/mask-fade/CTA row to visibly jump on every scroll.)
     Old engines without svh support just keep the vh line above. */
  min-height: min(94svh, 880px);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: #fff;
  overflow: hidden;
  /* Fallback for old TV browsers (e.g. 5-yr-old Hisense VIDAA). Two layers:
     (1) a solid dark tone as the ultimate floor, and (2) the JPG poster painted
     straight on .hero with a baked-in dark overlay. This floor sits BEHIND the
     masked .hero-media layer, so when an old engine mis-clips that mask (or
     drops WebP/video), a real, legible photo still shows here instead of a flat
     colour block. The overlay is baked in because .hero-media's scrim is a child
     of the masked layer and vanishes with it — this floor carries its own scrim.
     Modern browsers never see this: .hero-media covers .hero completely (only
     the bottom fade zone reveals a faint, harmless darkened sliver). */
  background-color: #0d1f18;
  /* Two-line fallback, same pattern as the clamp() ones: the JPG line is what
     an old engine (no WebP decode, no image-set) keeps, and every modern
     browser overrides it with the WebP and never requests the JPG at all.
     That matters for performance, not just weight — hero-poster.jpg is 180 KB
     against 133 KB (desktop) / 39 KB (phone) for the WebP, and it was being
     fetched on every device purely as an old-TV safety net. */
  background-image:
    linear-gradient(rgba(8,14,11,.55), rgba(8,14,11,.55)),
    url("/assets/images/hero-poster.jpg");
  background-image:
    linear-gradient(rgba(8,14,11,.55), rgba(8,14,11,.55)),
    image-set(url("/assets/images/hero-poster.webp") type("image/webp"),
              url("/assets/images/hero-poster.jpg") type("image/jpeg"));
  background-size: cover;
  background-position: center;
}
/* Fades the hero into the real page background. This used to be a mask-image
   on .hero-media (the layer holding the live <video>) — masking a video
   element is exactly the pattern that triggers a known Chromium/WebKit
   compositor bug: resize the window mid-scroll and the browser can freeze a
   stale bitmap for part of the box (video in one region, an old frozen frame
   in the rest). Moving 100% of the fade into this separate, non-masked,
   always-opaque overlay avoids ever masking the video layer, so there is no
   layer for the compositor to get stuck on.
   Two-layer technique, not a single dark→pale gradient: a SOLID var(--bg)
   fill sits underneath at all times, and a dark veil sits on top whose alpha
   eases up then back down to fully transparent. Only one colour is ever
   interpolating (the veil's own alpha) — the pale base is a constant, not a
   second colour the gradient has to land on. A gradient that instead
   hard-swaps from a dark rgba stop straight to var(--bg) reads as a visible
   seam/line, because two different hues meet at a boundary instead of one
   colour smoothly dissolving over a base that was already there.
   height:100% is deliberate, not a leftover — on mobile .hero-rail becomes
   in-flow content (see the ≤1150px block below), so .hero's real height
   depends on stacked content, not just min-height, and can end up much
   taller than a percentage tuned against the desktop case ever accounted
   for. A shorter percentage here (62%, 80%, whatever) reliably left a whole
   extra stretch of raw, un-faded photo exposed BELOW where the veil ended —
   confirmed visually: a pale band appearing partway down, then the photo
   going dark again underneath it, because the veil's own 100% (its OWN
   height) landed short of .hero's actual bottom edge. height:100% removes
   that gap by construction — the veil's 100% stop always IS .hero's real
   bottom, at any content height — with the gradient stops themselves
   pushed down into roughly the bottom half so the top (headline/tagline)
   stays untouched exactly as before. */
.hero::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0; height: 100%;
  z-index: 2; pointer-events: none;
  /* Single gradient layer only — NOT a background-color + background-image
     pair. That two-layer version was a real bug, not just theory: a solid
     background-color sits under the WHOLE box permanently, and a
     "transparent" stop in the image layer only means the image itself has
     no paint there — it does NOT hide the opaque colour layer underneath,
     which shows through fully everywhere the image is transparent. That
     silently covered the entire top of hero (video included) in flat
     var(--bg), which is exactly why the video "disappeared". A single
     gradient has no such hidden opaque layer: transparent really is
     see-through, all the way down to hero-media's photo/video. The dark
     stops build up normally, then blend into var(--bg) over a wide final
     span (not a narrow jump) so the browser's own RGB interpolation carries
     it smoothly from dark green to the theme colour — no seam. */
  /* Dark theme (and the no-data-theme default) gets the same two-part treatment
     the light rule below documents in full, for the same two reasons:

     1. START EDGE — the old stops held transparent all the way to 56% and then
        ramped 0 → .52 in 18%. That rate spike is what the eye reads as a
        horizontal boundary partway down the photo, even though the gradient is
        mathematically smooth. Replaced with a slow-in curve: the veil now opens
        at 40% but stays near-invisible (.03, .07) for a long stretch, so no
        single row announces itself as "the fade starts here".
     2. THE BOUNDARY IS A SHAPE, NOT A LINE — the radial layer on top lifts the
        page colour higher in the middle than at the edges, so what used to be a
        straight rule across the viewport is now a wide soft curve.

     Dark needs no hue-bridging stops (the light rule's green-greys): --bg here
     is #080C0A and the veil is rgba(8,14,11) — the same colour, so the final
     blend has no luminance or hue gap to cross and cannot band.
     Two background IMAGES in one `background` is safe; the rule that must never
     be broken is background-COLOR + background-image (see the comment above). */
  /* TAIL — the remaining seam (reported 2026-08-15) was in the last 8%, not the
     start. The veil climbed to .93 at 93% and then finished in one short step,
     so whatever photo detail was still readable at .93 disappeared across a
     single row — the eye reads that as a horizontal edge even though every
     stop before it is smooth. Two changes: the ramp now reaches effectively
     opaque at 90% and then HOLDS flat var(--bg) for the last tenth, so the
     photo is already gone well before the box ends and nothing can pop; and
     the top of the ramp is stretched (more, smaller steps between .60 and 1)
     so the approach to opaque is gradual rather than a final lunge.
     The radial is also wider and taller (170% 78% vs 145% 62%) — a flatter,
     longer curve, which spreads the boundary over more vertical distance
     instead of concentrating it into one arc. */
  background:
    radial-gradient(170% 78% at 50% 116%,
      var(--bg) 34%,
      rgba(8,12,10,.50) 64%,
      rgba(8,12,10,0) 92%),
    linear-gradient(to bottom,
      transparent 0%, transparent 36%,
      rgba(8,14,11,.02) 42%,
      rgba(8,14,11,.05) 48%,
      rgba(8,14,11,.10) 54%,
      rgba(8,14,11,.17) 59%,
      rgba(8,14,11,.26) 64%,
      rgba(8,14,11,.37) 69%,
      rgba(8,14,11,.49) 73%,
      rgba(8,14,11,.61) 77%,
      rgba(8,14,11,.72) 81%,
      rgba(8,14,11,.82) 84%,
      rgba(8,14,11,.90) 87%,
      rgba(8,14,11,.96) 89%,
      var(--bg) 90%,
      var(--bg) 100%);
}
/* Light theme has the biggest luminance gap to cross — dark footage landing on
   a pale background. Two things used to make the transition read as EDGES
   rather than a fade, and both are fixed here:

   1. WHERE IT STARTS was visible because the veil's alpha ramped up fast
      (0 → .29 over 15% of the box). A steep enough ramp reads as a boundary
      even though it is technically a gradient. The stops below follow a
      slow-in curve instead: barely-there for a long stretch, so there is no
      point the eye can identify as "it begins here".
   2. WHERE IT ENDS was visible because the gradient jumped from a nearly
      opaque dark green-black straight to the pale mint page colour. Those are
      two very different hues AND luminances, so the browser interpolates
      through a muddy grey band — that was the hard line above "Recognition".
      Now it marches through explicit intermediate green-greys, so the hue
      travels continuously from dark to pale with no single crossing point.

   The radial layer on top is the "not a line, a shape" part: the page colour
   rises higher in the middle than at the sides, so the boundary is a wide soft
   curve rather than a horizontal rule across the viewport.

   Intermediate stops are literal rgba, not color-mix(): color-mix is dropped
   by the old-TV engine (see the old-TV notes) and this fade must not depend on
   it. They are hand-mixed from --bg (#E7F0E9) toward the veil colour — if that
   token ever changes, re-derive these four values with it.

   3. THE TAIL needs a flat opaque run, the same one dark theme got at v=74 and
      light did not (fixed 2026-08-15, reported on iPhone). The stops used to
      end `rgba(226,237,229,.97) 94%` → `var(--bg) 100%`, i.e. the veil was
      still ~3% translucent almost to the last row, so the dark photo beneath
      kept pulling it about 12 RGB levels below --bg and the page colour then
      arrived in ONE row. Measured off the device screenshot: rgb(220,230,222)
      immediately above the hero's bottom edge, rgb(232,239,232) immediately
      below — that step IS the white line. The ramp now reaches flat var(--bg)
      at 90% and HOLDS it for the last tenth, so the photo is gone well before
      the box ends and there is no edge left at the boundary.
      RULE (already learned once in dark theme): a fade must never finish
      exactly at 100% — the last visible change then lands on the last row,
      which is the single most conspicuous place to put it. */
[data-theme="light"] .hero::after {
  background:
    /* SHAPE, not a line. A wide flat radial (185% x 74%) is geometrically almost
       a straight edge — the arc is so shallow it reads as a horizontal rule.
       Narrower and taller gives real curvature: the page colour climbs high in
       the middle and stays low at the sides, so the boundary is a dome. A
       second, smaller lobe offset to the left breaks the symmetry — a perfect
       arc still reads as a drawn shape; an asymmetric one reads as light.
       Anchored below the box (at 122%/128% vertically), so only the top of each
       ellipse enters the hero. Rule of thumb: a bottom-anchored radial of
       height H at offset Y reaches up to (Y - H) of the box, which is what
       keeps these off the video. */
    /* Fade height cut ~40% (owner request 2026-08-16): more of the hero video
       stays visible. Radial lobe heights x0.6 (so each dome sits lower in the
       box) and the linear ramp start pushed 30% -> 52%, completion held at 85%
       so the stat-card seam is unchanged. Steeper than before by design. */
    radial-gradient(96% 63.5% at 50% 118%,
      var(--bg) 26%,
      rgba(231,240,233,.82) 46%,
      rgba(231,240,233,.56) 64%,
      rgba(231,240,233,.28) 82%,
      rgba(231,240,233,0) 98%),
    radial-gradient(62% 45.5% at 20% 126%,
      rgba(231,240,233,.66) 24%,
      rgba(231,240,233,.38) 54%,
      rgba(231,240,233,.14) 78%,
      rgba(231,240,233,0) 100%),
    radial-gradient(54% 35.9% at 84% 128%,
      rgba(231,240,233,.52) 26%,
      rgba(231,240,233,.26) 60%,
      rgba(231,240,233,0) 100%),
    linear-gradient(to bottom,
      transparent 0%, transparent 47%,
      rgba(8,14,11,.02) 50.5%,
      rgba(8,14,11,.04) 53.3%,
      rgba(8,14,11,.06) 55.3%,
      rgba(8,14,11,.09) 57.4%,
      rgba(8,14,11,.12) 59.5%,
      rgba(8,14,11,.16) 60.9%,
      rgba(30,45,38,.20) 62.2%,
      rgba(46,62,55,.25) 63.6%,
      rgba(60,77,68,.30) 65%,
      rgba(72,88,80,.35) 66.4%,
      rgba(88,105,96,.41) 67.8%,
      rgba(104,121,112,.47) 69.1%,
      rgba(118,137,127,.53) 70.5%,
      rgba(132,152,141,.59) 71.2%,
      rgba(146,166,155,.65) 72.6%,
      rgba(156,175,164,.70) 73.3%,
      rgba(168,186,175,.75) 74.7%,
      rgba(178,196,185,.79) 76%,
      rgba(188,205,194,.83) 77.4%,
      rgba(196,212,202,.87) 78.8%,
      rgba(204,220,210,.90) 79.5%,
      rgba(210,226,215,.93) 80.9%,
      rgba(218,231,222,.95) 81.6%,
      rgba(224,236,228,.97) 82.9%,
      rgba(228,238,230,.99) 83.6%,
      var(--bg) 85%,
      var(--bg) 100%);
}
/* Why light finishes at 80% while dark finishes at 90%: the light-theme stat
   card is a PALE card, so anything darker than the page showing beneath it
   reads as a band. Measured at 393x852 with marker rows in the live DOM, the
   card's bottom edge sits at ~82% of the hero's height. A veil that only
   completes at 90% therefore leaves ~46px of half-faded photo directly under
   the card — bounded by the card above and the page below, which is precisely
   the "line under the 10+ box". Finishing at 80% puts the completion just
   above the card's own edge, so the card sits on flat page colour and there is
   no darker strip left to bound.
   Dark theme does not have this problem and is left at 90%: its page colour IS
   near-black, so leftover photo there is not darker than what follows it and
   cannot read as a band. */
/* Phones, light theme: the veil must be finished ABOVE the stat card, not below
   it. Measured off the owner's iPhone screenshot (2026-08-15), the reported
   "white line under the 10+ box" is not a line at all — it is a ~60px DARK STRIP
   of leftover photo trapped between two pale surfaces:

     white stat card ......... luma 238
     one row below the card ... luma 211   <- 27-level drop, the hard edge
     the strip (60px tall) .... luma 211 -> 224
     the page ................. luma 236

   At phone scale a dark band that thin reads as a line. The stat card sits at
   roughly 59-96% of the hero's height here, so a veil that only reaches --bg at
   90% still leaves that 96-100% sliver of photo showing beneath the card. The
   stops above finish at 79% instead, which is above the card's lower half, so
   the card and everything under it sit on flat page colour and there is no
   strip left to read as an edge.
   Trade-off, stated plainly: this removes the thin photo sliver that used to
   show under the rail on phones. That sliver is the artifact — at 60px it can
   only read as a band, never as "photo". The generous photo area above the card
   is untouched.
   Paint only (background), so the theme toggle still cannot move the box.
   Dark theme is NOT touched: it was measured at the same viewport and already
   lands on --bg (8,12,10) well before the boundary and holds flat. */
/* The bike-rental "guided tour instead" strip reuses .hero-cta inside a narrow
   sidebar column, so above 680px its two buttons WRAP onto separate lines. The
   base `.hero-cta > * + * { margin-left: 14px }` is tuned for a single row: on a
   wrapped line it indents the second button 14px and contributes no vertical
   space at all, so the pair reads crooked and cramped — the exact asymmetry the
   ≤680 block already fixes for phones. Same treatment here, at every width, so
   the strip looks identical across resolutions.
   Adjacent-sibling margin, not flex `gap` — the old signage TV ignores gap. */
.direct-strip .hero-cta { flex-direction: column; align-items: stretch; }
.direct-strip .hero-cta > * + * { margin-left: 0; margin-top: 14px; }
.direct-strip .hero-cta .btn { width: 100%; justify-content: center; text-align: center; }

.hero-media {
  position: absolute; inset: 0;
  /* Own GPU compositor layer, kept for general resize stability even though
     the mask that used to sit on this element (and cause the stale-bitmap
     resize bug) is gone — see .hero::after above for the real fix. */
  transform: translateZ(0);
  /* Same fallback path: a JPG (decodes on every engine) painted straight on
     the media layer so the hero shows a real photo even when WebP/WebM fail.
     Modern browsers stack the <img>/<video> on top via z-index — no change. */
  background: #0d1f18 url("/assets/images/hero-poster.jpg") center/cover no-repeat;
  background-image: image-set(url("/assets/images/hero-poster.webp") type("image/webp"),
                              url("/assets/images/hero-poster.jpg") type("image/jpeg"));
}
/* Phones already preload hero-poster-800.webp (39 KB) for the <img>; pointing
   both photo floors at that same file means the whole hero costs ONE download
   on a phone instead of the 1600px asset plus a 180 KB JPG. Same URL as the
   preload, so it is a cache hit, not a second request. */
@media (max-width: 820px) {
  .hero { background-image:
    linear-gradient(rgba(8,14,11,.55), rgba(8,14,11,.55)),
    image-set(url("/assets/images/hero-poster-800.webp") type("image/webp"),
              url("/assets/images/hero-poster.jpg") type("image/jpeg")); }
  .hero-media { background-image:
    image-set(url("/assets/images/hero-poster-800.webp") type("image/webp"),
              url("/assets/images/hero-poster.jpg") type("image/jpeg")); }
}
/* The scrim has to thin out with the image, otherwise the fade zone reads as a
   grey haze sitting on top of the page colour. */
[data-theme="light"] .hero-media::after {
  background:
    radial-gradient(ellipse 58% 26% at 50% 30%, rgba(8,14,11,.66) 0%, rgba(8,14,11,.32) 60%, rgba(8,14,11,0) 100%),
    linear-gradient(180deg, rgba(8,14,11,.50) 0%, rgba(8,14,11,.30) 30%, rgba(8,14,11,0) 55%);
}
.hero-media img,
.hero-media video { width: 100%; height: 100%; object-fit: cover; }
/* Poster image sits underneath; video fades in over it once it can play */
.hero-media .hero-fallback { position: absolute; inset: 0; z-index: 0; }
.hero-media .hero-video { position: absolute; inset: 0; z-index: 1; opacity: 0; transition: opacity .6s ease; }
.hero-media .hero-video.ready { opacity: 1; }
/* Scrim: keeps the headline legible over any photo OR background video.
   Deliberately kept SMALL and high (tight ellipse around the headline, linear
   component fading out by 55%) — .hero::after now owns the entire lower-half
   fade into the page background on its own. This used to reach much further
   down (ellipse radius 45%, linear to 78-100%) tuned for a short desktop-style
   hero; on the mobile layout where .hero-rail stacks in-flow and .hero can run
   much taller, that reach stretched across nearly the whole box and directly
   overlapped .hero::after's own gradient — two different gradient SHAPES
   (elliptical vs linear) fighting for the same territory reads as visible
   rings/bands, not one smooth fade. Keeping this scrim tight and letting
   .hero::after own the rest removes the interference entirely. */
.hero-media::after {
  content: "";
  position: absolute; inset: 0;
  z-index: 2;               /* above the video, below the copy */
  background:
    radial-gradient(ellipse 58% 26% at 50% 31%, rgba(8,14,11,.70) 0%, rgba(8,14,11,.36) 60%, rgba(8,14,11,0) 100%),
    linear-gradient(180deg, rgba(8,14,11,.54) 0%, rgba(8,14,11,.32) 30%, rgba(8,14,11,0) 55%);
}

/* ===== Hidden sentence =====
   "You. Segway. Budapest." is a list. Take the full stops away and it is a
   sentence, with Segway acting as the verb. The dots shrink out on load and the
   words close up to show it.

   Animating font-size rather than opacity is what makes the collapse work: it
   takes each glyph's advance width to zero with it, so the following words
   slide left on their own and nothing has to be measured or hard-coded. */
.hs-dot { display: inline-block; }
.hs.hs-go .hs-dot { animation: hsDrop .62s cubic-bezier(.4,0,.2,1) forwards 1.5s; }
@keyframes hsDrop { to { font-size: 0; opacity: 0; } }
.hs.hs-done .hs-dot { font-size: 0; opacity: 0; }

/* Gold rule under the verb — the payoff line that says which word turned. */
/* inline-block, not plain inline: the gold underline is an absolutely-positioned
   ::after with left:0;right:0, and on an INLINE containing block that rect
   resolved to a non-paintable box at some widths (underline vanished on a 1280px
   external monitor while showing on the laptop). inline-block gives it a real
   box so the underline paints at every width and DPR. */
.hs-verb { position: relative; display: inline-block; }
.hs-verb::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -.13em;
  /* Whole-pixel height, not .055em: a sub-pixel-tall pseudo-element forced onto
     its own GPU layer by the transform below vanished on a 1x external monitor
     (BenQ) while rendering fine on Retina. A fixed 3px layer is safe on both. */
  height: 3px; border-radius: 2px;
  background: var(--gold);
  box-shadow: 0 1px 8px rgba(0,0,0,.55);
  transform: scaleX(0); transform-origin: left center;
}
.hs.hs-go .hs-verb::after { animation: hsDraw .8s cubic-bezier(.2,.8,.3,1) forwards 2.25s; }
.hs.hs-done .hs-verb::after { transform: scaleX(1); }
@keyframes hsDraw { to { transform: scaleX(1); } }

@media (prefers-reduced-motion: reduce) {
  .hs .hs-dot, .hs .hs-verb::after { animation: none !important; }
}

/* extra top padding keeps the copy clear of the overlaid header */
.hero-content { position: relative; z-index: 4; padding: calc(60px + var(--header-h)) 0 60px; max-width: 900px; }
.hero-content h1 {
  color: #fff;
  max-width: 16ch;
  margin: 0 auto .9rem;
  text-shadow: 0 2px 24px rgba(0,0,0,.55), 0 1px 3px rgba(0,0,0,.4);
}
.hero-tagline {
  font-size: 1.15rem;               /* fallback for old TV (<Chrome 79, no clamp()) */
  font-size: clamp(1rem, 2vw, 1.25rem);
  font-weight: 500;
  color: rgba(255,255,255,.92);
  letter-spacing: .01em;
  margin: 0 auto 34px;
  max-width: 34ch;
  text-shadow: 0 1px 12px rgba(0,0,0,.5);
}
.hero-cta { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; }
.hero-cta > * + * { margin-left: 14px; }
/* Entrance only — base rule above carries no opacity, so once the
   animation finishes (fill defaults to none, not forwards) the buttons
   just fall back to normal CSS opacity:1. Never pair persistent
   opacity:0 with only `forwards` here — see the v=73 stat-rail vanishing
   bug in CLAUDE.md for why that specific mistake bites. */
.hero-cta { animation: heroCtaIn .8s cubic-bezier(.16,1,.3,1) .5s backwards; }
@keyframes heroCtaIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .hero-cta { animation: none; } }
.hero .eyebrow {
  color: #fff;
  justify-content: center;
  text-shadow: 0 1px 10px rgba(0,0,0,.5);
}
.hero .eyebrow::before { background: var(--accent); }

/* ===== Credibility rail — compact glass sidebar inside the hero ===== */
.hero-rail {
  position: absolute;
  right: 22px;                      /* fallback for old TV (<Chrome 79, no max()) — keeps rail docked right, not overlapping */
  right: max(20px, 3vw);
  /* centred within the area below the overlaid header, not the whole hero */
  top: calc(50% + var(--header-h) / 2);
  transform: translateY(-50%);
  z-index: 4;
  display: flex;
  flex-direction: column;
  width: 190px;                     /* fallback for old TV (<Chrome 79, no clamp()) */
  width: clamp(160px, 15vw, 205px);
  padding: 22px 20px;
  border-radius: var(--radius);
  background: rgba(8,14,11,.40);
  backdrop-filter: blur(14px) saturate(150%);
  border: 1px solid rgba(255,255,255,.15);
  box-shadow: 0 10px 40px rgba(0,0,0,.35);
}
.hero-rail .credibility-item + .credibility-item { margin-top: 18px; } /* flex-gap fallback for old TV */
.hero-rail .credibility-item {
  align-items: flex-start;
  text-align: left;
  min-width: 0;
  /* Visible by DEFAULT, entrance supplied by `backwards` fill — never
     `opacity: 0` + `forwards`. With forwards, the visible state exists only
     for as long as the animation's fill survives; anything that restarts or
     replaces the animation (crossing the 1150px breakpoint while resizing,
     where .credibility-item flips to display:contents and back) drops the
     element to the declared 0 and the whole rail renders as an empty box.
     `backwards` inverts the dependency: 0 applies only during the delay, and
     the resting state is 1, so no interruption can hide the numbers. */
  opacity: 1;
  animation: railIn .7s cubic-bezier(.22,.9,.3,1) backwards;
}
.hero-rail .credibility-item:nth-child(1) { animation-delay: .35s; }
.hero-rail .credibility-item:nth-child(2) { animation-delay: .55s; }
.hero-rail .credibility-item:nth-child(3) { animation-delay: .75s; }
.hero-rail .credibility-item:nth-child(4) { animation-delay: .95s; }
/* display:flex + a fixed line-height-based min-height locks every .num to
   the identical box height regardless of what's inside it — plain digits
   ("10+", "7"), a wider comma-formatted count ("5,012+"), or a glyph with
   different natural metrics than digits ("5.0★", the star). Without this,
   line-height alone can still let one item's rendered box sit taller/lower
   than its neighbours depending on glyph metrics, so the four numbers read
   off a common line instead of a level one. */
.hero-rail .num {
  font-size: clamp(1.4rem, 1.7vw, 1.75rem);
  line-height: 1.05;
  min-height: 1.05em;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* white-space:nowrap is the actual fix for the alignment bug: without it, a
   longer label ("Years guiding", "Languages spoken") can wrap to 2 lines in
   a narrow flex item while shorter labels stay on 1 — that genuinely changes
   the item's height (confirmed via DevTools: one item measured 67px tall,
   another 49px), which is what breaks the shared row, not just a font-size
   or box-height quirk. One line, always, at every breakpoint. */
.hero-rail .label { font-size: 11.5px; color: rgba(255,255,255,.72); margin-top: 5px; white-space: nowrap; }
@keyframes railIn {
  from { opacity: 0; transform: translateX(18px); }
  to   { opacity: 1; transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-rail .credibility-item { opacity: 1; animation: none; }
}

.credibility-bar {
  display: flex; gap: 56px; flex-wrap: wrap;
  justify-content: center; align-items: flex-start;
}
.credibility-item { display: flex; flex-direction: column; align-items: center; text-align: center; min-width: 130px; }
.credibility-item .num {
  font-family: var(--font-head); font-size: clamp(2rem, 4vw, 2.7rem); font-weight: 700;
  letter-spacing: -0.035em;
  color: var(--text-primary);
  transition: text-shadow .3s ease;
  line-height: 1;
  /* digits share one advance width, so a counting number cannot shuffle
     the layout on every frame */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* Each figure gets its own hue — one green, one indigo, one persimmon, one gold.
   Restraint comes from the labels staying uniformly quiet underneath. */
.credibility-item:nth-child(1) .num { color: var(--brand-dark); }
.credibility-item:nth-child(2) .num { color: var(--indigo); }
.credibility-item:nth-child(3) .num { color: var(--gold); }
.credibility-item:nth-child(4) .num { color: var(--accent); }
[data-theme="dark"] .credibility-item:nth-child(1) .num { color: var(--brand); }
.credibility-item.glow .num { animation: glowPulse 3s ease-in-out infinite; }

/* The hero rail always sits on moving footage, so it cannot use the theme
   palette — those colours are picked for a page background and disappeared
   against a dark frame. Fixed bright values plus a shadow instead, so the
   numbers hold up over sunlit stone and night sky alike, in both themes. */
.hero-rail .credibility-item:nth-child(1) .num,
[data-theme="dark"] .hero-rail .credibility-item:nth-child(1) .num { color: #79DCB0; }
.hero-rail .credibility-item:nth-child(2) .num { color: #8CCBEE; }
.hero-rail .credibility-item:nth-child(3) .num { color: #FFC94D; }
.hero-rail .credibility-item:nth-child(4) .num { color: #FF9C7A; }
.hero-rail .num { text-shadow: 0 1px 10px rgba(0,0,0,.7), 0 0 3px rgba(0,0,0,.55); }
/* Needs .credibility-item in the selector: the generic `.credibility-item .label`
   rule below has equal specificity and, being later, was winning — so rail labels
   silently rendered in --text-muted (dim grey on the dark rail) instead of white. */
.hero-rail .credibility-item .label {
  color: #FFFFFF;
  font-weight: 600;
  text-shadow: 0 1px 8px rgba(0,0,0,.75), 0 0 3px rgba(0,0,0,.55);
  white-space: nowrap;
}
.credibility-item .label {
  font-size: 12.5px; color: var(--text-muted); margin-top: 8px;
  letter-spacing: .01em; font-weight: 500;
}
@keyframes glowPulse {
  0%, 100% { text-shadow: 0 0 0 rgba(223,170,85,0); }
  50% { text-shadow: 0 0 18px rgba(223,170,85,.6); }
}

/* ===== Trust / rating badges ===== */
.rating-badge {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--gold-tint); color: var(--gold-contrast);
  font-size: 12px; font-weight: 700;
  padding: 6px 12px; border-radius: var(--radius-pill);
}
[data-theme="dark"] .rating-badge { color: var(--gold); }
.rating-badge .stars { color: var(--gold); letter-spacing: 1px; }
.trust-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 18px 0; }
.trust-badge {
  display: flex; align-items: center; gap: 8px;
  background: var(--brand-tint); color: var(--brand-dark);
  font-size: 12.5px; font-weight: 600;
  padding: 9px 14px; border-radius: var(--radius-pill);
  border: 1px solid transparent;
}
[data-theme="dark"] .trust-badge { color: var(--brand); }
.trust-badge .ic { font-size: 16px; }

/* ===== Tour cards ===== */
/* min() guard: without it the 300px track floor overflows sub-340px phones */
.tour-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 28px; align-items: stretch; }
.tour-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; align-items: stretch; }
.tour-card {
  background: var(--surface);
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  transition: transform .2s ease, box-shadow .2s ease;
  height: 100%;
}
.tour-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }

/* ---- Rotating liquid-glass ring around a BUTTON ----
   .btn-halo wraps the button so the outer bloom can sit behind it
   without being painted over the button's own background. -------------- */
.featured-wrap { position: relative; display: flex; height: 100%; }
.featured-wrap > .tour-card { width: 100%; position: relative; }
.tour-card.featured { border-color: color-mix(in srgb, var(--accent) 40%, transparent); }

/* The ring must NOT rotate as a shape — only the colours travel around it.
   Animating a registered custom property (the gradient's start angle) keeps
   the pill outline perfectly still while the light sweeps around the edge. */
@property --ring-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.btn-halo { position: relative; display: block; margin-top: auto; }
.btn-halo::before {               /* soft bloom hugging the button */
  content: "";
  position: absolute; inset: -6px;
  border-radius: var(--radius-pill);
  background: conic-gradient(from var(--ring-angle),
    var(--gold), var(--accent), var(--indigo), var(--brand), var(--gold));
  filter: blur(10px);
  opacity: .65;
  animation: ringSweep 4s linear infinite;
  pointer-events: none;
  z-index: 0;
}
[data-theme="dark"] .btn-halo::before { opacity: .8; }
.btn-halo > .btn { position: relative; z-index: 1; }
.btn-halo > .btn::before {        /* crisp 2px ring locked to the button edge */
  content: "";
  position: absolute; inset: 0;
  border-radius: var(--radius-pill);
  padding: 2px;
  background: conic-gradient(from var(--ring-angle),
    var(--gold), var(--accent), var(--indigo), var(--brand), var(--gold));
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
          mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  animation: ringSweep 4s linear infinite;
  pointer-events: none;
  z-index: 2;
}
@keyframes ringSweep { to { --ring-angle: 360deg; } }
@media (prefers-reduced-motion: reduce) {
  .btn-halo::before, .btn-halo > .btn::before { animation: none; }
}
.tour-photo { display: block; position: relative; aspect-ratio: 5/4; overflow: hidden; flex: none; }
.tour-photo img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.tour-card:hover .tour-photo img { transform: scale(1.06); }
@media (prefers-reduced-motion: reduce) {
  .tour-photo img { transition: none; }
  .tour-card:hover .tour-photo img { transform: none; }
}
.badge-price {
  position: absolute; top: 14px; right: 14px;
  background: var(--gold); color: var(--gold-contrast);
  font-weight: 700; font-size: 14px;
  padding: 6px 14px; border-radius: var(--radius-pill);
}
/* Isolation effect: three identical gold pills and one that breaks the set.
   Same size and position — only the treatment differs, so the eye lands here
   first without the card shouting. */
.badge-price--pick {
  background: linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent) 76%, #7a1f00));
  color: #fff;
  border: 1.5px solid rgba(255,255,255,.55);
  box-shadow: 0 6px 18px -4px color-mix(in srgb, var(--accent) 70%, transparent),
              0 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent);
  animation: pickPulse 3.4s ease-in-out infinite;
}
@keyframes pickPulse {
  0%, 100% { box-shadow: 0 6px 18px -4px color-mix(in srgb, var(--accent) 70%, transparent),
                         0 0 0 4px color-mix(in srgb, var(--accent) 16%, transparent); }
  50%      { box-shadow: 0 6px 20px -4px color-mix(in srgb, var(--accent) 80%, transparent),
                         0 0 0 8px color-mix(in srgb, var(--accent) 8%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .badge-price--pick { animation: none; } }
/* the per-person unit anchors the number: "€59 / person" frames it as small */
.badge-price--pick .unit { font-weight: 600; font-size: 11px; opacity: .85; margin-left: 2px; }
.badge-popular {
  position: absolute; top: 14px; left: 14px;
  background: var(--accent); color: #fff;
  font-weight: 700; font-size: 12px;
  padding: 6px 12px; border-radius: var(--radius-pill);
  overflow: hidden;
}
/* Slow periodic shine sweep — a diagonal highlight crosses the pill every
   5s. Clipped by the pill's own overflow:hidden, so it never spills onto
   the photo. Pure paint, no layout impact. */
.badge-popular::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  background: linear-gradient(120deg, transparent 30%, rgba(255,255,255,.55) 50%, transparent 70%);
  background-repeat: no-repeat;
  background-size: 220% 100%;
  background-position: 200% 0;
  animation: badgeShine 5s ease-in-out infinite;
}
@keyframes badgeShine {
  0%, 55% { background-position: 200% 0; }
  80%, 100% { background-position: -60% 0; }
}
@media (prefers-reduced-motion: reduce) { .badge-popular::after { animation: none; display: none; } }
/* Rental is a different product to a guided tour — signal that quietly */
.badge-rental { background: var(--indigo); color: #fff; }
.tour-card--rental { border-style: dashed; border-color: color-mix(in srgb, var(--indigo) 45%, transparent); }
.tour-card--rental .tour-duration { color: var(--indigo); }
.badge-rating-card {
  position: absolute; bottom: 14px; left: 14px;
  background: rgba(22,36,30,.72); backdrop-filter: blur(4px);
  color: #fff; font-weight: 700; font-size: 12px;
  padding: 6px 12px; border-radius: var(--radius-pill);
  display: flex; align-items: center; gap: 5px;
}
.badge-rating-card .stars { color: var(--gold); }
.tour-body { padding: 22px 20px 20px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.tour-duration { color: var(--brand-dark); font-weight: 700; font-size: 13px; letter-spacing: .03em; }
[data-theme="dark"] .tour-duration { color: var(--brand); }
.tour-body p { font-size: 14px; margin: 0; flex: 1; }
.tag-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 8px; }
/* Pills carry meaning through colour, and use a gradient fill + gradient-lit
   border rather than one flat tone (glassmorphism depth-as-information). */
.tag-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600;
  color: var(--text-secondary);
  background: linear-gradient(140deg, color-mix(in srgb, var(--surface-alt) 92%, #fff), var(--surface-alt));
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  padding: 6px 13px; border-radius: var(--radius-pill);
  backdrop-filter: blur(6px);
}
/* 11px was fine for an emoji glyph but muddies a stroke icon — 13.5px keeps
   the linework legible without making the pill any taller. */
.tag-pill .ic { font-size: 13.5px; opacity: .9; display: inline-flex; align-items: center; }
.tag-pill--lang {
  color: var(--indigo);
  background: linear-gradient(140deg, color-mix(in srgb, var(--indigo-tint) 70%, #fff), var(--indigo-tint));
  border-color: color-mix(in srgb, var(--indigo) 26%, transparent);
}
.tag-pill--type {
  color: var(--brand-dark);
  background: linear-gradient(140deg, color-mix(in srgb, var(--brand-tint) 70%, #fff), var(--brand-tint));
  border-color: color-mix(in srgb, var(--brand) 26%, transparent);
}
[data-theme="dark"] .tag-pill--type { color: var(--brand); }
.tag-pill--rating {
  color: var(--gold-contrast);
  background: linear-gradient(140deg, color-mix(in srgb, var(--gold-tint) 70%, #fff), var(--gold-tint));
  border-color: color-mix(in srgb, var(--gold) 32%, transparent);
}
[data-theme="dark"] .tag-pill--rating { color: var(--gold); }
.tag-pill--pace {
  color: var(--accent);
  background: linear-gradient(140deg, color-mix(in srgb, var(--accent-tint) 70%, #fff), var(--accent-tint));
  border-color: color-mix(in srgb, var(--accent) 26%, transparent);
}
.tour-body > a.btn { margin-top: auto; }
.tour-grid-4 h3 { font-size: 1.35rem; }
.tour-grid-4 .tour-body { padding: 24px 22px 22px; gap: 11px; }
.tour-grid-4 .tour-body p { font-size: 15px; }
.tour-grid-4 .badge-price { font-size: 15px; padding: 7px 16px; }
.tour-grid-4 .badge-popular { font-size: 12.5px; padding: 7px 14px; }
/* .badge-popular (top-left) and .badge-price (top-right) are two
   independent absolutely-positioned pills with no collision awareness —
   when a card has both AND the price pill is the wide --pick variant
   ("from €49 / person"), their combined width can exceed the narrower
   4-up card width and they overlap instead of leaving a gap between them.
   Capping each to half the card width (minus the corner insets) makes
   that mathematically impossible: the two can now touch at the middle at
   worst, never overlap. Long text wraps onto a second line instead of
   colliding — an ellipsis ("from €49...") read as broken/cut-off text,
   wrapping reads as an intentional two-line pill. */
.tour-grid-4 .badge-popular,
.tour-grid-4 .badge-price {
  max-width: calc(50% - 20px);
  white-space: normal;
  line-height: 1.25;
  text-align: center;
}

/* =====================================================================
   Tour matcher quiz
   ===================================================================== */
.matcher {
  max-width: 780px; margin: 0 auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 38px 36px 34px;
  position: relative;
  overflow: hidden;
}
.matcher-progress { height: 4px; background: var(--surface-alt); border-radius: 999px; margin-bottom: 26px; overflow: hidden; }
.matcher-progress span {
  display: block; height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--brand), var(--gold), var(--accent));
  border-radius: 999px;
  transition: width .45s cubic-bezier(.22,.9,.3,1);
}
.matcher-step { display: none; animation: qFade .4s ease; }
.matcher-step.active { display: block; }
@keyframes qFade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.matcher-count { font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 10px; display: block; }
.matcher h3 { font-size: clamp(1.3rem, 2.4vw, 1.75rem); margin-bottom: 6px; }
.matcher .q-hint { font-size: 13.5px; color: var(--text-muted); margin-bottom: 22px; }
.opt-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 26px; }
.opt {
  display: flex; align-items: center; gap: 12px;
  padding: 15px 17px;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  cursor: pointer;
  font-size: 14.5px; font-weight: 600;
  text-align: left;
  transition: border-color .16s, background .16s, transform .12s;
  color: var(--text-primary);
  font-family: var(--font-body);
}
.opt:hover { border-color: color-mix(in srgb, var(--brand) 55%, transparent); transform: translateY(-1px); }
.opt .emo { font-size: 20px; flex: none; }
.opt.selected { border-color: var(--brand); background: var(--brand-tint); }
.opt.selected::after { content: "✓"; margin-left: auto; color: var(--brand-dark); font-weight: 800; }
[data-theme="dark"] .opt.selected::after { color: var(--brand); }
.matcher-nav { display: flex; gap: 12px; align-items: center; }
.matcher-nav .spacer { flex: 1; }

/* ---- Result ---- */
.matcher-result { display: none; }
.matcher-result.active { display: block; animation: qFade .5s ease; }
.result-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--brand-dark); }
[data-theme="dark"] .result-eyebrow { color: var(--brand); }
.result-card {
  display: flex; gap: 22px; align-items: center;
  background: linear-gradient(135deg, var(--brand-tint), color-mix(in srgb, var(--gold-tint) 60%, transparent));
  border: 1px solid color-mix(in srgb, var(--brand) 28%, transparent);
  border-radius: var(--radius); padding: 22px; margin: 18px 0 20px;
}
.result-card img { width: 132px; height: 100px; object-fit: cover; border-radius: var(--radius-sm); flex: none; }
.result-card h4 { font-family: var(--font-head); font-size: 1.4rem; margin: 0 0 6px; }
.result-meta { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.result-why { font-size: 14.5px; color: var(--text-secondary); margin-bottom: 20px; line-height: 1.7; }
.result-why b { color: var(--text-primary); }
/* Runner-up gets its own real card so it reads as a genuine second option */
.result-alt-head {
  display: flex; align-items: center; gap: 10px;
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--indigo); margin: 26px 0 12px;
}
.result-alt-head::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.result-alt {
  display: flex; gap: 18px; align-items: center;
  background: var(--surface);
  border: 1.5px dashed color-mix(in srgb, var(--indigo) 45%, transparent);
  border-radius: var(--radius);
  padding: 18px; margin-bottom: 22px;
  transition: border-color .18s, transform .18s, box-shadow .18s;
}
.result-alt:hover { border-color: var(--indigo); transform: translateY(-2px); box-shadow: var(--shadow); }
.result-alt img { width: 104px; height: 78px; object-fit: cover; border-radius: var(--radius-sm); flex: none; }
.result-alt-body { flex: 1; min-width: 0; }
.result-alt-body h5 {
  font-family: var(--font-head); font-size: 1.12rem; font-weight: 700;
  margin: 0 0 5px; color: var(--text-primary);
}
.result-alt-body p { font-size: 13.5px; margin: 0 0 8px; color: var(--text-secondary); }
.result-alt .result-meta { margin-bottom: 0; }
.result-alt .btn { flex: none; }
@media (max-width: 680px) {
  .result-alt { flex-direction: column; align-items: stretch; }
  .result-alt img { width: 100%; height: 120px; }
  .result-alt .btn { width: 100%; }
}
.result-actions { display: flex; gap: 12px; flex-wrap: wrap; }
.matcher-socialproof { font-size: 12.5px; color: var(--text-muted); margin-top: 18px; text-align: center; }

/* Confetti canvas */
#confetti-canvas { position: fixed; inset: 0; pointer-events: none; z-index: 9999; }

@media (max-width: 680px) {
  .matcher { padding: 26px 20px 24px; }
  .opt-grid { grid-template-columns: 1fr; }
  .result-card { flex-direction: column; align-items: flex-start; }
  .result-card img { width: 100%; height: 150px; }
  .result-actions .btn { width: 100%; }
}

/* =====================================================================
   Awards strip
   ===================================================================== */
.awards-strip {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: stretch;
  gap: 16px;
}
.award {
  display: flex; align-items: center; gap: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 22px;
  min-width: 250px; flex: 0 1 300px;
  box-shadow: var(--shadow);
}
.award .medal {
  width: 46px; height: 46px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
  background: var(--gold-tint); color: var(--gold-contrast);
}
[data-theme="dark"] .award .medal { color: var(--gold); }
.award .a-body { min-width: 0; }
.award b { display: block; font-family: var(--font-head); font-size: 1.02rem; line-height: 1.25; }
.award span { display: block; font-size: 12.5px; color: var(--text-muted); margin-top: 3px; }
.award--rank .medal { background: var(--brand-tint); color: var(--brand-dark); }
[data-theme="dark"] .award--rank .medal { color: var(--brand); }
.award--reviews .medal { background: var(--accent-tint); color: var(--accent); }
.awards-note { text-align: center; font-size: 12px; color: var(--text-muted); margin-top: 16px; }

/* --- Cold-foil sweep -------------------------------------------------
   A specular band travels across each award once, the way light catches
   foil stamping on a physical certificate. soft-light keeps it a highlight
   rather than a white wash, so it works in both themes. Cards also stamp
   in with a small overshoot, staggered left to right. ------------------ */
.award { position: relative; overflow: hidden; opacity: 0; transform: translateY(14px) scale(.97); }
.awards-strip.lit .award { animation: awardStamp .8s cubic-bezier(.2,.9,.25,1.12) forwards; }
.awards-strip.lit .award:nth-child(1) { animation-delay: .08s; }
.awards-strip.lit .award:nth-child(2) { animation-delay: .26s; }
.awards-strip.lit .award:nth-child(3) { animation-delay: .44s; }
@keyframes awardStamp {
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.award::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;          /* square corners used to poke out of the card */
  pointer-events: none;
  /* A narrow specular streak, not a wash. Alpha stays low so the blend lifts
     the surface slightly instead of painting a pale block over it. */
  background: linear-gradient(105deg,
    rgba(255,255,255,0)   43%,
    rgba(255,255,255,.20) 48%,
    rgba(255,255,255,.42) 50%,
    rgba(255,255,255,.20) 52%,
    rgba(255,255,255,0)   57%);
  mix-blend-mode: soft-light;
  transform: translateX(-140%);
  will-change: transform;
}
/* On the near-black dark surface soft-light reads as grey haze. screen only
   ever adds light, so the streak stays a highlight and the card stays black. */
[data-theme="dark"] .award::after {
  mix-blend-mode: screen;
  background: linear-gradient(105deg,
    rgba(255,255,255,0)   43%,
    rgba(255,255,255,.06) 48%,
    rgba(255,255,255,.14) 50%,
    rgba(255,255,255,.06) 52%,
    rgba(255,255,255,0)   57%);
}
.awards-strip.lit .award::after { animation: foilSweep 2.8s cubic-bezier(.4,0,.35,1) forwards; }
.awards-strip.lit .award:nth-child(1)::after { animation-delay: .5s; }
.awards-strip.lit .award:nth-child(2)::after { animation-delay: .78s; }
.awards-strip.lit .award:nth-child(3)::after { animation-delay: 1.06s; }
@keyframes foilSweep {
  from { transform: translateX(-140%); }
  to   { transform: translateX(140%); }
}

/* the rank medal keeps a slow breathing halo after the sweep lands */
.awards-strip.lit .award--rank .medal { animation: rankHalo 3.6s ease-in-out 3.2s infinite; }
@keyframes rankHalo {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 40%, transparent); }
  50%      { box-shadow: 0 0 0 7px color-mix(in srgb, var(--brand) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .award { opacity: 1; transform: none; }
  .awards-strip.lit .award,
  .awards-strip.lit .award::after,
  .awards-strip.lit .award--rank .medal { animation: none; }
}

/* =====================================================================
   Legal notice / imprint block
   ===================================================================== */
.legal-block {
  background: var(--surface-alt);
  border-radius: var(--radius);
  padding: 26px 28px;
}
.legal-block h3 { font-size: 1.05rem; margin-bottom: 14px; }
.legal-grid { display: grid; grid-template-columns: auto 1fr; gap: 8px 22px; font-size: 13.5px; }
.legal-grid dt { color: var(--text-muted); }
.legal-grid dd { margin: 0; color: var(--text-primary); font-weight: 500; }

/* =====================================================================
   Serpentine itinerary — nodes laid out in rows that alternate direction,
   joined by a curved SVG path. Positions are computed in main.js because
   the column count changes with width.
   ===================================================================== */
.snake { position: relative; margin: 8px 0 6px; }
.snake-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; }
.snake-path { fill: none; stroke: url(#snakeGrad); stroke-width: 3; stroke-linecap: round; opacity: .9; }
.snake-node {
  position: absolute; z-index: 1;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; padding: 0 6px;
}
.snake-dot {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--surface); border: 3px solid var(--brand);
  color: var(--brand-dark);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-head); font-weight: 700; font-size: 15px;
  box-shadow: var(--shadow);
  transition: transform .18s ease;
}
[data-theme="dark"] .snake-dot { color: var(--brand); }
.snake-node:hover .snake-dot { transform: scale(1.12); }
.snake-node--main .snake-dot { background: var(--accent); border-color: var(--accent); color: #fff; }
.snake-node--edge .snake-dot { background: var(--brand); border-color: var(--brand); color: var(--brand-contrast); }
.snake-name {
  font-size: 12.5px; font-weight: 700; line-height: 1.3;
  margin-top: 9px; color: var(--text-primary);
  max-width: 130px;
}
.snake-min { font-size: 11px; color: var(--text-muted); margin-top: 3px; }
.snake-legend { display: flex; gap: 20px; justify-content: center; font-size: 12px; color: var(--text-muted); margin-top: 6px; }
.snake-legend i { font-style: normal; display: inline-flex; align-items: center; gap: 7px; }
.snake-legend .k { width: 12px; height: 12px; border-radius: 50%; display: inline-block; }
.snake-legend .k-main { background: var(--accent); }
.snake-legend .k-other { background: var(--surface); border: 2.5px solid var(--brand); }

/* =====================================================================
   Collapsible tour info blocks
   ===================================================================== */
.info-block {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  margin-bottom: 12px;
  overflow: hidden;
}
.info-block > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 12px;
  padding: 18px 22px;
  font-family: var(--font-head); font-weight: 700; font-size: 1.05rem;
  transition: background .15s;
}
.info-block > summary::-webkit-details-marker { display: none; }
.info-block > summary:hover { background: var(--surface-alt); }
.info-block > summary .chev {
  margin-left: auto; flex: none;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--surface-alt); color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; transition: transform .22s ease;
}
.info-block[open] > summary .chev { transform: rotate(180deg); }
.info-block > summary .lead-ic { font-size: 18px; flex: none; }
.info-block .block-body { padding: 0 22px 22px; }
.info-block .block-body p:last-child { margin-bottom: 0; }
.tick-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 11px; }
.tick-list li { display: flex; gap: 11px; align-items: flex-start; font-size: 14.5px; color: var(--text-secondary); }
.tick-list .ic { flex: none; width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; margin-top: 1px; }
.tick-yes .ic { background: var(--brand-tint); color: var(--brand-dark); }
[data-theme="dark"] .tick-yes .ic { color: var(--brand); }
.tick-no .ic { background: var(--surface-alt); color: var(--text-muted); }
.tick-warn .ic { background: var(--gold-tint); color: var(--gold-contrast); }
[data-theme="dark"] .tick-warn .ic { color: var(--gold); }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; }
@media (max-width: 700px) { .two-col { grid-template-columns: 1fr; gap: 18px; } }
.block-sub { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 12px; }

/* Review speech bubble */
.review-bubble {
  position: relative;
  background: linear-gradient(140deg, var(--brand-tint), color-mix(in srgb, var(--gold-tint) 55%, transparent));
  border: 1px solid color-mix(in srgb, var(--brand) 22%, transparent);
  border-radius: var(--radius);
  padding: 22px 24px;
  margin-bottom: 26px;
}
.review-bubble::after {
  content: ""; position: absolute; left: 34px; bottom: -11px;
  width: 20px; height: 20px; transform: rotate(45deg);
  background: color-mix(in srgb, var(--gold-tint) 55%, var(--brand-tint));
  border-right: 1px solid color-mix(in srgb, var(--brand) 22%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--brand) 22%, transparent);
}
.review-bubble .stars { color: var(--gold); letter-spacing: 2px; font-size: 14px; }
.review-bubble q { display: block; font-size: 15.5px; line-height: 1.65; color: var(--text-primary); margin: 10px 0 14px; quotes: "\201C" "\201D"; }
.review-who { display: flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--text-secondary); }
.review-who .av {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: var(--accent); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 13px;
}
.review-who b { color: var(--text-primary); }
.source-note { font-size: 11.5px; color: var(--text-muted); margin-top: 14px; }

/* =====================================================================
   Itinerary timeline (legacy vertical list, kept for narrow screens)
   ===================================================================== */
.itinerary-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; align-items: start; }
.itinerary {
  list-style: none; margin: 0; padding: 0;
  position: relative;
  max-height: 520px; overflow-y: auto; padding-right: 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.itinerary::-webkit-scrollbar { width: 6px; }
.itinerary::-webkit-scrollbar-track { background: transparent; }
.itinerary::-webkit-scrollbar-thumb {
  background: var(--border); border-radius: 999px;
}
.itinerary::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
.itinerary::before {
  content: ""; position: absolute; left: 13px; top: 8px; bottom: 8px;
  width: 3px; border-radius: 3px;
  background: linear-gradient(180deg, var(--accent), var(--brand));
}
.itin-stop {
  position: relative; padding: 0 0 20px 42px;
  display: flex; align-items: baseline; gap: 10px;
}
.itin-stop:last-child { padding-bottom: 0; }
.itin-min {
  font-size: 11.5px; font-weight: 600; color: var(--text-muted);
  background: var(--surface-alt); border-radius: var(--radius-pill);
  padding: 3px 9px; flex: none;
}
.itin-dot {
  position: absolute; left: 4px; top: 2px;
  width: 21px; height: 21px; border-radius: 50%;
  background: var(--surface); border: 3px solid var(--brand);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 800; color: var(--brand-dark);
  z-index: 1;
}
[data-theme="dark"] .itin-dot { color: var(--brand); }
.itin-stop--main .itin-dot { background: var(--accent); border-color: var(--accent); color: #fff; }
.itin-stop b { font-size: 14.5px; line-height: 1.35; }
.itin-legend { display: flex; gap: 18px; font-size: 12px; color: var(--text-muted); margin-top: 14px; }
.itin-legend i { font-style: normal; display: inline-flex; align-items: center; gap: 6px; }
.itin-legend .k { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
.itin-legend .k-main { background: var(--accent); }
.itin-legend .k-other { background: var(--surface); border: 2px solid var(--brand); }
#route-map, .route-map {
  height: 520px; border-radius: var(--radius);
  border: 1px solid var(--border); overflow: hidden; z-index: 0;
}
.map-note { font-size: 11.5px; color: var(--text-muted); margin-top: 10px; }

/* Dark map. The Google Maps embed cannot be styled — no dark parameter, and the
   JS styling API does not reach an iframe. Inverting luminosity and rotating the
   hue back by 180deg gets a proper dark map: land goes dark, labels go light,
   and water and parks keep roughly their own colours instead of turning pink. */
[data-theme="dark"] .map-frame iframe {
  filter: invert(1) hue-rotate(180deg) brightness(.92) contrast(.92) saturate(.85);
}
[data-theme="dark"] .map-frame { border-color: color-mix(in srgb, var(--border) 70%, transparent); }
.leaflet-container { background: var(--surface-alt) !important; font-family: var(--font-body) !important; }
@media (max-width: 960px) {
  .itinerary-grid { grid-template-columns: 1fr; }
  #route-map, .route-map { height: 380px; }
  .itinerary { max-height: none; }
}

/* =====================================================================
   Business page (/for-groups/) — REBUILT FROM SCRATCH, second design.
   Deliberately punk / rock-and-roll this time: a gig-poster hero (Bebas
   Neue, huge condensed caps, a diagonal hazard-stripe band, a ticket-stub
   eyebrow), a "backstage laminate" list instead of hairline rows, a vinyl-
   record tour strip instead of a photo grid, a lightning-bolt 3-step
   instead of a fill-line timeline, and a spotlight-lit form shell instead
   of a plain container. Still on this site's own tokens (--accent as the
   hot colour, never a literal neon punk palette) — loud through shape,
   rotation and contrast, not through inventing new colours.
   Nothing here reuses the previous pass: no Anton, no inline-balancing
   Segway icon, no fill-line timeline, no hairline numbered rows, no photo-
   grid tour strip. Buttons/inputs/accordion/pill-options/segmented are
   shared site-wide components — only decorative shells around them are
   new; their own rules are untouched. */

/* ---- Hero: gig poster ---- */
.rock-hero { padding-top: 44px; padding-bottom: 44px; position: relative; overflow: hidden; }
.rock-hero-stripes {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: repeating-linear-gradient(-45deg, var(--accent) 0 26px, transparent 26px 52px);
  opacity: .06;
  mask-image: linear-gradient(180deg, #000, transparent 85%);
}
.rock-hero-inner { position: relative; z-index: 1; max-width: 800px; }
.rock-stub {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-body); font-size: 12px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-primary);
  border: 1.5px dashed var(--text-primary); border-radius: 999px;
  padding: 6px 14px 6px 6px; margin-bottom: 20px;
}
.rock-stub b {
  background: var(--accent); color: #fff; border-radius: 999px;
  padding: 3px 10px; font-weight: 700;
}
/* Bebas Neue: loaded only on this page, only for the hero headline —
   condensed, all-caps, the loudest type on the site. */
.rock-h1 {
  font-family: 'Bebas Neue', var(--font-head);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .01em;
  font-size: clamp(3.2rem, 8.5vw, 6.2rem);
  line-height: .88;
  margin: 0 0 20px;
}
.rock-h1 em { font-style: normal; color: var(--accent); }
.rock-lead { font-size: 1.08rem; line-height: 1.6; color: var(--text-secondary); max-width: 50ch; margin: 0 0 26px; }

/* Ticker — a hazard-stripe strip, not a plain hairline marquee. */
.rock-ticker {
  position: relative; z-index: 1;
  overflow: hidden; white-space: nowrap;
  margin-top: 30px; border-radius: 6px;
  background: var(--text-primary);
  padding: 12px 0;
}
.rock-ticker-track { display: inline-flex; gap: 22px; animation: rockTicker 24s linear infinite; }
.rock-ticker-track span {
  font-family: var(--font-head); font-size: .85rem; font-weight: 700;
  letter-spacing: .03em; color: var(--bg);
}
.rock-ticker-track span.dot { color: var(--accent); font-weight: 900; }
@keyframes rockTicker { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .rock-ticker-track { animation: none; } }

/* ---- "The pass includes" — backstage laminates, staggered zigzag ---- */
.rock-passes { display: flex; flex-direction: column; gap: 18px; }
.rock-pass {
  position: relative;
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 18px;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 12px;
  padding: 16px 22px 16px 16px;
  max-width: 620px;
  opacity: 0; transform: translateX(-24px);
  transition: opacity .5s ease, transform .5s ease;
  transition-delay: calc(var(--i, 0) * 90ms);
}
.rock-passes.is-in .rock-pass { opacity: 1; transform: none; }
.rock-pass:nth-child(even) { align-self: flex-end; transform: translateX(24px); }
.rock-passes.is-in .rock-pass:nth-child(even) { transform: none; }
/* lanyard punch-hole, top-left, half off the card like a real laminate */
.rock-pass::before {
  content: ""; position: absolute; top: -9px; left: 22px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--bg); border: 1.5px solid var(--border);
}
.rock-pass-num {
  font-family: 'Bebas Neue', var(--font-head); font-size: 2.1rem; line-height: 1;
  color: var(--stripe, var(--accent));
  width: 44px; text-align: center;
}
.rock-pass:nth-child(6n+1) { --stripe: var(--accent); }
.rock-pass:nth-child(6n+2) { --stripe: var(--brand-dark); }
[data-theme="dark"] .rock-pass:nth-child(6n+2) { --stripe: var(--brand); }
.rock-pass:nth-child(6n+3) { --stripe: var(--gold-contrast); }
[data-theme="dark"] .rock-pass:nth-child(6n+3) { --stripe: var(--gold); }
.rock-pass:nth-child(6n+4) { --stripe: var(--indigo); }
.rock-pass:nth-child(6n+5) { --stripe: var(--accent); }
.rock-pass:nth-child(6n+6) { --stripe: var(--brand-dark); }
[data-theme="dark"] .rock-pass:nth-child(6n+6) { --stripe: var(--brand); }
.rock-pass-body h3 { margin: 0 0 2px; font-size: 1rem; }
.rock-pass-body p { margin: 0; font-size: 13px; line-height: 1.45; color: var(--text-secondary); }
.rock-pass-ic { width: 20px; height: 20px; color: var(--stripe, var(--accent)); }
/* left edge stripe, the laminate's colour tab */
.rock-pass { border-left: 5px solid var(--stripe, var(--accent)); }
@media (max-width: 720px) {
  .rock-pass, .rock-pass:nth-child(even) { max-width: none; align-self: stretch; }
}
@media (max-width: 480px) {
  .rock-pass { grid-template-columns: auto 1fr; padding: 14px 16px; }
  .rock-pass-ic { display: none; }
}

/* ---- Popular tours — vinyl records, not photo cards ---- */
.rock-tours { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.rock-tour { display: flex; flex-direction: column; align-items: center; text-align: center; color: inherit; text-decoration: none; }
.rock-tour-disc {
  position: relative; width: 100%; max-width: 220px; aspect-ratio: 1;
  border-radius: 50%; overflow: hidden;
  /* Fixed ink tone, not var(--text-primary) — vinyl is black in both
     themes; the token flips near-white in dark mode and the record loses
     the point. Same "deliberate fixed tone" move the punk bento used. */
  background: #14100D;
  box-shadow: 0 14px 30px -16px rgba(0,0,0,.45);
  transition: transform .6s cubic-bezier(.2,.7,.3,1);
}
.rock-tour:hover .rock-tour-disc { transform: rotate(28deg); }
.rock-tour-disc img { position: absolute; inset: 10%; width: 80%; height: 80%; border-radius: 50%; object-fit: cover; }
.rock-tour-disc::after {
  /* record grooves */
  content: ""; position: absolute; inset: 4%; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 0 0 14px rgba(255,255,255,.06), 0 0 0 28px rgba(255,255,255,.06);
}
.rock-tour-disc::before {
  /* centre spindle */
  content: ""; position: absolute; top: 50%; left: 50%; z-index: 2;
  width: 14px; height: 14px; margin: -7px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--text-primary);
}
.rock-tour-track { margin-top: 16px; font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
.rock-tour h3 { margin: 4px 0 6px; font-size: 1.05rem; }
.rock-tour-time { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.rock-tour p { margin: 6px 0 0; font-size: 13px; line-height: 1.45; color: var(--text-secondary); max-width: 30ch; }
@media (max-width: 780px) { .rock-tours { grid-template-columns: 1fr; gap: 40px; } }

/* ---- How it works — three big steps, a lightning-bolt connector ---- */
.rock-steps-wrap { position: relative; }
.rock-bolt { position: absolute; top: 32px; left: 0; width: 100%; height: 60px; z-index: 0; pointer-events: none; }
.rock-bolt path {
  fill: none; stroke: var(--accent); stroke-width: 2; stroke-dasharray: 6 6;
  stroke-dashoffset: 400; transition: stroke-dashoffset 1.1s cubic-bezier(.3,.7,.2,1);
}
.rock-steps-wrap.is-in .rock-bolt path { stroke-dashoffset: 0; }
.rock-steps { position: relative; z-index: 1; display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.rock-step { text-align: center; }
.rock-step-num {
  display: flex; align-items: center; justify-content: center; margin: 0 auto 16px;
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--surface); border: 2.5px solid var(--text-primary);
  font-family: 'Bebas Neue', var(--font-head); font-size: 1.8rem; color: var(--text-primary);
  transform: scale(.5); opacity: 0;
  transition: transform .4s cubic-bezier(.34,1.56,.64,1), opacity .3s, background .3s, border-color .3s, color .3s;
}
.rock-steps-wrap.is-in .rock-step:nth-child(1) .rock-step-num { transition-delay: .1s; }
.rock-steps-wrap.is-in .rock-step:nth-child(2) .rock-step-num { transition-delay: .5s; }
.rock-steps-wrap.is-in .rock-step:nth-child(3) .rock-step-num { transition-delay: .95s; }
.rock-steps-wrap.is-in .rock-step-num { transform: scale(1); opacity: 1; background: var(--accent); border-color: var(--accent); color: #fff; }
.rock-step b { display: block; font-size: 1.05rem; margin-bottom: 6px; }
.rock-step p { font-size: 13.5px; margin: 0; color: var(--text-secondary); max-width: 32ch; margin-inline: auto; }
@media (max-width: 780px) {
  .rock-steps { grid-template-columns: 1fr; gap: 34px; }
  .rock-bolt { display: none; }
}
@media (max-width: 680px), (prefers-reduced-motion: reduce) {
  .rock-pass, .rock-step-num, .rock-bolt path { transition: none; }
  .rock-pass { opacity: 1; transform: none; }
  .rock-step-num { transform: scale(1); opacity: 1; background: var(--accent); border-color: var(--accent); color: #fff; }
  .rock-bolt path { stroke-dashoffset: 0; }
  .rock-ticker-track { animation: none; }
}

/* ---- Enquiry — spotlight shell around the UNCHANGED shared form ---- */
.rock-form-shell {
  position: relative; overflow: hidden;
  border-radius: 20px; border: 1.5px solid var(--border);
  padding: 40px 36px;
  background:
    radial-gradient(ellipse 70% 60% at 50% 0%, color-mix(in srgb, var(--accent) 12%, transparent), transparent),
    var(--surface);
}
.rock-form-shell::before, .rock-form-shell::after {
  /* gaffer-tape corner marks, top corners only */
  content: ""; position: absolute; top: 14px; width: 46px; height: 16px;
  background: color-mix(in srgb, var(--text-primary) 12%, var(--surface));
  border: 1px solid var(--border);
}
.rock-form-shell::before { left: -8px; transform: rotate(-38deg); }
.rock-form-shell::after { right: -8px; transform: rotate(38deg); }
.rock-form .field-row-3 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.invoice-note {
  display: flex; gap: 14px; align-items: flex-start;
  background: var(--gold-tint); border-radius: var(--radius-sm);
  padding: 16px 18px; margin: 20px 0; font-size: 13.5px; line-height: 1.65;
  color: var(--text-primary);
  border-left: 3px solid var(--gold);
}
.invoice-note .ic { font-size: 18px; flex: none; }
@media (max-width: 860px) {
  .rock-form .field-row-3 { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .rock-form-shell { padding: 28px 20px; border-radius: 14px; }
}

/* ---- FAQ — scoped over the shared .accordion-item (page-exclusive, safe
   to reskin here without touching a component another page relies on) ---- */
.rock-faq .accordion-item { border-bottom: none; border-top: 2px dashed var(--border); padding: 20px 0; }
.rock-faq .accordion-item:last-child { border-bottom: 2px dashed var(--border); }
.rock-faq .accordion-item summary { font-family: var(--font-head); font-size: 1.02rem; }
.rock-faq .accordion-item summary span {
  color: var(--accent); font-family: 'Bebas Neue', var(--font-head); font-size: 1.3rem;
  transition: transform .25s ease;
}
.rock-faq .accordion-item[open] summary span { transform: rotate(45deg); }

/* ===== Filter chips ===== */
.filter-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 40px; }
.chip {
  padding: 10px 20px; border-radius: var(--radius-pill);
  border: 1.5px solid var(--border);
  background: var(--surface);
  font-weight: 600; font-size: 14px;
  cursor: pointer; color: var(--text-secondary);
}
.chip.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ===== Sections ===== */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.split img { border-radius: var(--radius); width: 100%; aspect-ratio: 4/3; object-fit: cover; }

/* ===== Time-race chart ("See more, walk less") =====
   Deliberately dark in BOTH themes — its own self-contained component, not a
   [data-theme] override, so it never touches the light/dark cascade rules
   documented elsewhere in this file. Colours are exactly the site's own dark-
   theme brand/accent/gold tokens (:root dark block above), just pinned rather
   than switched, so the palette matches the rest of the page. The chart draws
   itself in on scroll: pathLength="1" normalises every path/segment to the
   same 0-1 unit, so stroke-dasharray/dashoffset needs no measuring. It is an
   illustrative comparison, not a measured one — deliberately, see the section
   above this in the file. */
.rc {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  padding: 36px 32px 28px;
  background: none;
  box-shadow: var(--shadow-lg);
}
.rc-glow {
  display: none;
}
.rc-glow-a { top: -20%; left: -16%; background: #0C8060; }
.rc-glow-b { bottom: -30%; right: -18%; background: #EBA92C; opacity: .14; }

/* Large ghost mark in the corner instead of its own row — decorative only,
   sits behind the copy so it costs no vertical space. Two classes (0,2,0)
   beat the base .ico rule (0,1,0) regardless of source order, since .ico is
   declared later in this file among the icon rules. */
.rc .rc-watermark {
  position: absolute;
  top: 18px; right: 20px;
  width: 130px; height: 130px;
  color: #7EBEA5;
  opacity: .10;
  pointer-events: none;
  animation: rcWatermarkFloat 3.5s ease-in-out infinite;
}
/* inset kept inside the watermark's own top/right margin (18px/20px) —
   .rc has overflow:hidden, so a wider inset here gets silently clipped
   by the box edge and the glow never shows at all. */
.rc .rc-watermark::before {
  content: "";
  position: absolute;
  inset: -14px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(126,190,165,.75), transparent 70%);
  filter: blur(14px);
  z-index: -1;
}
@keyframes rcWatermarkFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}
[data-theme="dark"] .rc .rc-watermark { opacity: .20; }
[data-theme="dark"] .rc .rc-watermark::before { background: radial-gradient(closest-side, rgba(126,190,165,.9), transparent 70%); }
[data-theme="light"] .rc .rc-watermark { color: var(--brand-dark); opacity: .22; }
[data-theme="light"] .rc .rc-watermark::before { background: radial-gradient(closest-side, rgba(9,99,73,.55), transparent 70%); }

.rc-tag {
  position: relative;
  margin: 0 0 10px;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: #9BD1BB;
}
.rc-head {
  position: relative;
  margin: 0 0 10px;
  max-width: 22ch;
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  line-height: 1.2;
  color: #F3EFE4;
}
[data-theme="light"] .rc-head { color: var(--text-primary); }
.rc-sub { position: relative; margin: 0 0 20px; max-width: 46ch; font-size: .96rem; line-height: 1.5; color: #A9B8B2; }

.rc-chart { position: relative; display: block; width: 100%; height: auto; overflow: visible; }
.rc-axis line { stroke: rgba(255,255,255,.14); stroke-width: 1; }
.rc-ticks line { stroke: rgba(255,255,255,.22); }
.rc-axis text { fill: #6E7C76; font-size: 11px; font-family: var(--font-body); }

.rc-line {
  fill: none;
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition-property: stroke-dashoffset;
  transition-timing-function: cubic-bezier(.4,0,.2,1);
}
.rc-line--dotted { stroke-dasharray: .04 .06; stroke-linecap: round; }
.rc-line--segway { stroke: #7EBEA5; }
.rc-line--car     { stroke: #F2C46D; }
.rc-line--walk    { stroke: #EE9A82; }

.rc-dot {
  fill: var(--rc-dot-color, #F3EFE4);
  opacity: 0;
  transform-origin: center;
  transform-box: fill-box;
  transform: scale(0);
  filter: drop-shadow(0 0 6px var(--rc-dot-color, #F3EFE4));
  transition: opacity .3s ease, transform .3s cubic-bezier(.34,1.56,.64,1);
}
.rc-dot--segway { --rc-dot-color: #7EBEA5; }
.rc-dot--car     { --rc-dot-color: #F2C46D; }
.rc-dot--walk    { --rc-dot-color: #EE9A82; }

/* Labels sit ABOVE their line's finish point, always — never below, so they
   can never collide with the axis text or the line itself underneath. */
.rc-label { opacity: 0; transition: opacity .4s ease; }
.rc-label-time  { font-family: var(--font-head); font-weight: 700; font-size: 16px; fill: #F3EFE4; }
.rc-label-note  { font-family: var(--font-body); font-size: 11px; fill: #A9B8B2; }

/* All three modes start drawing together, like a race — Segway (seg 1) is
   one confident curve; Car (seg 2-4) is three chained segments (a jittery
   stop-start drive, a stalled dotted "parking" stretch, then a rougher
   stretch on foot), each starting where the last one finished; Walking
   (seg 5) is one long, very slow meander. Who finishes drawing first argues
   the point on its own. */
.rc[data-rc].is-in path[data-seg="1"] { transition-duration: 1s;   transition-delay: .15s; stroke-dashoffset: 0; }
.rc[data-rc].is-in path[data-seg="2"] { transition-duration: .6s;  transition-delay: .15s; stroke-dashoffset: 0; }
.rc[data-rc].is-in path[data-seg="3"] { transition-duration: 1s;   transition-delay: .75s; stroke-dashoffset: 0; }
.rc[data-rc].is-in path[data-seg="4"] { transition-duration: 1.3s; transition-delay: 1.75s; stroke-dashoffset: 0; }
.rc[data-rc].is-in path[data-seg="5"] { transition-duration: 3.6s; transition-delay: .15s; stroke-dashoffset: 0; }
.rc[data-rc].is-in circle[data-seg] { opacity: 1; transform: scale(1); }
.rc[data-rc].is-in .rc-label { opacity: 1; }
/* Dot + label reveal timed to land right as each line finishes its own draw. */
.rc[data-rc].is-in circle[data-seg="1"], .rc[data-rc].is-in g[data-seg="1"] { transition-delay: 1.15s; }
.rc[data-rc].is-in circle[data-seg="4"], .rc[data-rc].is-in g[data-seg="4"] { transition-delay: 3.05s; }
.rc[data-rc].is-in circle[data-seg="5"], .rc[data-rc].is-in g[data-seg="5"] { transition-delay: 3.75s; }

.rc-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin: 14px 0 0;
  padding: 0;
  font-family: var(--font-body);
  font-size: 12px;
  color: #A9B8B2;
}
.rc-legend li { display: flex; align-items: center; gap: 7px; }
.rc-legend-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.rc-legend-dot--segway { background: #7EBEA5; }
.rc-legend-dot--car     { background: #F2C46D; }
.rc-legend-dot--walk    { background: #EE9A82; }

.rc-note {
  position: relative;
  margin: 16px 0 0;
  font-size: .9rem;
  line-height: 1.5;
  color: #A9B8B2;
}
.rc-note a { color: #7EBEA5; text-decoration: underline; }

@media (max-width: 680px) {
  .rc { padding: 30px 20px 22px; }
  .rc-sub { max-width: none; }
  .rc .rc-watermark { width: 90px; height: 90px; top: 14px; right: 14px; opacity: .08; }
  .rc-label-time { font-size: 22px; }
  .rc-label-note { font-size: 15px; }
}
@media (prefers-reduced-motion: reduce) {
  .rc-line { transition: none; stroke-dashoffset: 0; }
  .rc-dot { transition: none; opacity: 1; transform: scale(1); }
  .rc-label { transition: none; opacity: 1; }
  .rc .rc-watermark { animation: none; }
}
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 32px;
  box-shadow: var(--shadow);
}
.pricing-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.price-card { text-align: center; }
.price-card .num { font-family: var(--font-head); font-size: 2.6rem; font-weight: 700; }
.price-card .unit { font-size: 14px; color: var(--text-secondary); }
.info-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
.info-list li { display: flex; gap: 14px; align-items: flex-start; color: var(--text-secondary); font-size: 14.5px; }
.info-list li b { color: var(--text-primary); }
.check-icon { flex: none; width: 28px; height: 28px; border-radius: 50%; background: var(--brand-tint); color: var(--brand-dark); display: flex; align-items: center; justify-content: center; font-size: 15px; margin-top: 2px; }
[data-theme="dark"] .check-icon { color: var(--brand); }

/* ===== About stat row (reused: homepage teaser + /about-us/) ===== */
/* Fixed three-column grid + tabular figures. As a wrapping flex row the
   growing numbers re-wrapped on almost every frame, which is what made the
   whole block jump while it counted. */
.about-badge-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px 22px;
  margin: 26px 0;
  align-items: baseline;
}
.about-stat { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.about-stat b {
  font-family: var(--font-head); font-size: 1.9rem; color: var(--accent);
  text-shadow: 0 0 14px color-mix(in srgb, var(--accent) 35%, transparent);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  white-space: nowrap;
}
@media (max-width: 620px) {
  .about-badge-row { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 10px; }
  .about-stat { flex-direction: column; align-items: flex-start; gap: 2px; }
  .about-stat b { font-size: 1.5rem; }
  .about-stat span { font-size: 11.5px; line-height: 1.25; }
}
.about-stat.glow b { animation: glowPulseSoft 2.8s ease-in-out infinite; }
.about-stat span { font-size: 13px; color: var(--text-secondary); }
@keyframes glowPulseSoft {
  0%, 100% { text-shadow: 0 0 8px color-mix(in srgb, var(--accent) 25%, transparent); }
  50% { text-shadow: 0 0 20px color-mix(in srgb, var(--accent) 55%, transparent); }
}

/* ===== Marquee ticker ===== */
/* Hairlines taper off at both ends in every theme — an edge-to-edge rule was
   another place the page looked chopped into blocks. */
.marquee { overflow: hidden; white-space: nowrap; padding: 20px 0; position: relative; border: none; }
.marquee::before,
.marquee::after {
  content: ""; position: absolute; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--border) 30%, var(--border) 70%, transparent);
}
.marquee::before { top: 0; }
.marquee::after { bottom: 0; }
.marquee-track { display: inline-flex; gap: 16px; animation: marqueeScroll 34s linear infinite; }
.marquee-track span { font-family: var(--font-head); font-size: 1.15rem; font-weight: 700; color: var(--text-muted); white-space: nowrap; }
.marquee-track span.dot { color: var(--accent); }
@keyframes marqueeScroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ===== About hero / quote ===== */
.about-hero { padding: 64px 0 16px; }
.about-quote { max-width: 760px; margin: 8px auto 0; text-align: center; }
.about-quote p { font-family: var(--font-head); font-size: 1.5rem; font-weight: 500; color: var(--text-primary); line-height: 1.5; }
.about-quote cite { font-size: 12.5px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .08em; font-style: normal; }

/* ---- Word-by-word reveal: each word arrives lit gold, then settles ---- */
.reveal-words .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(.35em);
  color: var(--gold);
  text-shadow: 0 0 18px color-mix(in srgb, var(--gold) 60%, transparent);
}
.reveal-words.playing .w {
  animation: wordIn .9s ease forwards;
  animation-delay: var(--d, 0s);
}
@keyframes wordIn {
  0%   { opacity: 0; transform: translateY(.35em); color: var(--gold);
         text-shadow: 0 0 22px color-mix(in srgb, var(--gold) 70%, transparent); }
  35%  { opacity: 1; transform: translateY(0); color: var(--gold);
         text-shadow: 0 0 18px color-mix(in srgb, var(--gold) 55%, transparent); }
  100% { opacity: 1; transform: translateY(0); color: var(--text-primary);
         text-shadow: 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .reveal-words .w { opacity: 1; transform: none; color: var(--text-primary); text-shadow: none; }
  .reveal-words.playing .w { animation: none; }
}

/* ===== Feature grid (why choose us) ===== */
.feature-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; }
.feature-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 26px; }
.feature-card .ic { width: 54px; height: 54px; border-radius: 50%; background: var(--brand-tint); color: var(--brand-dark); display: flex; align-items: center; justify-content: center; font-size: 24px; margin-bottom: 16px; }
[data-theme="dark"] .feature-card .ic { color: var(--brand); }
.feature-card h3 { font-size: 1.05rem; }
.feature-card p { font-size: 13.5px; margin: 0; }

/* ===== Testimonials ===== */
.testimonial-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.testimonial-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 26px; display: flex; flex-direction: column; transition: transform .25s ease, box-shadow .25s ease; }
.testimonial-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
@media (prefers-reduced-motion: reduce) {
  .testimonial-card { transition: none; }
  .testimonial-card:hover { transform: none; }
}
.testimonial-card .stars { color: var(--gold); margin-bottom: 12px; letter-spacing: 2px; }
.testimonial-card p { font-size: 14px; color: var(--text-secondary); margin-bottom: 18px; flex: 1; }
.testimonial-card .who { display: flex; flex-direction: column; }
.testimonial-card .who b { font-size: 13.5px; }
.testimonial-card .who span { font-size: 12px; color: var(--text-muted); }
.testimonial-source { font-size: 11px; color: var(--text-muted); margin-top: 4px; }

/* ===== Booking widget ===== */
.booking-widget { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: 32px; }
.booking-steps { display: flex; align-items: center; gap: 10px; margin-bottom: 28px; }
.booking-step { display: flex; align-items: center; gap: 9px; font-size: 13px; font-weight: 700; color: var(--text-muted); }
.booking-step .dot { width: 26px; height: 26px; border-radius: 50%; background: var(--surface-alt); color: var(--text-muted); display: flex; align-items: center; justify-content: center; font-size: 12px; flex: none; }
.booking-step.active { color: var(--brand-dark); }
[data-theme="dark"] .booking-step.active { color: var(--brand); }
.booking-step.active .dot { background: var(--brand); color: var(--brand-contrast); }
.booking-step.done .dot { background: var(--success); color: #fff; }
.step-line { flex: 1; height: 1px; background: var(--border); }
.field-label { font-size: 13px; font-weight: 700; margin-bottom: 9px; display: block; }
.field-label .req { color: var(--danger); }
/* Generic two-column field row — first/last name, any paired inputs.
   Unscoped (unlike .rock-form .field-row-3) so every booking widget can
   use it, not just the group-enquiry form. */
.field-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 480px) { .field-row-2 { grid-template-columns: 1fr; } }
.field-input {
  width: 100%; padding: 13px 16px; border-radius: var(--radius-sm);
  border: 1.5px solid var(--border); background: var(--bg); color: var(--text-primary);
  font-family: var(--font-body); font-size: 15px;
  /* iOS styles date/number/email inputs itself — reset so every field in the
     form is the same height, radius and colour */
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  min-height: 50px;
  line-height: 1.3;
  text-align: left;
}
.field-input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 18%, transparent);
}
.field-input::placeholder { color: var(--text-muted); opacity: 1; }
/* Safari renders empty date fields blank; keep the picker visible and aligned */
.field-input[type="date"] { position: relative; }
.field-input[type="date"]::-webkit-date-and-time-value { text-align: left; margin: 0; }
.field-input[type="date"]::-webkit-calendar-picker-indicator {
  filter: var(--picker-filter, none);
  opacity: .75; cursor: pointer;
}
[data-theme="dark"] .field-input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(1) brightness(.9);
}
/* strip the number spinner so it matches the other fields */
.field-input[type="number"]::-webkit-outer-spin-button,
.field-input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.field-input[type="number"] { -moz-appearance: textfield; }
textarea.field-input { min-height: 0; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 18px; }
.segmented { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 20px; }
.segmented label {
  border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  padding: 14px; text-align: center; font-weight: 700; font-size: 14px; cursor: pointer;
  transition: all .15s; line-height: 1.4;
}
.segmented input { display: none; }
.segmented input:checked + label { border-color: var(--brand); background: var(--brand-tint); color: var(--brand-dark); }
[data-theme="dark"] .segmented input:checked + label { color: var(--brand); }
/* ===== Booking option cards (morning / group / private) =====
   Replaces the old two-up .segmented control. A tour can now offer two or three
   tiers, and each needs room for a price and a line explaining what it is —
   a guest choosing between "Morning" and "Group" cannot be expected to guess. */
.type-options { display: flex; flex-direction: column; gap: 10px; margin-bottom: 22px; }
.type-options .oc-input { position: absolute; opacity: 0; pointer-events: none; }
.opt-card {
  display: flex; align-items: flex-start; gap: 13px;
  border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  padding: 15px 16px; cursor: pointer; transition: border-color .15s, background .15s;
}
.opt-card:hover { border-color: var(--brand); }
.oc-tick {
  flex: none; width: 20px; height: 20px; margin-top: 2px; border-radius: 50%;
  border: 1.5px solid var(--border); position: relative; transition: all .15s;
}
.oc-tick::after {
  content: ''; position: absolute; inset: 4px; border-radius: 50%;
  background: var(--brand-contrast); transform: scale(0); transition: transform .15s;
}
.oc-main { flex: 1; min-width: 0; }
.oc-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.oc-title { font-weight: 700; font-size: 14.5px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.oc-badge {
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 8px; border-radius: var(--radius-pill);
  background: var(--brand-tint); color: var(--brand-dark);
}
[data-theme="dark"] .oc-badge { color: var(--brand); }
.oc-price { flex: none; font-family: var(--font-head); font-weight: 700; font-size: 1.2rem; }
.oc-note { display: block; font-size: 12.5px; color: var(--text-secondary); line-height: 1.55; margin-top: 5px; }
.oc-meta { display: block; font-size: 11.5px; color: var(--text-muted); margin-top: 5px; }
.oc-input:checked + .opt-card { border-color: var(--brand); background: var(--brand-tint); }
.oc-input:checked + .opt-card .oc-tick { border-color: var(--brand); background: var(--brand); }
.oc-input:checked + .opt-card .oc-tick::after { transform: scale(1); }
.oc-input:focus-visible + .opt-card { outline: 2px solid var(--brand); outline-offset: 2px; }
.time-hint { font-size: 12.5px; color: var(--text-muted); margin: -12px 0 20px; line-height: 1.6; }
/* Sits under the card blurb so the "from €39" badge is qualified where the guest
   reads it, not two clicks later in the booking widget. */
.tour-early {
  font-size: 12.5px; color: var(--text-secondary); line-height: 1.55;
  margin: -4px 0 4px; display: flex; align-items: center; gap: 7px;
}
.tour-early strong { color: var(--text-primary); font-weight: 700; }
.tour-early em { font-style: normal; color: var(--gold); font-weight: 600; letter-spacing: .01em; }
/* Same qualifier, on the tour page hero where it sits over the photo. */
.thf-early {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; margin-top: 10px;
  padding: 7px 13px; border-radius: var(--radius-pill);
  background: rgba(255,255,255,.14); backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,.22); color: #fff;
}
.thf-early .ico { width: 15px; height: 15px; color: var(--gold); }

/* On a 320–400px phone the title row has ~170px to hold a name, a badge and a
   price. Shrink the type rather than let "Join a mini-group" wrap mid-phrase. */
@media (max-width: 400px) {
  .opt-card { padding: 13px 13px; gap: 11px; }
  .oc-title { font-size: 13.5px; gap: 6px; }
  .oc-price { font-size: 1.05rem; }
  .oc-badge { font-size: 10px; padding: 2px 7px; }
  .oc-note, .oc-meta { font-size: 12px; }
}
/* Gold rather than the usual green: this note sits directly under the brand-tinted
   total box, and two identical tints stacked read as one mushy block. Gold also
   ties it to the sunrise mark used for the morning tier everywhere else. */
.save-note {
  display: flex; align-items: center; gap: 9px;
  font-size: 12.5px; font-weight: 600; color: var(--text-primary);
  background: var(--gold-tint); padding: 10px 14px;
  border-radius: var(--radius-sm); margin-bottom: 14px; line-height: 1.55;
}
.save-note::before {
  content: ''; flex: none; width: 15px; height: 15px; background-color: var(--gold);
  -webkit-mask: center/contain no-repeat; mask: center/contain no-repeat;
  -webkit-mask-image: var(--i-sunrise); mask-image: var(--i-sunrise);
}

.pill-options { display: flex; flex-wrap: wrap; gap: 9px; margin-bottom: 20px; }
.pill-options label {
  border: 1.5px solid var(--border); border-radius: var(--radius-pill);
  padding: 10px 17px; font-size: 13px; font-weight: 600; cursor: pointer;
}
.pill-options input { display: none; }
.pill-options input:checked + label { border-color: var(--brand); background: var(--brand); color: var(--brand-contrast); }
.hint { font-size: 12.5px; color: var(--text-muted); margin: -10px 0 20px; line-height: 1.6; }
.total-box { background: var(--brand-tint); border-radius: var(--radius-sm); padding: 18px 20px; margin: 22px 0 10px; display: flex; align-items: baseline; justify-content: space-between; }
.total-box .amount { font-family: var(--font-head); font-size: 1.9rem; font-weight: 700; color: var(--brand-dark); }
[data-theme="dark"] .total-box .amount { color: var(--brand); }
.price-breakdown { font-size: 13px; color: var(--text-secondary); margin-bottom: 14px; }
.surcharge-note { font-size: 12.5px; color: var(--text-muted); background: var(--surface-alt); padding: 11px 15px; border-radius: var(--radius-sm); margin-bottom: 20px; line-height: 1.6; }
.booking-actions { display: flex; gap: 12px; margin-top: 10px; }
.form-step { display: none; }
.form-step.visible { display: block; }
.success-box { text-align: center; padding: 20px 0; }
.success-box .check { width: 56px; height: 56px; border-radius: 50%; background: var(--success-tint); color: var(--success); display: flex; align-items: center; justify-content: center; font-size: 26px; margin: 0 auto 16px; }
.booking-trust { display: flex; flex-direction: column; gap: 10px; margin-top: 22px; padding-top: 20px; border-top: 1px dashed var(--border); }
.booking-trust-item { display: flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--text-secondary); }
.booking-trust-item .ic { flex: none; width: 26px; height: 26px; border-radius: 50%; background: var(--brand-tint); color: var(--brand-dark); display: flex; align-items: center; justify-content: center; font-size: 13px; }
[data-theme="dark"] .booking-trust-item .ic { color: var(--brand); }
.reassurance { font-size: 12px; color: var(--text-muted); text-align: center; margin-top: 12px; }

/* ===== Info sidebar card ===== */
.info-card { background: var(--surface-alt); border-radius: var(--radius); padding: 28px; }
.info-card h3 { margin-bottom: 18px; }

/* ===== Monster Bikes section ===== */
.mb-section { position: relative; overflow: hidden; }
.mb-grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: 40px; align-items: start; }
.mb-col { display: flex; flex-direction: column; }
.mb-gallery { border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); aspect-ratio: 4/3; flex: none; }
.mb-gallery img { width: 100%; height: 100%; object-fit: cover; }
.mb-rental-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 28px; margin-top: 24px; display: flex; flex-direction: column; }
.mb-rental-card h3 { margin-bottom: 4px; }
.mb-rental-card .hint { margin-top: 4px; }
.mb-rental-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 18px; }
.mb-rental-item { background: var(--surface-alt); border-radius: var(--radius-sm); padding: 16px 18px; }
.mb-rental-item .seat-label { font-weight: 700; font-size: 14px; display: block; margin-bottom: 6px; }
.mb-rental-item .price { font-family: var(--font-head); font-size: 1.3rem; color: var(--accent); }
.mb-rental-item .price-note { font-size: 12px; color: var(--text-secondary); display: block; margin-top: 2px; }
.mb-rental-card .mb-rental-footer { margin-top: auto; padding-top: 16px; }
/* Two-column only (below 961px .mb-grid collapses to one column and none of
   this applies). The two columns used to be `align-items: start`, so each sized
   itself independently and the photo+rental stack ended well below the booking
   form — the section read as lopsided on tablets. Now the row stretches and the
   PHOTO absorbs the difference: .mb-gallery drops its fixed 4/3 ratio and
   flexes, so whichever column is naturally shorter grows its image rather than
   opening dead white space inside a card. Both columns therefore end on the
   same line at every width in this range. min-height keeps the photo from being
   crushed if the form is ever much shorter than the rental card. */
@media (min-width: 961px) {
  .mb-grid { align-items: stretch; }
  .mb-col { height: 100%; }
  .mb-gallery { flex: 1 1 auto; aspect-ratio: auto; min-height: 300px; }
}

/* ===== Footer ===== */
/* The 1px rule plus a flat fill made a visible seam. Both themes now ease into
   the footer over a tall gradient, so there is no line to see. */
footer {
  border-top: none;
  backdrop-filter: blur(8px);
  padding: 56px 0 32px;
  background: linear-gradient(180deg,
    transparent 0%,
    color-mix(in srgb, var(--surface) 30%, transparent) 22%,
    color-mix(in srgb, var(--surface) 62%, transparent) 45%,
    color-mix(in srgb, var(--surface) 80%, transparent) 70%,
    color-mix(in srgb, var(--surface) 82%, transparent) 100%);
}
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 40px; margin-bottom: 40px; }
.footer-col h4 { font-size: 14px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); margin-bottom: 16px; }
.footer-col a, .footer-col p { display: block; font-size: 14px; color: var(--text-secondary); margin-bottom: 12px; }
.footer-col a:hover { color: var(--brand-dark); }
[data-theme="dark"] .footer-col a:hover { color: var(--brand); }
.social-row { display: flex; gap: 12px; margin-top: 8px; }
.social-row a { width: 40px; height: 40px; border-radius: 50%; background: var(--surface-alt); display: flex; align-items: center; justify-content: center; }
.social-row a:hover { background: var(--brand-tint); color: var(--brand-dark); }
.footer-bottom { border-top: 1px solid var(--border); padding-top: 24px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; font-size: 13px; color: var(--text-muted); }
/* Trademark attribution. Google Ads restricts a trademark in AD TEXT unless the
   advertiser fits a listed exception — one of which is providing services
   relating to the trademarked goods. The reviewer reads the landing page, so
   the page has to say plainly which of the two this business is. Quiet by
   design: it is a legal notice, not a message to guests. */
.footer-legal { margin: 18px 0 0; max-width: 78ch; font-size: 11.5px; line-height: 1.5; color: var(--text-muted); opacity: .8; }


/* Icon paths. Kept as custom properties so the class list above stays readable. */
:root {
  --i-globe: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M12%202a10%2010%200%20100%2020%2010%2010%200%20000-20M2%2012h20M12%202a15.3%2015.3%200%20010%2020%2015.3%2015.3%200%20010-20'/></svg>");
  --i-users: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M16%2021v-2a4%204%200%2000-4-4H6a4%204%200%2000-4%204v2M9%203a4%204%200%20100%208%204%204%200%20000-8M22%2021v-2a4%204%200%2000-3-3.87M16%203.13a4%204%200%20010%207.75'/></svg>");
  --i-clock: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M12%202a10%2010%200%20100%2020%2010%2010%200%20000-20M12%206.5V12l3.5%202'/></svg>");
  --i-peak: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M3%2020h18L14%206l-3.2%206L9%209z'/></svg>");
  --i-leaf: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M11%2020A7%207%200%20019.8%206.1C15.5%205%2017%204.5%2019%202c1%202%202%204.2%202%208%200%205.5-4.8%2010-10%2010zM2%2021c0-3%201.9-5.4%205.1-6'/></svg>");
  --i-map: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M9%2020l-6%203V6l6-3%206%203%206-3v17l-6%203zM9%203v17M15%206v17'/></svg>");
  --i-bolt: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M13%202L3%2014h9l-1%208%2010-12h-9z'/></svg>");
  --i-camera: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M23%2019a2%202%200%2001-2%202H3a2%202%200%2001-2-2V8a2%202%200%20012-2h4l2-3h6l2%203h4a2%202%200%20012%202zM12%209a4%204%200%20100%208%204%204%200%20000-8'/></svg>");
  --i-trophy: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M6%209H4.5a2.5%202.5%200%20010-5H6M18%209h1.5a2.5%202.5%200%20000-5H18M4%2022h16M10%2014.7V17c0%20.6-.5%201-1%201.2C7.9%2018.8%207%2020.2%207%2022M14%2014.7V17c0%20.6.5%201%201%201.2%201.1.6%202%202%202%203.8M18%202H6v7a6%206%200%200012%200z'/></svg>");
  --i-verified: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M9%2012l2%202%204-4M12%203a9%209%200%20100%2018%209%209%200%20000-18'/></svg>");
  /* The old path was 'M18 6.5A7 7 0 108 17.5' — a single arc that stopped at
     (8,17.5) instead of curving back out to the right, so the C of the euro
     was cut off mid-stroke and rendered as half a symbol. This draws the full
     open C (top-right, counterclockwise around, back to bottom-right) plus
     the two crossbars. */
  --i-euro: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M18.5%206.6a7.4%207.4%200%20100%2010.8'/><path%20d='M3.8%2010.4h10.4M3.8%2013.6h8.6'/></svg>");
  --i-tag: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M20.6%2013.4l-7.2%207.2a2%202%200%2001-2.8%200L2%2012V2h10l8.6%208.6a2%202%200%20010%202.8zM7.5%207.5h.01'/></svg>");
  --i-refresh: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M23%204v6h-6M1%2020v-6h6M3.5%209a9%209%200%200114.9-3.4L23%2010M1%2014l4.6%204.4A9%209%200%200020.5%2015'/></svg>");
  --i-chat: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M21%2011.5a8.4%208.4%200%2001-9%208.5%208.4%208.4%200%2001-3.8-.9L3%2021l1.9-5.2A8.4%208.4%200%20013%2011.5%208.5%208.5%200%200112%203a8.5%208.5%200%20019%208.5z'/></svg>");
  --i-phone: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M22%2016.9v3a2%202%200%2001-2.2%202%2019.8%2019.8%200%2001-8.6-3.1%2019.5%2019.5%200%2001-6-6A19.8%2019.8%200%20012.1%204.2%202%202%200%20014.1%202h3a2%202%200%20012%201.7c.1%201%20.4%201.9.7%202.8a2%202%200%2001-.5%202.1L8.1%209.9a16%2016%200%20006%206l1.3-1.3a2%202%200%20012.1-.4c.9.3%201.9.6%202.8.7a2%202%200%20011.7%202z'/></svg>");
  --i-mail: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M4%204h16a2%202%200%20012%202v12a2%202%200%2001-2%202H4a2%202%200%2001-2-2V6a2%202%200%20012-2zM22%206l-10%207L2%206'/></svg>");
  --i-pin: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M21%2010c0%207-9%2013-9%2013s-9-6-9-13a9%209%200%200118%200zM12%207a3%203%200%20100%206%203%203%200%20000-6'/></svg>");
  --i-sun: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M12%207a5%205%200%20100%2010%205%205%200%20000-10M12%201v2M12%2021v2M4.2%204.2l1.4%201.4M18.4%2018.4l1.4%201.4M1%2012h2M21%2012h2M4.2%2019.8l1.4-1.4M18.4%205.6l1.4-1.4'/></svg>");
  --i-sunrise: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M12%203v2.5M4.6%207.6l1.8%201.8M19.4%207.6l-1.8%201.8M2.5%2018.5h19M7.5%2018.5a4.5%204.5%200%20019%200'/></svg>");
  --i-moon: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M21%2012.8A9%209%200%201111.2%203%207%207%200%200021%2012.8z'/></svg>");
  --i-compass: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M12%202a10%2010%200%20100%2020%2010%2010%200%20000-20M16.2%207.8l-2.1%206.4-6.4%202.1%202.1-6.4z'/></svg>");
  --i-key: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M21%202l-2%202M11.4%2011.6a5.5%205.5%200%2011-7.8%207.8%205.5%205.5%200%20017.8-7.8zm0%200L15.5%207.5m0%200l3%203L22%207l-3-3'/></svg>");
  --i-shield: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M12%2022s8-4%208-10V5l-8-3-8%203v7c0%206%208%2010%208%2010z'/></svg>");
  --i-receipt: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M5%202v20l2-1%202%201%202-1%202%201%202-1%202%201V2l-2%201-2-1-2%201-2-1-2%201zM9%208h6M9%2012h6M9%2016h4'/></svg>");
  --i-user: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M20%2021v-2a4%204%200%2000-4-4H8a4%204%200%2000-4%204v2M12%203a4%204%200%20100%208%204%204%200%20000-8'/></svg>");
  --i-landmark: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M3%2021h18M5%2021V10M9.5%2021V10M14.5%2021V10M19%2021V10M2%2010l10-7%2010%207'/></svg>");
  --i-help: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M12%202a10%2010%200%20100%2020%2010%2010%200%20000-20M9.1%209a3%203%200%20015.8%201c0%202-3%203-3%203M12%2017h.01'/></svg>");
  --i-sunset: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M17%2018a5%205%200%2000-10%200M12%202v6M4.2%2010.2l1.4%201.4M1%2018h2M21%2018h2M18.4%2011.6l1.4-1.4M23%2022H1'/></svg>");
  --i-book: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M4%2019.5A2.5%202.5%200%20016.5%2017H20M6.5%202H20v20H6.5A2.5%202.5%200%20014%2019.5v-15A2.5%202.5%200%20016.5%202z'/></svg>");
  --i-heart: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M20.8%204.6a5.5%205.5%200%2000-7.8%200L12%205.7l-1.1-1.1a5.5%205.5%200%2000-7.8%207.8l1.1%201.1L12%2021.2l7.8-7.8%201.1-1.1a5.5%205.5%200%20000-7.8z'/></svg>");
  --i-sparkle: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M12%203l1.9%205.1L19%2010l-5.1%201.9L12%2017l-1.9-5.1L5%2010l5.1-1.9zM19%2015l.9%202.1L22%2018l-2.1.9L19%2021l-.9-2.1L16%2018l2.1-.9z'/></svg>");
  --i-bag: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M6%202L3%206v14a2%202%200%20002%202h14a2%202%200%20002-2V6l-3-4zM3%206h18M16%2010a4%204%200%2001-8%200'/></svg>");
  --i-alert: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M10.3%203.9L1.8%2018a2%202%200%20001.7%203h17a2%202%200%20001.7-3L14.7%203.9a2%202%200%2000-3.4%200zM12%209v4M12%2017h.01'/></svg>");
  --i-home: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M3%209.5L12%202l9%207.5V21a2%202%200%2001-2%202H5a2%202%200%2001-2-2zM9%2022V12h6v10'/></svg>");
  --i-lock: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M5%2011h14a2%202%200%20012%202v7a2%202%200%2001-2%202H5a2%202%200%2001-2-2v-7a2%202%200%20012-2zM7%2011V7a5%205%200%200110%200v4'/></svg>");
  --i-family: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M9%203a3%203%200%20100%206%203%203%200%20000-6M4%2021v-2a4%204%200%20014-4h2a4%204%200%20014%204v2M17.5%208a2.5%202.5%200%20100%205%202.5%202.5%200%20000-5M15%2021v-1.5a3%203%200%20013-3h1a3%203%200%20013%203V21'/></svg>");
  --i-hand: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M18%2011V6a2%202%200%2000-4%200v5M14%2010V4a2%202%200%2000-4%200v6M10%2010.5V6a2%202%200%2000-4%200v9M18%2011a4%204%200%2001-4%204h-1a6%206%200%2001-6-6'/></svg>");
  --i-segway: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M4.80%2013.70a3.70%203.70%200%201%201%200%207.40a3.70%203.70%200%201%201%200%20-7.40zM4.80%2016.10a1.30%201.30%200%201%201%200%202.60a1.30%201.30%200%201%201%200%20-2.60zM19.20%2013.70a3.70%203.70%200%201%201%200%207.40a3.70%203.70%200%201%201%200%20-7.40zM19.20%2016.10a1.30%201.30%200%201%201%200%202.60a1.30%201.30%200%201%201%200%20-2.60zM8.90%2015.60h6.20a0.90%200.90%200%200%201%200.90%200.90v1.80a0.90%200.90%200%200%201%20-0.90%200.90h-6.20a0.90%200.90%200%200%201%20-0.90%20-0.90v-1.80a0.90%200.90%200%200%201%200.90%20-0.90zM9.9%2012.4h4.2l1.3%203.2H8.6zM11.50%205.20h1.00a0.30%200.30%200%200%201%200.30%200.30v6.60a0.30%200.30%200%200%201%20-0.30%200.30h-1.00a0.30%200.30%200%200%201%20-0.30%20-0.30v-6.60a0.30%200.30%200%200%201%200.30%20-0.30zM6.75%202.70h2.30a1.15%201.15%200%200%201%201.15%201.15v0.00a1.15%201.15%200%200%201%20-1.15%201.15h-2.30a1.15%201.15%200%200%201%20-1.15%20-1.15v-0.00a1.15%201.15%200%200%201%201.15%20-1.15zM14.95%202.70h2.30a1.15%201.15%200%200%201%201.15%201.15v0.00a1.15%201.15%200%200%201%20-1.15%201.15h-2.30a1.15%201.15%200%200%201%20-1.15%20-1.15v-0.00a1.15%201.15%200%200%201%201.15%20-1.15zM11.65%202.40h0.70a1.45%201.45%200%200%201%201.45%201.45v0.00a1.45%201.45%200%200%201%20-1.45%201.45h-0.70a1.45%201.45%200%200%201%20-1.45%20-1.45v-0.00a1.45%201.45%200%200%201%201.45%20-1.45z'/></svg>");
  --i-bridge: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M2%2018.5h20M6.5%2018.5V7.2M17.5%2018.5V7.2M5%207.2h3M16%207.2h3M6.5%207.2c2.4%204.6%208.6%204.6%2011%200M6.5%207.2C5.3%209.4%203.8%2011%202%2012.3M17.5%207.2c1.2%202.2%202.7%203.8%204.5%205.1'/></svg>");
  --i-dome: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M3%2021h18M4.5%2021v-6.5M8%2021v-6.5M16%2021v-6.5M19.5%2021v-6.5M3%2014.5h18M12%204.2c2%201.7%203%203.8%203%206v4.3H9v-4.3c0-2.2%201-4.3%203-6zM12%204.2V1.8M12%208.6v2.4'/></svg>");
  --i-turret: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M12%202.2l4.2%205.3H7.8zM8.4%207.5v3.4M15.6%207.5v3.4M6%2010.9h12M6.4%2010.9V21M17.6%2010.9V21M4%2021h16M9.6%2021v-3.6a2.4%202.4%200%20014.8%200V21'/></svg>");
  --i-wave: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M2%207.6c2.4-2%204.9-2%207.3%200s4.9%202%207.3%200%202.4-1.4%205.4-1.4M2%2012.4c2.4-2%204.9-2%207.3%200s4.9%202%207.3%200%202.4-1.4%205.4-1.4M2%2017.2c2.4-2%204.9-2%207.3%200s4.9%202%207.3%200%202.4-1.4%205.4-1.4'/></svg>");
  --i-helmet: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M3.2%2015.2a8.8%208.8%200%200117.6%200v1.6a2%202%200%2001-2%202h-2.3l-.9-3.6H8.4l-.9%203.6H5.2a2%202%200%2001-2-2zM3.2%2015.2h17.6'/></svg>");
  --i-castle: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M3%2021V8.4l3-2v3h3.5V6.4l2.5-2%202.5%202v3H18v-3l3%202V21zM3%2021h18M10%2021v-4.6h4V21'/></svg>");
  --i-mbike: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='black'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'><path%20d='M5.5%2014.4a4%204%200%20100%208%204%204%200%20000-8M18.5%2014.4a4%204%200%20100%208%204%204%200%20000-8M9.5%2018.4h5M9.5%2018.4l2.2-6.4h4.6M16.3%2012l2.2%206.4M11.7%2012H8.6M16.3%2012l.9-2.6h2.4'/></svg>");
}

/* =====================================================================
   Icon set — replaces the emoji that used to sit in tags, badges and
   buttons. Emoji are a messenger's alphabet: multicoloured, inconsistent
   between platforms, and they read as a chat app rather than a brand.

   Each icon is an SVG carried in a CSS mask, so it takes its colour from
   `currentColor` and its size from `font-size` — one class, no sprite
   sheet, no extra request, and it inherits the theme automatically.
   ===================================================================== */
.ico {
  display: inline-block;
  width: 1em; height: 1em;
  flex: none;
  background-color: currentColor;
  -webkit-mask: center / contain no-repeat;
          mask: center / contain no-repeat;
  vertical-align: -0.14em;
}
/* --- Traced marks -------------------------------------------------------
   These come from real reference drawings, so they carry far more path data
   than a UI glyph. They are linked as files rather than inlined: keeping them
   out of this stylesheet leaves it small, and the browser caches each one
   separately. A mask reads the file's alpha, so the colour still comes from
   `currentColor` exactly like the inline icons above.
   Detail costs legibility — use these at 40px and up, not inside a tag pill. */
.ico--segway,
.ico--segway-mark,
.ico--training,
.ico--monster-bike,
.ico--monster-bike-rent,
.ico--chain-bridge,
.ico--elizabeth-bridge,
.ico--liberty-bridge,
.ico--parliament,
.ico--matthias-church,
.ico--basilica,
.ico--buda-castle,
.ico--fishermans-bastion,
.ico--water-tower,
.ico--liberty-statue,
.ico--tour-guide,
.ico--group-tour { -webkit-mask-size: contain; mask-size: contain; }

.ico--segway            { -webkit-mask-image: url("/assets/icons/segway.svg");            mask-image: url("/assets/icons/segway.svg"); }
.ico--segway-mark       { -webkit-mask-image: url("/assets/icons/segway-mark.svg");       mask-image: url("/assets/icons/segway-mark.svg"); }
.ico--training          { -webkit-mask-image: url("/assets/icons/training.svg");          mask-image: url("/assets/icons/training.svg"); }
.ico--monster-bike      { -webkit-mask-image: url("/assets/icons/monster-bike.svg");      mask-image: url("/assets/icons/monster-bike.svg"); }
/* Social/brand marks. External files, not inline data-URIs: they are outline
   drawings with several sub-paths and inlining them bloats this file. They are
   masks like every other icon, so they inherit the link colour and both themes
   for free. Rendered to PNG and eyeballed before shipping (see "Do not design
   SVG blind"). These replaced literal "IG" / "▶" / "TA" text in the footer and
   the contact page, which is what read as broken icons. */
.ico--instagram         { -webkit-mask-image: url("/assets/icons/instagram.svg");         mask-image: url("/assets/icons/instagram.svg"); }
.ico--youtube           { -webkit-mask-image: url("/assets/icons/youtube.svg");           mask-image: url("/assets/icons/youtube.svg"); }
.ico--tripadvisor       { -webkit-mask-image: url("/assets/icons/tripadvisor.svg");       mask-image: url("/assets/icons/tripadvisor.svg"); }
.ico--monster-bike-rent { -webkit-mask-image: url("/assets/icons/monster-bike-rent.svg"); mask-image: url("/assets/icons/monster-bike-rent.svg"); }
.ico--chain-bridge      { -webkit-mask-image: url("/assets/icons/chain-bridge.svg");      mask-image: url("/assets/icons/chain-bridge.svg"); }
.ico--elizabeth-bridge  { -webkit-mask-image: url("/assets/icons/elizabeth-bridge.svg");  mask-image: url("/assets/icons/elizabeth-bridge.svg"); }
.ico--liberty-bridge    { -webkit-mask-image: url("/assets/icons/liberty-bridge.svg");    mask-image: url("/assets/icons/liberty-bridge.svg"); }
.ico--parliament        { -webkit-mask-image: url("/assets/icons/parliament.svg");        mask-image: url("/assets/icons/parliament.svg"); }
.ico--matthias-church   { -webkit-mask-image: url("/assets/icons/matthias-church.svg");   mask-image: url("/assets/icons/matthias-church.svg"); }
.ico--basilica          { -webkit-mask-image: url("/assets/icons/basilica.svg");          mask-image: url("/assets/icons/basilica.svg"); }
.ico--buda-castle       { -webkit-mask-image: url("/assets/icons/buda-castle.svg");       mask-image: url("/assets/icons/buda-castle.svg"); }
.ico--fishermans-bastion{ -webkit-mask-image: url("/assets/icons/fishermans-bastion.svg");mask-image: url("/assets/icons/fishermans-bastion.svg"); }
.ico--water-tower       { -webkit-mask-image: url("/assets/icons/water-tower.svg");       mask-image: url("/assets/icons/water-tower.svg"); }
.ico--liberty-statue    { -webkit-mask-image: url("/assets/icons/liberty-statue.svg");    mask-image: url("/assets/icons/liberty-statue.svg"); }
.ico--tour-guide        { -webkit-mask-image: url("/assets/icons/tour-guide.svg");        mask-image: url("/assets/icons/tour-guide.svg"); }
.ico--group-tour        { -webkit-mask-image: url("/assets/icons/group-tour.svg");        mask-image: url("/assets/icons/group-tour.svg"); }

.ico--lang       { -webkit-mask-image: var(--i-globe);   mask-image: var(--i-globe); }
.ico--group      { -webkit-mask-image: var(--i-users);   mask-image: var(--i-users); }
.ico--clock      { -webkit-mask-image: var(--i-clock);   mask-image: var(--i-clock); }
.ico--peak       { -webkit-mask-image: var(--i-peak);    mask-image: var(--i-peak); }
.ico--leaf       { -webkit-mask-image: var(--i-leaf);    mask-image: var(--i-leaf); }
.ico--map        { -webkit-mask-image: var(--i-map);     mask-image: var(--i-map); }
.ico--bolt       { -webkit-mask-image: var(--i-bolt);    mask-image: var(--i-bolt); }
.ico--camera     { -webkit-mask-image: var(--i-camera);  mask-image: var(--i-camera); }
.ico--trophy     { -webkit-mask-image: var(--i-trophy);  mask-image: var(--i-trophy); }
.ico--verified   { -webkit-mask-image: var(--i-verified);mask-image: var(--i-verified); }
.ico--euro       { -webkit-mask-image: var(--i-euro);    mask-image: var(--i-euro); }
.ico--tag        { -webkit-mask-image: var(--i-tag);     mask-image: var(--i-tag); }
.ico--refresh    { -webkit-mask-image: var(--i-refresh); mask-image: var(--i-refresh); }
.ico--chat       { -webkit-mask-image: var(--i-chat);    mask-image: var(--i-chat); }
.ico--phone      { -webkit-mask-image: var(--i-phone);   mask-image: var(--i-phone); }
.ico--mail       { -webkit-mask-image: var(--i-mail);    mask-image: var(--i-mail); }
.ico--pin        { -webkit-mask-image: var(--i-pin);     mask-image: var(--i-pin); }
.ico--sun        { -webkit-mask-image: var(--i-sun);     mask-image: var(--i-sun); }
.ico--sunrise    { -webkit-mask-image: var(--i-sunrise); mask-image: var(--i-sunrise); }
.ico--moon       { -webkit-mask-image: var(--i-moon);    mask-image: var(--i-moon); }
.ico--compass    { -webkit-mask-image: var(--i-compass); mask-image: var(--i-compass); }
.ico--key        { -webkit-mask-image: var(--i-key);     mask-image: var(--i-key); }
.ico--shield     { -webkit-mask-image: var(--i-shield);  mask-image: var(--i-shield); }
.ico--receipt    { -webkit-mask-image: var(--i-receipt); mask-image: var(--i-receipt); }
.ico--user       { -webkit-mask-image: var(--i-user);    mask-image: var(--i-user); }
.ico--landmark   { -webkit-mask-image: var(--i-landmark);mask-image: var(--i-landmark); }
.ico--help       { -webkit-mask-image: var(--i-help);    mask-image: var(--i-help); }
.ico--sunset     { -webkit-mask-image: var(--i-sunset);  mask-image: var(--i-sunset); }
.ico--book       { -webkit-mask-image: var(--i-book);    mask-image: var(--i-book); }
.ico--sparkle   { -webkit-mask-image: var(--i-sparkle); mask-image: var(--i-sparkle); }
.ico--bag       { -webkit-mask-image: var(--i-bag); mask-image: var(--i-bag); }
.ico--alert     { -webkit-mask-image: var(--i-alert); mask-image: var(--i-alert); }
.ico--home      { -webkit-mask-image: var(--i-home); mask-image: var(--i-home); }
.ico--lock      { -webkit-mask-image: var(--i-lock); mask-image: var(--i-lock); }
.ico--family    { -webkit-mask-image: var(--i-family); mask-image: var(--i-family); }
.ico--hand      { -webkit-mask-image: var(--i-hand); mask-image: var(--i-hand); }
.ico--segway    { -webkit-mask-image: var(--i-segway); mask-image: var(--i-segway); }
.ico--bridge    { -webkit-mask-image: var(--i-bridge); mask-image: var(--i-bridge); }
.ico--dome      { -webkit-mask-image: var(--i-dome); mask-image: var(--i-dome); }
.ico--turret    { -webkit-mask-image: var(--i-turret); mask-image: var(--i-turret); }
.ico--wave      { -webkit-mask-image: var(--i-wave); mask-image: var(--i-wave); }
.ico--helmet    { -webkit-mask-image: var(--i-helmet); mask-image: var(--i-helmet); }
.ico--castle    { -webkit-mask-image: var(--i-castle); mask-image: var(--i-castle); }
.ico--mbike     { -webkit-mask-image: var(--i-mbike); mask-image: var(--i-mbike); }
.ico--heart      { -webkit-mask-image: var(--i-heart);   mask-image: var(--i-heart); }

/* ===== Book-direct strip =====
   Deliberately quiet. The research on premium sites is consistent: restraint
   reads as authority, and a loud "BEST PRICE!!" banner reads as a marketplace.
   So this is a plain hairline panel, one gold rule, no badges shouting. It is
   placed where a visitor is already comparing us with an OTA tab. */
.direct-strip {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  backdrop-filter: blur(6px);
  padding: 26px 28px;
  position: relative;
  overflow: hidden;
}
.direct-strip::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold) 22%, var(--gold) 78%, transparent);
}
.direct-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 20px; }
.direct-head h3 { font-size: 1.15rem; margin: 0; }
.direct-head span { font-size: 13.5px; color: var(--text-secondary); }
/* Five fixed columns above 900px, not auto-fit. auto-fit sized each column at
   a 185px minimum, which at ~1000px of container lands on FOUR columns and
   drops the fifth item onto a row of its own — the stranded "A person, not a
   ticket" line. Five explicit columns put all five points on one row, evenly
   sized, which is what the content actually is: one set of five. */
.direct-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 22px 18px; align-items: start; }
.direct-item { display: flex; gap: 10px; align-items: flex-start; min-width: 0; }
/* The old "span the orphan across the full row" workaround is gone with the
   five-column grid above — there is no orphan left to rescue. It still
   applies at the 2-column tablet layout, where 5 into 2 does leave one. */
@media (max-width: 900px) {
  .direct-item:nth-child(5):last-child { grid-column: 1 / -1; max-width: 460px; margin: 0 auto; }
}
.direct-item .ic {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 15px;
  background: var(--brand-tint); color: var(--brand-dark);
}
[data-theme="dark"] .direct-item .ic { color: var(--brand); }
.direct-item b { display: block; font-family: var(--font-head); font-size: 14.5px; margin-bottom: 3px; }
.direct-item span.t { display: block; font-size: 12.8px; color: var(--text-secondary); line-height: 1.5; }
@media (max-width: 900px) { .direct-grid { grid-template-columns: repeat(2, 1fr); gap: 18px; } }
@media (max-width: 520px) {
  .direct-grid { grid-template-columns: 1fr; gap: 16px; }
  .direct-strip { padding: 22px 20px; }
}

/* ===== Monster Bikes: tour vs rental =====
   Step one is a fork, not a field — the two products are priced and scheduled
   in completely different ways, so they get the room to explain themselves. */
.mode-cards { display: grid; gap: 12px; margin-bottom: 8px; }
.mode-cards input { position: absolute; opacity: 0; pointer-events: none; }
.mode-cards label {
  display: flex; gap: 18px; align-items: center;
  padding: 18px 20px; cursor: pointer;
  border: 1.5px solid var(--border); border-radius: var(--radius);
  background: var(--surface);
  transition: border-color .2s ease, background .2s ease, transform .12s ease;
}
.mode-cards label:hover { border-color: var(--brand); }
.mode-cards label:active { transform: scale(.995); }
.mode-cards input:checked + label {
  border-color: var(--brand); border-width: 2px; padding: 17px;
  background: color-mix(in srgb, var(--brand) 8%, var(--surface));
}
/* The traced bike marks are fine line drawings — at 26px they read as a smudge.
   They get a proper tile: 64px of icon inside a tinted square, which also gives
   the two options equal visual weight regardless of how wide each drawing is. */
.mode-cards .mc-ic {
  flex: none;
  width: 84px; height: 84px;
  display: flex; align-items: center; justify-content: center;
  font-size: 64px; line-height: 1;
  border-radius: 14px;
  background: color-mix(in srgb, var(--brand) 10%, transparent);
  color: var(--brand-dark);
}
[data-theme="dark"] .mode-cards .mc-ic { color: var(--brand); }
.mode-cards input:checked + label .mc-ic {
  background: color-mix(in srgb, var(--brand) 20%, transparent);
}
@media (max-width: 520px) {
  .mode-cards .mc-ic { width: 62px; height: 62px; font-size: 46px; border-radius: 12px; }
  .mode-cards label { gap: 14px; padding: 16px; }
}
.mode-cards .mc-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mode-cards .mc-body b { font-family: var(--font-head); font-size: 1.05rem; }
.mode-cards .mc-body span { font-size: 13.5px; color: var(--text-secondary); line-height: 1.45; }
.mode-cards .mc-from { font-weight: 700; color: var(--brand-dark); font-size: 13px !important; }
[data-theme="dark"] .mode-cards .mc-from { color: var(--brand); }

/* The three guided tours, as a vertical list of radio cards */
.opt-cards { display: grid; gap: 10px; margin-bottom: 20px; }
.opt-cards input { position: absolute; opacity: 0; pointer-events: none; }
.opt-cards label {
  display: block; position: relative;
  padding: 15px 16px; cursor: pointer;
  border: 1.5px solid var(--border); border-radius: var(--radius);
  background: var(--surface);
  transition: border-color .2s ease, background .2s ease;
}
.opt-cards label:hover { border-color: var(--brand); }
.opt-cards input:checked + label {
  border-color: var(--brand); border-width: 2px; padding: 14px 15px;
  background: color-mix(in srgb, var(--brand) 8%, var(--surface));
}
.opt-cards .oc-tag {
  position: absolute; top: -9px; right: 14px;
  background: var(--gold); color: var(--gold-contrast);
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 999px;
}
.opt-cards .oc-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.opt-cards .oc-head b { font-family: var(--font-head); font-size: 1rem; }
.opt-cards .oc-price { font-family: var(--font-head); font-weight: 700; font-size: 1.15rem; color: var(--accent); white-space: nowrap; }
.opt-cards .oc-per { font-size: 11.5px; font-weight: 400; color: var(--text-muted); }
.opt-cards .oc-blurb { display: block; font-size: 13px; color: var(--text-secondary); line-height: 1.5; margin-top: 5px; }
.opt-cards .oc-meta { display: block; font-size: 11.5px; color: var(--text-muted); margin-top: 7px; }

/* ===== Bike rental band on the homepage =====
   Deliberately a different shape from the tour cards above it: photo left, copy
   right, one row. It reads as a neighbouring business rather than a ninth tour,
   which is the point — these are two companies. */
.rent-band {
  display: grid; grid-template-columns: 0.85fr 1fr; gap: 40px; align-items: center;
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 22px;
  backdrop-filter: blur(6px);
}
.rent-photo { border-radius: 14px; overflow: hidden; aspect-ratio: 4/3; }
.rent-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rent-body { padding-right: 12px; }
.rent-body h2 { margin-bottom: 10px; }
.rent-facts { display: flex; flex-wrap: wrap; gap: 10px 22px; margin-top: 18px; }
.rent-facts span {
  font-size: 13.5px; color: var(--text-secondary);
  display: inline-flex; align-items: baseline; gap: 6px;
}
.rent-facts b { font-family: var(--font-head); font-size: 1.05rem; color: var(--accent); }
@media (max-width: 860px) {
  .rent-band { grid-template-columns: 1fr; gap: 24px; padding: 18px; }
  .rent-photo { aspect-ratio: 16/9; }
  .rent-body { padding-right: 0; }
}

/* ===== Sticky WhatsApp button ===== */
.whatsapp-float {
  position: fixed; bottom: 24px; right: 24px; z-index: 90;
  width: 58px; height: 58px; border-radius: 50%;
  background: #22B559; color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-lg); font-size: 26px;
}

/* ===== Tour detail: full-bleed hero with the key facts laid over it ===== */
.tour-hero-full {
  position: relative;
  margin-top: calc(var(--header-h) * -1);
  min-height: min(88vh, 820px);
  display: flex; align-items: flex-end;
  overflow: hidden;
  color: #fff;
}
.thf-media { position: absolute; inset: 0; }
.thf-media img { width: 100%; height: 100%; object-fit: cover; }
/* two stacked scrims: a broad floor plus a stronger pool under the text */
.thf-media::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(8,14,11,.62) 0%, rgba(8,14,11,.20) 34%, rgba(8,14,11,.72) 74%, rgba(8,14,11,.94) 100%),
    linear-gradient(90deg, rgba(8,14,11,.72) 0%, rgba(8,14,11,.15) 55%, transparent 100%);
}
.thf-inner {
  position: relative; z-index: 2;
  width: 100%;
  padding: calc(40px + var(--header-h)) 24px 52px;
  display: grid; grid-template-columns: 1fr auto; gap: 40px; align-items: end;
}
.crumb { font-size: 13px; color: rgba(255,255,255,.75); margin-bottom: 16px; }
.crumb a { color: var(--gold); }
.crumb a:hover { text-decoration: underline; }
.thf-badges { display: flex; gap: 9px; flex-wrap: wrap; margin-bottom: 14px; }
.thf-badge {
  font-size: 12.5px; font-weight: 700; padding: 7px 14px; border-radius: var(--radius-pill);
  background: rgba(255,255,255,.16); backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,.24); color: #fff;
}
.thf-badge--hot { background: var(--accent); border-color: var(--accent); }
.thf-badge--gold { background: var(--gold); border-color: var(--gold); color: var(--gold-contrast); }
.tour-hero-full h1 {
  color: #fff; max-width: 15ch; margin: 0 0 18px;
  text-shadow: 0 2px 26px rgba(0,0,0,.55);
}
.thf-sights { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.thf-sight {
  font-size: 12.5px; font-weight: 600; padding: 7px 13px; border-radius: var(--radius-pill);
  background: rgba(255,255,255,.12); backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,.18); color: rgba(255,255,255,.94);
}
.thf-price { display: flex; align-items: baseline; gap: 9px; color: rgba(255,255,255,.8); font-size: 14px; }
.thf-price b { font-family: var(--font-head); font-size: 2.6rem; color: var(--gold); line-height: 1; }

/* floating quick-info card */
.quick-card {
  width: 340px; flex: none;
  background: rgba(16,23,20,.62);
  backdrop-filter: blur(16px) saturate(150%);
  border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--radius);
  padding: 24px;
  box-shadow: 0 24px 60px rgba(0,0,0,.45);
}
.qc-title {
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 16px;
}
.qc-row {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 11px 0; border-bottom: 1px solid rgba(255,255,255,.12);
  font-size: 13.5px;
}
.qc-row:last-of-type { border-bottom: none; }
.qc-row span { color: rgba(255,255,255,.66); }
.qc-row b { color: #fff; text-align: right; font-weight: 700; }
.quick-card .btn { margin-top: 18px; }

@media (max-width: 960px) {
  .thf-inner { grid-template-columns: 1fr; gap: 26px; padding-bottom: 40px; }
  .quick-card { width: 100%; }
  .tour-hero-full { min-height: min(80vh, 700px); }
  .tour-hero-full h1 { max-width: 100%; }
}

/* ---- Phones ----
   The photo gets a real, generous height. The title block is pinned to its
   lower third, and the quick-info card rides UP over the photo's bottom edge
   so it overlaps by roughly a third — the card lifts off the image instead of
   burying it or sitting awkwardly beneath it. -------------------------- */
@media (max-width: 760px) {
  .tour-hero-full {
    --tph: max(62vh, 380px);        /* one source of truth for photo height */
    display: block;
    position: relative;
    min-height: 0;
    align-items: initial;
    color: var(--text-primary);
    overflow: visible;
  }
  .thf-media {
    position: relative; inset: auto;
    height: var(--tph);
    overflow: hidden;
    border-bottom-left-radius: 26px;
    border-bottom-right-radius: 26px;
  }
  .thf-media::after {
    border-bottom-left-radius: 26px;
    border-bottom-right-radius: 26px;
    background: linear-gradient(180deg,
      rgba(8,14,11,.50) 0%, rgba(8,14,11,.06) 30%,
      rgba(8,14,11,.42) 62%, rgba(8,14,11,.88) 100%);
  }

  .thf-inner { display: block; position: static; padding: 0 18px; }

  /* pinned to the photo, measured from the same variable */
  .thf-head {
    position: absolute;
    left: 20px; right: 20px;
    top: calc(var(--tph) - 232px);
    z-index: 3;
    color: #fff;
  }
  .thf-head .crumb { color: rgba(255,255,255,.82); margin-bottom: 10px; }
  .tour-hero-full h1 { font-size: clamp(1.85rem, 7.6vw, 2.5rem); margin-bottom: 12px; }
  .thf-sights { display: none; }                /* duplicated by the route below */
  .thf-price { margin-bottom: 0; }
  .thf-price b { font-size: 2rem; }

  /* the overlap itself */
  .quick-card {
    position: relative;
    z-index: 4;
    margin-top: -62px;
    background: var(--surface);
    border-color: var(--border);
    backdrop-filter: none;
    box-shadow: 0 18px 44px rgba(12,60,42,.22);
    color: var(--text-primary);
    padding: 20px;
  }
  .quick-card .qc-title { color: var(--brand-dark); }
  .quick-card .qc-row { border-bottom-color: var(--border); }
  .quick-card .qc-row span { color: var(--text-secondary); }
  .quick-card .qc-row b { color: var(--text-primary); }
}
[data-theme="dark"] .quick-card .qc-title { color: var(--brand); }
[data-theme="dark"] .quick-card { box-shadow: 0 18px 44px rgba(0,0,0,.55); }
@media (max-width: 400px) {
  .tour-hero-full { --tph: max(56vh, 330px); }
  .thf-head { top: calc(var(--tph) - 210px); left: 16px; right: 16px; }
  .thf-inner { padding: 0 14px; }
  .quick-card { margin-top: -52px; }
  .qc-row { font-size: 12.5px; }
}

/* legacy inline hero (unused on tour pages now) */
.tour-hero { position: relative; border-radius: var(--radius); overflow: hidden; aspect-ratio: 16/8; margin-bottom: 40px; }
.tour-hero img { width: 100%; height: 100%; object-fit: cover; }
.detail-grid { display: grid; grid-template-columns: 1.5fr 1fr; gap: 56px; align-items: start; }
.quick-facts { display: grid; grid-template-columns: repeat(2,1fr); gap: 16px; margin-bottom: 28px; }
.quick-fact { background: var(--surface-alt); border-radius: var(--radius-sm); padding: 16px 18px; }
.quick-fact span { display: block; font-size: 12px; color: var(--text-muted); margin-bottom: 5px; }
.quick-fact b { font-family: var(--font-head); font-size: 1.1rem; }
.sights-row { display: flex; flex-wrap: wrap; gap: 9px; margin: 14px 0 28px; }
.accordion-item { border-bottom: 1px solid var(--border); padding: 18px 0; }
.accordion-item summary { font-weight: 700; cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; }
.accordion-item summary::-webkit-details-marker { display: none; }
.sticky-col { position: sticky; top: calc(var(--header-h) + 24px); }
.related-row { display: grid; grid-template-columns: repeat(3,1fr); gap: 24px; margin-top: 24px; align-items: stretch; }

/* ===== Utility ===== */
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.grid-3 { display: grid; grid-template-columns: repeat(3,1fr); gap: 24px; }
.badge-soft { display: inline-block; background: var(--brand-tint); color: var(--brand-dark); font-size: 12px; font-weight: 700; padding: 6px 14px; border-radius: var(--radius-pill); }
[data-theme="dark"] .badge-soft { color: var(--brand); }

/* ===== Responsive ===== */
@media (max-width: 1280px) {
  .container-wide { max-width: 100%; padding: 0 28px; }
}
/* Rail drops out of the corner and becomes a compact row under the hero copy */
@media (max-width: 1150px) {
  .hero { flex-direction: column; justify-content: center; }
  .hero-content { order: 1; }
  .hero-media img,
  .hero-media video { object-position: 50% 42%; }   /* keep the subject, crop sky */
  /* Two shared row tracks, not four independent columns. Every .num lands in
     row 1 and every .label in row 2 — enforced by the grid itself, so the
     numbers CANNOT sit at different heights no matter how long a label is,
     how wide its column is, or what glyphs it contains. The previous flex
     version gave each item its own independent box, so any difference in
     content height (a wrapped label, different glyph metrics) shifted that
     one item's number off the shared line — which is the bug that kept
     coming back. display:contents dissolves the wrapper so .num/.label
     become direct grid children and can be assigned to those tracks. */
  .hero-rail {
    order: 2;
    position: static;
    transform: none;
    display: grid;
    grid-template-rows: auto auto;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    align-items: center;
    justify-items: center;
    width: auto;
    max-width: min(100%, 680px);
    margin: 0 auto 8px;
    gap: 6px 24px;
    padding: 16px 20px;
    /* Denser plate than on desktop: as a wide row it lands on whatever the
       footage is doing at that height, and at 40% it washed out completely. */
    background: rgba(8,14,11,.62);
    border-color: rgba(255,255,255,.20);
  }
  .hero-rail .credibility-item { display: contents; }
  /* No entrance fade on these two, deliberately. The wrapper used to carry it,
     but the wrapper has no box now — and moving `opacity:0 + animation` onto
     .num is a trap: main.js adds a `.glow` class to each stat once its
     count-up finishes, and `.credibility-item.glow .num` sets its own
     `animation: glowPulse`, which REPLACES the entrance animation. The
     forwards-fill that was holding opacity at 1 disappears with it, the
     element falls back to the declared `opacity: 0`, and every number
     vanishes the moment it finishes counting. The count-up itself is the
     entrance effect here, so there is nothing to add. */
  .hero-rail .num,
  .hero-rail .label { opacity: 1; animation: none; }
  .hero-rail .num { grid-row: 1; font-size: 1.5rem; margin: 0; text-align: center; }
  .hero-rail .label { grid-row: 2; margin: 0; text-align: center; }
  /* Restored after the blanket `animation: none` above, so the 5.0★ stat keeps
     its pulse. It sets no opacity, which is safe now nothing declares 0. */
  .hero-rail .credibility-item.glow .num { animation: glowPulse 3s ease-in-out infinite; }
}
@keyframes railInUp {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (max-width: 560px) {
  /* Scaled back up. At 7.4vw the headline was ~36px on a 390px phone — small
     enough that the whole hero read as a stray label on a photo. 11.5vw gives
     it the presence the format needs, and it still breaks to a clean two lines
     ("You Segway" / "Budapest") both before and after the dots collapse. */
  .hero-content h1 { font-size: clamp(2.05rem, 11.5vw, 2.9rem); letter-spacing: -0.035em; line-height: 1.06; }
  .hero-tagline { font-size: 1.02rem; max-width: 28ch; margin-bottom: 36px; opacity: .94; }
  .hero-cta { gap: 10px; }
  .hero-cta .btn { padding: 15px 24px; font-size: 15px; }
  .wa-long { display: none; }            /* "Book via WhatsApp" -> "WhatsApp" */

  /* Stats span the full width as four equal columns — the boxed 2x2 read as
     a stubby off-centre slab. Fixed columns also mean the counting numbers
     cannot nudge each other around while they animate. */
  /* .hero prefix is deliberate: the ≤980px block further down sets a margin on
     a bare .hero-rail, and being later in the file it would otherwise win here. */
  /* Keeps the two shared row tracks from the ≤1150 block above (numbers in
     row 1, labels in row 2 — see that comment for why). Only the column
     sizing and plate styling change here: four fixed equal columns spanning
     the full width. */
  .hero .hero-rail {
    grid-auto-flow: row;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: auto auto;
    gap: 4px 0;
    width: 100%;
    max-width: none;
    margin: 0 0 4vh;
    /* Feathered plate rather than none: a boxed panel looked stubby here, but
       with no plate at all the row vanished on dark frames. This darkens the
       band without drawing an edge anywhere. */
    background: linear-gradient(180deg,
      rgba(8,14,11,0) 0%, rgba(8,14,11,.46) 20%,
      rgba(8,14,11,.46) 80%, rgba(8,14,11,0) 100%);
    padding: 18px 0;
    border: none;
    box-shadow: none;
    backdrop-filter: none;
  }
  /* Each stat occupies the same column in both rows, so number and label stay
     paired while every number still shares one track. */
  .hero-rail .credibility-item:nth-child(1) .num,
  .hero-rail .credibility-item:nth-child(1) .label { grid-column: 1; }
  .hero-rail .credibility-item:nth-child(2) .num,
  .hero-rail .credibility-item:nth-child(2) .label { grid-column: 2; }
  .hero-rail .credibility-item:nth-child(3) .num,
  .hero-rail .credibility-item:nth-child(3) .label { grid-column: 3; }
  .hero-rail .credibility-item:nth-child(4) .num,
  .hero-rail .credibility-item:nth-child(4) .label { grid-column: 4; }
  .hero-rail .num { font-size: 1.3rem; letter-spacing: -0.04em; }
  .hero-rail .label {
    font-size: 10.5px; line-height: 1.3;
    color: rgba(255,255,255,.86); letter-spacing: .01em; white-space: nowrap;
  }
}
/* very small / short screens: drop the tagline rather than squeeze everything */
/* Short screens only. This used to fire at max-width:400px too, which meant a
   393px iPhone 15 lost its tagline — and once the hero grew, that left a 300px
   hole in the middle of it. Narrow is not the same problem as short. */
@media (max-height: 680px) and (max-width: 980px) {
  .hero-tagline { display: none; }
  .hero .hero-rail { margin: 0 0 3vh; }
  .hero-content h1 { font-size: clamp(1.85rem, 10.5vw, 2.35rem); }
}
/* Narrower than any current iPhone — foldable cover screens, old Androids. */
@media (max-width: 360px) {
  .hero-content h1 { font-size: clamp(1.75rem, 10.8vw, 2.1rem); }
  .hero-tagline { font-size: .95rem; margin-bottom: 30px; }
  .hero-cta .btn { padding: 14px 20px; font-size: 14.5px; }
}
/* Short viewports of any width — laptop in split screen, phone in landscape,
   a 1276x500 window. The hero used to claim 94vh of a 500px screen and then
   overflow it, so nothing below the headline had room. Here it sizes to its
   own content instead and every gap tightens. */
@media (max-height: 620px) {
  .hero { min-height: 0; }
  .hero-content { padding: calc(18px + var(--header-h)) 0 18px; }
  .hero-content h1 { font-size: clamp(1.5rem, 4.4vw, 2.4rem); margin-bottom: 10px; }
  .hero-tagline { margin-bottom: 18px; font-size: .95rem; }
  .hero-cta .btn { padding: 11px 18px; font-size: 13.5px; }
  .hero .hero-rail { margin: 22px auto 0; padding: 10px 16px; gap: 8px 22px; }
  .hero-rail .num { font-size: 1.15rem; }
  .hero-rail .label { font-size: 10px; margin-top: 2px; }
}
@media (max-height: 500px) {
  .hero-tagline { display: none; }
  .hero .hero-rail { margin-top: 16px; }
}
/* Below ~1240 four across squeezes each card under 280px — go two-up instead
   (covers iPad landscape at 1180 and 11" tablets). */
@media (max-width: 1240px) {
  .tour-grid-4 { grid-template-columns: repeat(2,1fr); }
}
@media (max-width: 960px) {
  .related-row { grid-template-columns: repeat(2,1fr); }
  .split, .detail-grid, .mb-grid { grid-template-columns: 1fr; gap: 32px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .pricing-grid { grid-template-columns: 1fr; }
  .feature-grid { grid-template-columns: repeat(2,1fr); }
  .testimonial-grid { grid-template-columns: repeat(2,1fr); }
  h2 { max-width: none; }
  .credibility-bar { gap: 36px; }
  /* once the detail page is single-column the sidebar must stop sticking */
  .sticky-col { position: static; top: auto; }
}
/* Five nav items + logo + two buttons stop fitting well before 680px —
   switch to the hamburger at 980 instead of letting them collide. */
/* Raised from 980 to 1150: the sixth link (Bike rental) pushes the row to about
   1090px of chrome, which no longer clears a 1024 or 1100 viewport. Better to
   hand over to the hamburger early than to let the logo and the nav collide. */
@media (max-width: 1150px) {
  .nav-links { display: none; }
  .hamburger { display: flex; }
  .site-header .container { gap: 14px; }
}
@media (max-width: 980px) {
  /* Once the header is genuinely touch-only, its three controls have to clear
     Apple's 44px minimum target. They were 42, 42 and ~37. */
  .hamburger, .theme-toggle { width: 44px; height: 44px; }
  .btn-sm { padding: 13px 18px; font-size: 13.5px; }
}
@media (max-width: 680px) {
  /* One lead colour only on phone, not a blend of two or three. On a narrow
     viewport the blobs' vw-sized radii and vw/vh offsets stop overlapping
     smoothly the way they do on desktop — they read instead as separate
     coloured patches sitting side by side, most visible right where the
     hero fades into the page. Forcing a2/a3/a4 off (regardless of what the
     scroll crossfade in main.js computes for them) leaves only a1's single
     brand-teal wash — calmer, and reads as one deliberate colour instead of
     an accidental collision of several. */
  .aurora-bg .a2, .aurora-bg .a3, .aurora-bg .a4 { opacity: 0 !important; }
  .related-row, .grid-3, .mb-rental-grid, .tour-grid-4, .feature-grid, .testimonial-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; }
  .quick-facts { grid-template-columns: 1fr; }
  .section { padding: 56px 0; }
  .container, .container-wide { padding: 0 20px; }
  /* 94svh + space-between was still too tall once real content (headline +
     tagline + two buttons + stat rail) is this compact on a phone — it just
     relocated the dead air into one big band of bare photo between the CTA
     buttons and the stat rail instead of removing it. Sizing the hero to its
     own content (no forced min-height, no space-between stretch) removes
     that gap outright instead of redistributing it.
     padding-top as a longhand, deliberately: a `padding: X 0 0` shorthand
     also zeroes the 20px side padding this element inherits from .container. */
  /* Owner asked for a longer hero on phones: more of the city photo below the
     content. justify-content is flex-start here, so every extra pixel lands
     BELOW the stat rail — this cannot bring back the old space-between dead-air
     band between the CTA buttons and the rail, which is what the note above
     was about. min-height (not a fixed height) so a phone with tall content
     still grows past it instead of clipping.
     Two lines: the plain vh value is the old-TV fallback (svh needs Chrome 108). */
  /* This value has now been moved three times — 94svh → 78svh → 60svh → 85svh —
     because "too long" and "too short" were about DIFFERENT things and the
     history is worth keeping straight before anyone changes it again:
       - 94svh + space-between was wrong because the extra height was injected
         as dead air BETWEEN the CTA buttons and the stat rail. That is fixed
         structurally (justify-content: flex-start), not by the height.
       - 60svh was an over-correction: with flex-start every extra pixel lands
         BELOW the rail as more city photo, which is the part the owner wants.
     85svh is the owner's marked-up target (2026-08-15, iPhone 17 Air): photo
     continues well past the stat rail before the page turns over. It cannot
     bring the old dead-air band back — flex-start guarantees the slack goes to
     the bottom. min-height, so taller content still grows past it. */
  /* `center`, NOT `space-between`. Those are not the same thing and confusing
     them is what caused the original dead-air bug: space-between pushes the
     hero's two children (content block, stat rail) apart and dumps all the
     slack BETWEEN them. `center` keeps the two children packed together and
     centres the whole group as a unit, so the slack is split above and below
     it — which is what "move the text more into the middle" means. If a phone's
     content is ever taller than the box, min-height lets it grow instead of
     clipping, and .hero-content keeps its header-clearing padding-top so the
     headline can never slide under the fixed header. */
  .hero { min-height: 85vh; min-height: 85svh; justify-content: center; }
  .hero-content {
    flex: none;
    padding-top: calc(24px + var(--header-h));
    padding-bottom: 0;
    margin-top: 0;
    margin-bottom: 28px;
  }
  .hero-content h1 { max-width: 100%; margin-bottom: 20px; }
  /* Buttons stay on one line, sized to their content and centred — full-width
     stacked bars read as an old mobile template. Scoped to the homepage hero
     only: the bike-rental "guided tour instead" strip reuses .hero-cta with
     long labels that overflow off-screen if forced onto one nowrap line. */
  .hero-content .hero-cta { flex-direction: row; flex-wrap: nowrap; justify-content: center; gap: 10px; }
  .hero-content .hero-cta .btn { flex: 0 1 auto; width: auto; white-space: nowrap; }
  /* The bike-rental "guided tour instead" strip's long WhatsApp label wraps to
     its own row on phone width no matter what, which the base .hero-cta's
     flex-start left the second button hugging the left edge under it —
     visibly off-centre next to the paragraph above. Full-width + stacked +
     centred reads as one deliberate pair instead of a wrap accident. */
  .direct-strip .hero-cta { flex-direction: column; align-items: stretch; justify-content: center; gap: 16px; }
  /* Base .hero-cta > * + * (unscoped, above) puts a 14px LEFT margin on the
     second button — meant for the row layout. In this column layout that
     margin doesn't add vertical space, it just shoves the full-width button
     14px off-centre to the right. Cancel it; `gap` on the flex column above
     already does the actual spacing job. */
  .direct-strip .hero-cta > * + * { margin-left: 0; }
  .direct-strip .hero-cta .btn { width: 100%; justify-content: center; text-align: center; }
  /* space-between already pushes the rail down; this just lifts it off the edge */
  .hero-rail { margin: 0 auto 4vh; }
  .about-badge-row { gap: 16px; }
  .credibility-bar { gap: 26px 30px; }
  .credibility-item { min-width: 110px; flex: 1 1 40%; }
  .booking-widget, .card, .mb-rental-card, .feature-card, .testimonial-card { padding: 22px 18px; }
  .segmented { grid-template-columns: 1fr; }
  .booking-actions { flex-direction: column; }
  .booking-actions .btn { width: 100%; }
  .marquee-track span { font-size: .95rem; }
  .about-quote p { font-size: 1.15rem; }
  .footer-bottom { flex-direction: column; }
  .tour-hero { aspect-ratio: 4/3; }
  .matcher-nav { flex-wrap: wrap; }
}
/* Step rail: drop the wordy labels, keep the numbered dots */
@media (max-width: 560px) {
  .booking-steps { gap: 8px; }
  .booking-step { font-size: 11.5px; }
  .booking-step .s-label { display: none; }
}
/* iPhone SE / 5s territory */
@media (max-width: 400px) {
  .container, .container-wide { padding: 0 16px; }
  .quick-facts { grid-template-columns: 1fr; }
  .credibility-item { flex: 1 1 100%; }
  .matcher { padding: 22px 16px 20px; }
  .booking-widget { padding: 20px 14px; }
  .badge-price, .badge-popular { font-size: 11.5px; padding: 5px 10px; }
  .badge-rating-card { font-size: 11px; padding: 5px 10px; }
  .tag-pill { font-size: 11.5px; padding: 5px 11px; }
  .btn { padding: 13px 20px; font-size: 14.5px; }
  .pill-options label { padding: 9px 13px; font-size: 12.5px; }
  .field-input { font-size: 16px; }  /* 16px stops iOS zooming the page on focus */
  .logo { font-size: 17px; }
  .logo img { width: 30px; height: 30px; }
}

/* ===== Large displays: let the layout breathe on 1440p / 4K ===== */
@media (min-width: 1900px) {
  .container { max-width: 1360px; }
  .container-wide { max-width: 1840px; }
  .hero-rail { width: clamp(200px, 12vw, 250px); }
}
@media (min-width: 2500px) {
  .container { max-width: 1500px; }
  .container-wide { max-width: 2100px; }
  html { font-size: 18px; }          /* everything scales via rem */
}
/* Large TVs / true 4K panels (e.g. a 65" screen running the site as lobby
   signage at 3840px wide). Without this the content sits as a narrow ~1500px
   column marooned in the middle. Widen the shell and scale type up via rem so
   it reads as a full-screen showcase, keeping a comfortable side margin. */
@media (min-width: 3200px) {
  .container { max-width: 1900px; }
  .container-wide { max-width: 2800px; }
  html { font-size: 24px; }
  .hero-rail { width: clamp(260px, 12vw, 340px); }
}
/* Tall screens (4K/portrait monitors): let the hero fill more of the view */
@media (min-height: 1100px) and (min-width: 1200px) {
  .hero { min-height: min(86vh, 1120px); }
}

/* ===== Mobile nav drawer ===== */
.mobile-nav {
  position: fixed; inset: 0; z-index: 1000;   /* above every other fixed layer */
  background: var(--bg);
  display: none;
  flex-direction: column;
  padding: 24px;
  pointer-events: auto;
  overflow-y: auto;
  overscroll-behavior: contain;   /* swiping the drawer must not move the page */
  -webkit-overflow-scrolling: touch;
}
.mobile-nav.open { display: flex; }
/* Freeze the page underneath while the drawer is open. Without this, a swipe
   anywhere on the drawer scrolled the real page behind it. */
html.nav-open, html.nav-open body { overflow: hidden; overscroll-behavior: none; }
.mobile-nav .close-row { display: flex; justify-content: flex-end; margin-bottom: 32px; }
/* Own styles — it used to borrow .theme-toggle, which meant closing the menu
   also flipped the colour scheme. */
.mobile-nav-close {
  width: 48px; height: 48px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text-primary); font-size: 19px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  touch-action: manipulation;       /* no 300ms delay / double-tap zoom */
  -webkit-tap-highlight-color: transparent;
  position: relative; z-index: 1;
}
.mobile-nav-close:active { transform: scale(.92); background: var(--surface-alt); }
.mobile-nav-close:hover { border-color: var(--brand); }
.mobile-nav a {
  font-family: var(--font-head); font-size: 1.6rem; font-weight: 700;
  padding: 14px 0; border-bottom: 1px solid var(--border);
  position: relative; z-index: 1;
  touch-action: manipulation;
  -webkit-tap-highlight-color: color-mix(in srgb, var(--brand) 20%, transparent);
}
.mobile-nav a:active { color: var(--brand); }

/* ==========================================================
   Tour photo gallery — adaptive viewer
   Earlier passes forced every guest photo (mixed portrait and
   landscape) into one fixed-aspect box: cover cropped people
   out, contain left big empty bars. Fixing the real cause
   instead of the symptom: the frame has a fixed HEIGHT only,
   width follows each photo's own ratio, so every photo fills
   the space correctly with no crop and no dead bars. Clean
   card, no props (no tape/pins/confetti) — those only fought
   the varying photo shapes. Fully theme-aware.
   ========================================================== */
.snap { margin-top: 36px; }
.snap-stage {
  display: flex; align-items: center; justify-content: center; gap: 14px;
  padding: 0 8px;
}
.snap-viewer {
  position: relative; margin: 0;
  height: min(56vh, 460px);
  max-width: min(88vw, 760px);
  border-radius: 14px; overflow: hidden;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  box-shadow: 0 20px 44px -20px rgba(0,0,0,.3), 0 2px 10px -2px rgba(0,0,0,.1);
}
.snap-img {
  display: block; height: 100%; width: auto; max-width: 100%;
  object-fit: contain;
  opacity: 1; transform: scale(1);
  transition: opacity .28s ease, transform .35s cubic-bezier(.22,.9,.35,1);
}
.snap-img.is-swapping { opacity: 0; transform: scale(.98); }
@media (prefers-reduced-motion: reduce) {
  .snap-img { transition: opacity .2s ease; transform: none; }
  .snap-img.is-swapping { transform: none; }
}
.snap-tag {
  position: absolute; left: 12px; bottom: 12px; z-index: 1;
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-head); font-size: 13px; font-weight: 700;
  color: #fff; letter-spacing: .01em;
  padding: 7px 13px 7px 11px; border-radius: var(--radius-pill);
  background: rgba(10,16,13,.55); backdrop-filter: blur(3px);
  max-width: calc(100% - 24px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.snap-tag::before {
  content: ''; display: inline-block; width: .9em; height: .9em; flex: none;
  background-color: var(--gold, #EBA92C);
  -webkit-mask: var(--i-pin) center / contain no-repeat;
          mask: var(--i-pin) center / contain no-repeat;
}
.snap-arrow {
  flex: none; width: 44px; height: 44px; border-radius: 50%; z-index: 2;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-primary);
  font-size: 22px; line-height: 1; cursor: pointer;
  display: grid; place-items: center;
  box-shadow: 0 6px 16px -6px rgba(0,0,0,.18);
  transition: background .15s, border-color .15s, transform .15s;
}
.snap-arrow:hover { background: var(--brand); border-color: var(--brand); color: #fff; transform: scale(1.08); }

.snap-strip {
  display: flex; flex-wrap: nowrap; gap: 10px;
  max-width: 900px; margin: 22px auto 0;
  padding: 4px max(20px, calc((100vw - 900px) / 2)) 6px;
  overflow-x: auto; scrollbar-width: none;
}
.snap-strip::-webkit-scrollbar { display: none; }
.snap-thumb {
  flex: 0 0 auto; width: 64px; height: 64px; padding: 0; margin: 0;
  border-radius: 8px; overflow: hidden; cursor: pointer;
  border: 2px solid transparent;
  opacity: .55; filter: saturate(.8);
  transition: opacity .2s, filter .2s, border-color .2s, transform .2s;
}
.snap-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.snap-thumb:hover { opacity: .85; }
.snap-thumb.is-active {
  opacity: 1; filter: saturate(1);
  border-color: var(--brand); transform: translateY(-3px);
  box-shadow: 0 8px 18px -8px color-mix(in srgb, var(--brand) 55%, transparent);
}
@media (max-width: 640px) {
  .snap-viewer { height: min(50vh, 380px); }
  .snap-arrow { width: 38px; height: 38px; font-size: 18px; }
  .snap-thumb { width: 52px; height: 52px; }
}
/* ── Cookie consent banner ─────────────────────────────────────────────── */
.cookie-bar {
  position: fixed; z-index: 200; left: 50%; bottom: 22px;
  transform: translateX(-50%) translateY(140%);
  width: min(720px, calc(100vw - 32px));
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 18px 22px;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  border: 1px solid color-mix(in srgb, var(--gold) 30%, var(--border));
  border-radius: var(--radius);
  box-shadow: 0 26px 60px -28px color-mix(in srgb, var(--brand) 70%, black);
  backdrop-filter: blur(12px);
  opacity: 0; visibility: hidden;
  transition: transform .45s cubic-bezier(.2,.9,.3,1), opacity .35s ease, visibility .35s;
}
.cookie-bar.show { transform: translateX(-50%) translateY(0); opacity: 1; visibility: visible; }
.cookie-bar .cookie-text { flex: 1 1 300px; font-size: 13.5px; line-height: 1.55; color: var(--text-secondary); }
.cookie-bar .cookie-text strong { color: var(--text-primary); font-family: "Space Grotesk", sans-serif; }
.cookie-bar .cookie-text a { color: var(--brand-dark); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
[data-theme="dark"] .cookie-bar .cookie-text a { color: var(--brand); }
.cookie-bar .cookie-actions { display: flex; gap: 10px; flex: 0 0 auto; }
.cookie-bar .cookie-actions .btn { padding: 11px 20px; font-size: 13.5px; }
@media (max-width: 560px) {
  .cookie-bar { flex-direction: column; align-items: stretch; gap: 16px; bottom: 12px; padding: 16px 18px; }
  /* In a column flex box, flex-basis is the MAIN axis = height. The base
     `flex: 1 1 300px` on .cookie-text forced a ~300px tall empty box. Reset it. */
  .cookie-bar .cookie-text { flex: 0 0 auto; }
  .cookie-bar .cookie-actions { justify-content: stretch; }
  .cookie-bar .cookie-actions .btn { flex: 1; }
}

/* ==========================================================================
   LIGHT THEME, PHONE/TABLET — the stat rail must not read as a separate box.
   Reported 2026-08-15 (iPhone 17 Air, light): the rail looked like a grey-green
   slab pasted onto the photo, its colour matching neither the hero above it nor
   the mint page below. Cause: at ≤1150px the rail is a solid plate
   (rgba(8,14,11,.62) + 1px light border + radius). On a dark photo in dark
   theme that plate is invisible as an object; in LIGHT theme it lands right
   where the hero is already fading toward the pale --bg, so a hard-edged dark
   rounded rectangle sits in the middle of the transition and reads as debris.
   Fix, light theme only: same treatment the ≤560px block already uses — a
   feathered full-bleed band with no edge anywhere (no border, no radius, no
   shadow). It still darkens the strip enough to keep the numbers legible, but
   it has no boundary to mismatch against. Dark theme is deliberately untouched.
   Placed at the end of the file on purpose: these media blocks are ordered by
   breakpoint, so a later rule of equal specificity wins (see "CSS cascade, not
   specificity" in CLAUDE.md).
   ========================================================================== */
/* ==========================================================================
   LIGHT THEME, PHONE + TABLET — the stat rail as a light CARD.
   Desktop (>1150px) is untouched: there the rail is a narrow glass sidebar
   docked in the corner of a dark photo, which works and is not this problem.

   Four earlier attempts and why each failed — do not re-try any of them:
     1. Dark solid plate (the base style): a hard dark rectangle in the middle
        of the hero's fade to pale --bg. Belonged to neither side.
     2. Feathered dark band: painted inside the element, so it kept the base
        border-radius and read as a soft dark rounded slab (the "strange box
        shadow" on iPad).
     3. No background + dark ink: the backdrop is LIVE VIDEO, dark pavement one
        second and pale veil the next; dark ink died on the dark frames.
     4. No background + mid-tone ink + black aura: legible, but naked type
        floating over a photo has no relationship to the section it sits in.

   The mistake in all four was treating this as a contrast problem. It is a
   COMPOSITION problem: a dark glass panel is dark-theme furniture, and in light
   theme it has nothing to belong to. So the rail now becomes what every other
   surface in light theme already is — a white frosted card with soft elevation
   and dark text. A white card over photography is legible at any backdrop
   luminance (that is why the cookie banner and the award cards work), and it
   ties the hero to the pale section beneath it instead of fighting it.

   Type is the page palette, the same colours the on-page stats use, so the
   numbers keep their four identities while reading as ink on a light surface.
   No text-shadow at all — on an opaque surface a halo is just grime.

   PAINT ONLY. Nothing here changes size, padding, border-width or position:
   the theme toggle must never move the box (that bug shipped once already).
   ========================================================================== */
@media (max-width: 1150px) {
  /* Not flat white — a white card on a pale-mint page is the one surface that
     belongs to nothing: it reads as a browser default pasted over the photo.
     The card is now tinted with the page's own pastels (kinari white ->
     --brand-tint mint -> --indigo-tint), the same two hues the stat ink uses,
     so it reads as a piece of the light section that drifted up onto the hero.
     Alpha stays high (.88-.94) so the ink keeps an opaque ground and needs no
     text-shadow, and the tints are pale enough that --brand-dark still clears
     ~6:1 on the darkest stop. Gradient only, never gradient + background-color
     (see the .hero::after note — a transparent stop does not hide a colour
     underneath it). */
  [data-theme="light"] .hero .hero-rail {
    background: linear-gradient(140deg,
      rgba(252,255,253,.94) 0%,
      rgba(225,241,234,.90) 48%,
      rgba(227,239,244,.88) 100%);
    -webkit-backdrop-filter: blur(18px) saturate(150%);
    backdrop-filter: blur(18px) saturate(150%);
    border-color: rgba(126,190,165,.45);   /* celadon edge, not white-on-white */
    /* The reported "white line under the 10+ box" was THIS, not the hero fade.
       Proven with marker rows injected into the live DOM at 393x852: the hero
       veil is already flat --bg from y=493 and the card's bottom edge is at
       y=514, so the ~45px dark band under the card sat entirely inside a region
       the fade had already finished. It was the elevation shadow: an 18px
       offset with a 40px blur throws dark green roughly 58px below the box.
       That reads as depth when the card floats on dark photography; now that
       the fade lands before the card, the shadow falls on pale page colour and
       the eye reads a dirty band with two edges — exactly the "line".
       Tight and faint instead: enough lift to separate the card from the photo
       above it, too short and too weak to form a band below it.
       RULE: on a pale ground, a large offset+blur elevation shadow IS a visible
       band. Shadow size has to be judged against what it falls ON, not against
       the element casting it. */
    box-shadow:
      0 4px 12px rgba(10,38,26,.07),
      0 1px 3px rgba(10,38,26,.05),
      inset 0 1px 0 rgba(255,255,255,.85);
  }
  [data-theme="light"] .hero-rail .credibility-item:nth-child(1) .num { color: var(--brand-dark); }
  [data-theme="light"] .hero-rail .credibility-item:nth-child(2) .num { color: var(--indigo); }
  [data-theme="light"] .hero-rail .credibility-item:nth-child(3) .num { color: #B07A0E; }
  [data-theme="light"] .hero-rail .credibility-item:nth-child(4) .num { color: var(--accent); }
  [data-theme="light"] .hero-rail .num { text-shadow: none; }
  [data-theme="light"] .hero-rail .credibility-item .label {
    color: var(--text-secondary);
    text-shadow: none;
  }
}
/* At ≤560px the rail is already full-bleed (see that block above), so the
   inherited 18px radius gets clipped by the screen edges and reads as broken
   corners rather than a card. Squared off, it becomes a deliberate full-width
   stat strip — which also does useful work compositionally: a solid white band
   under the CTAs is the first piece of the light section, so the hero resolves
   INTO the page instead of stopping at an arbitrary line.
   border-radius is safe to theme-scope: unlike width/padding/border-width it
   does not participate in the box model, so it cannot shift layout on toggle. */
/* ≤560px: the rail must be an INSET CARD, not a full-bleed strip.
   The full-bleed version (and the squared-off white strip built on top of it)
   cut the hero into three horizontal slabs — photo, band, photo — because the
   hero continues BELOW the rail; a band only reads as a section boundary if it
   is actually at the boundary, and this one is not. Inset with side margins and
   the standard radius, it reads as a card floating on the photo, which is what
   it is.
   THEME-NEUTRAL on purpose: geometry lives here, in a rule with no
   `[data-theme]` in the selector, so light and dark measure identically and the
   toggle cannot shift it. Dark keeps its feathered gradient — that gradient
   fades to transparent top and bottom, so it simply renders inside the narrower
   box; the rounded corners never show. Only the paint differs per theme.
   Padding is trimmed to 12px sides because 32px of margin has to come from
   somewhere and the four columns are tight at 360px. */
@media (max-width: 560px) {
  .hero .hero-rail {
    width: auto;
    max-width: none;
    /* 4vh below the rail on top of the hero's own tail double-counted the same
       gap; 2vh is enough to detach the card from the section edge. */
    margin: 0 14px 2vh;
    padding: 14px 12px;
    /* The ≤560 block sets `gap: 4px 0` — fine when the rail was full-bleed and
       each 1fr column had room to spare, but once 28px of margin and the side
       padding come out of a 360px screen the labels run into each other
       ("Years guidingHappy riders"). A small column gap restores the visual
       separation between stats. */
    gap: 4px 8px;
  }
  /* THIS is the rule that produced the reported "white line under the 10+ box"
     on phones — not the hero fade, and not the ≤680 rule above (which restates
     the same shadow and is overridden here by source order, the cascade trap
     this file documents elsewhere: equal specificity means LAST wins).
     Proven, not guessed: marker rows injected into the live DOM at 393x852 put
     the hero veil at flat --bg from y=493 and the card's bottom edge at y=514,
     so the ~45px dark band under the card lay entirely in a region where the
     fade had already finished. The only thing painting there was this shadow —
     a 14px offset with a 34px blur throws dark green ~48px below the box.
     Against dark photography that reads as elevation; against the pale page
     colour the fade now lands on, it reads as a dirty band with two edges.
     Tight and faint instead — the card still lifts off the photo above it, but
     nothing extends far enough below to form a band. */
  [data-theme="light"] .hero .hero-rail {
    box-shadow: 0 1px 3px rgba(10,38,26,.05);
  }
  /* DARK, phones: solid plate, same as tablet/desktop. The feathered gradient
     (fading to transparent top and bottom) was designed for the FULL-BLEED
     rail, where a hard edge would have cut across the whole screen. Since v=82
     the rail is an inset card with margins and a radius, so the feather has
     nothing to hide from — it just makes the card look half-erased at top and
     bottom while its side edges stay crisp. A flat fill matches the ≤1150px
     plate and reads as one object.
     PAINT ONLY: background / backdrop-filter / box-shadow. Geometry (width,
     margin, padding, gap, border-width) stays in the theme-neutral rule above
     so the toggle cannot move the box. */
  [data-theme="dark"] .hero .hero-rail {
    background: rgba(8,14,11,.62);
    -webkit-backdrop-filter: blur(14px) saturate(150%);
    backdrop-filter: blur(14px) saturate(150%);
    box-shadow: 0 14px 34px rgba(0,0,0,.42);
  }
}

/* ==========================================================================
   PHONE HERO — fill the screen, and spread the content through it.
   Owner asked for the hero ~20% longer and for the gaps between the text
   blocks to cover the whole section rather than bunching in the middle.
   min-height is 100svh: exactly the phone's visible height (svh = the
   toolbar-visible state, so it cannot overflow behind Safari's chrome the way
   100vh does). Going beyond 100 would push the stat rail off-screen on first
   paint, which loses the credibility numbers at the moment they matter most.
   The extra room is spent on the INTERNAL rhythm (headline → tagline → buttons
   → rail), NOT on justify-content: space-between. That distinction is the one
   this file keeps coming back to: space-between splits the hero's two children
   apart and dumps every spare pixel into a single band of bare photo between
   the buttons and the rail — the dead-air bug. Growing the individual margins
   distributes the same space across four boundaries instead of one, which is
   what "spacing from text to text covering the section" actually means.
   ========================================================================== */
/* Tightened 2026-08-15: 100svh put the rail near the middle of a full-screen
   hero and left the whole bottom third as bare photo before "Recognition" —
   read as one huge gap between blocks. 72svh keeps a clear photo band under
   the rail (which is what the "longer hero" request was actually about)
   without the empty tail, and the internal rhythm comes down with it so the
   ratio between the gaps stays the same at every phone size. svh, not vh, so
   Safari's toolbar cannot push it. */
@media (max-width: 680px) {
  .hero { min-height: 72vh; min-height: 72svh; }
  .hero-content h1 { margin-bottom: 20px; }
  .hero-tagline { margin-bottom: 34px; }
  .hero-content { margin-bottom: 34px; }
  /* The section right after the hero starts closer, so the seam reads as one
     transition rather than photo → void → heading. */
  .hero + .section-tight { padding-top: 36px; }
  /* Rail sits LOWER in the hero, closer to "Recognition". The hero is centred,
     so growing the group's top margin and dropping its bottom one moves the
     rail down by half the added amount and takes the rest out of the tail —
     without switching to justify-content: space-between, which is what dumps
     every spare pixel into one band between the buttons and the rail (the
     dead-air bug this file keeps relearning).
     LONGHANDS on purpose: `margin` shorthand would wipe the 14px side margins
     that make the ≤560px rail an inset card. */
  .hero .hero-rail { margin-top: 5vh; margin-bottom: 0; }
}

/* ==========================================================================
   "We rent bicycles too" CTA pair (.rent-body) — same bug, same fix as
   .direct-strip. This is a bare .hero-cta reused outside the hero, so at phone
   widths it kept the row layout, wrapped onto two lines, and the base
   `.hero-cta > * + *` LEFT margin then indented the wrapped button — the two
   buttons ended up different widths and off-axis, reading as overlapping.
   Column layout, equal full-width buttons, and the left margin converted to a
   top margin. Not scoped to a theme: this is geometry, it applies to both.
   ========================================================================== */
@media (max-width: 680px) {
  .rent-body .hero-cta { flex-direction: column; align-items: stretch; justify-content: center; }
  .rent-body .hero-cta > * + * { margin-left: 0; margin-top: 14px; }
  .rent-body .hero-cta .btn { width: 100%; justify-content: center; text-align: center; }
}

/* ==========================================================================
   OLD-TV FALLBACKS — Chromium <79 (e.g. ~5-yr Hisense VIDAA office signage).
   Those engines drop any declaration using clamp()/min()/max(), so headline
   sizes collapse to the UA default (~32px) and the site looks unstyled. This
   block re-states fixed sizes ONLY where clamp() is unsupported; modern
   browsers evaluate the @supports as false-for-them... i.e. skip it entirely,
   so their responsive clamps are untouched.
   ========================================================================== */
@supports not (font-size: clamp(1rem, 2vw, 3rem)) {
  h1 { font-size: 3.4rem; }
  h2 { font-size: 2.1rem; }
  h3 { font-size: 1.5rem; }
  .hero-content h1 { font-size: 3.4rem; }
  .hero-tagline { font-size: 1.2rem; }
  .hero-rail .num { font-size: 1.55rem; }
  .credibility-item .num { font-size: 2.1rem; }
  .matcher h3 { font-size: 1.6rem; }
  .tour-hero-full h1 { font-size: 2.4rem; }
}

/* Narrowest phones: four stat columns inside an inset card leave very little
   per column, and "Languages spoken" is the widest label on the page. Half a
   point off the label keeps all four on one line instead of wrapping and
   breaking the shared two-row grid. */
@media (max-width: 380px) {
  .hero-rail .label { font-size: 9.5px; letter-spacing: 0; }
}

/* ── Turnstile challenge overlay ───────────────────────────────────────────
   The captcha widget must live ON SCREEN. It was previously parked at
   left:-9999px, which is fine while Cloudflare stays silent but fatal the
   moment it asks the visitor to click a checkbox: off screen the box could
   never be clicked, no token was ever issued, and the server refused the
   booking with "Captcha required". Visitors on a flagged IP (an office that
   books repeatedly, a VPN, hotel wifi) could not book at all.
   The wrapper is inert and invisible until JS adds .is-open, which happens
   only in Cloudflare's before-interactive callback, so an ordinary guest
   never sees anything. Literal colours, no color-mix (old signage TV). */
.sbp-ts-overlay {
  position: fixed; inset: 0; z-index: 2147483000;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none; opacity: 0; visibility: hidden;
}
.sbp-ts-overlay.is-open {
  pointer-events: auto; opacity: 1; visibility: visible;
  background: rgba(8, 14, 11, .62);
}
.sbp-ts-overlay.is-open .sbp-ts-box {
  background: #FFFFFF;
  padding: 20px;
  border-radius: 16px;
  box-shadow: 0 24px 60px -24px rgba(0, 0, 0, .55);
}

/* =====================================================================
   Contact page — "sketchbook / sticky note" language. Flat paper, hairline
   borders, almost no shadow, pastel note cards at a slight tilt, a
   highlighter-marker swipe behind one headline word, rubber-stamp badges.
   Adapted from a reference's PRINCIPLES (flat colour, chunky display type,
   hand-made tilt), not its palette — every colour here is this site's own
   brand/gold/accent tokens. Nothing reuses the homepage chart's dark glass
   panel, the business page's balancing icon, or its hairline rows: this
   page's motion is rotation-settle, a marker swipe, and a stamp-slam.
   ===================================================================== */
.sticky-hero { text-align: center; max-width: 640px; margin: 0 auto 48px; }
.sticky-tag {
  display: inline-flex; align-items: center;
  padding: 7px 16px;
  border-radius: var(--radius-pill);
  background: var(--gold-tint);
  border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
  color: var(--gold-contrast);
  font-family: 'Roboto Mono', monospace;
  font-size: .74rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  transform: rotate(-2deg);
}
[data-theme="dark"] .sticky-tag { color: var(--gold); }
.sticky-tag--alt { background: var(--brand-tint); border-color: color-mix(in srgb, var(--brand) 40%, transparent); color: var(--brand-dark); transform: rotate(1.5deg); }
[data-theme="dark"] .sticky-tag--alt { color: var(--brand); }
/* Bricolage Grotesque: loaded only by this page's <link>, used only for
   these two headlines — every other heading on the page keeps Space Grotesk. */
.sticky-h1 {
  font-family: 'Bricolage Grotesque', var(--font-head);
  font-weight: 800;
  letter-spacing: .01em;
  font-size: clamp(2.4rem, 6vw, 4.2rem);
  line-height: 1.05;
  margin: 16px 0 14px;
}
.sticky-h2 { font-family: 'Bricolage Grotesque', var(--font-head); font-weight: 800; font-size: clamp(1.6rem, 3.4vw, 2.3rem); line-height: 1.1; margin: 14px 0 12px; }
.sticky-lead { font-size: 1.05rem; line-height: 1.6; color: var(--text-secondary); }
.sticky-hero .sticky-lead { max-width: 52ch; margin: 0 auto; }
/* Highlighter swipe: a block of gold grows in behind the word on load,
   transform-origin left so it reads as a marker stroke, not a fade. */
.sticky-mark { position: relative; display: inline-block; white-space: nowrap; }
.sticky-mark::before {
  content: "";
  position: absolute; left: -.08em; right: -.06em; bottom: .04em; top: .5em;
  background: var(--gold);
  opacity: .55;
  transform: scaleX(0) rotate(-1deg);
  transform-origin: left center;
  z-index: -1;
  animation: stickyMarker .55s cubic-bezier(.4,0,.2,1) .5s forwards;
}
@keyframes stickyMarker { to { transform: scaleX(1) rotate(-1deg); } }
@media (prefers-reduced-motion: reduce) { .sticky-mark::before { animation: none; transform: scaleX(1) rotate(-1deg); } }

/* Sticky-note board — three tilted notes, not a card grid. */
.sticky-board { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; margin-bottom: 64px; padding: 0 10px; }
.sticky-note {
  --tilt: -2.5deg;
  display: block;
  position: relative;
  padding: 26px 22px;
  border-radius: 10px;
  background: var(--brand-tint);
  border: 1px solid color-mix(in srgb, var(--text-primary) 12%, transparent);
  color: inherit;
  text-decoration: none;
  box-shadow: 0 2px 0 color-mix(in srgb, var(--text-primary) 8%, transparent);
  transform: rotate(var(--tilt)) scale(.9);
  opacity: 0;
  transition: transform .5s cubic-bezier(.34,1.56,.64,1), opacity .4s ease, box-shadow .2s ease;
}
.sticky-board.is-in .sticky-note { opacity: 1; transform: rotate(var(--tilt)) scale(1); }
.sticky-board.is-in .sticky-note--a { transition-delay: 0s; }
.sticky-board.is-in .sticky-note--b { transition-delay: .12s; }
.sticky-board.is-in .sticky-note--c { transition-delay: .24s; }
.sticky-note--a { --tilt: -3deg; background: var(--brand-tint); }
.sticky-note--b { --tilt: 2deg; background: var(--gold-tint); }
.sticky-note--c { --tilt: -1.5deg; background: var(--accent-tint); }
.sticky-note:hover { transform: rotate(0deg) scale(1) translateY(-6px); box-shadow: 0 14px 26px -14px color-mix(in srgb, var(--text-primary) 35%, transparent); }
.sticky-note-ic { width: 26px; height: 26px; color: var(--brand-dark); margin-bottom: 12px; }
[data-theme="dark"] .sticky-note-ic { color: var(--brand); }
.sticky-note-k { font-family: 'Roboto Mono', monospace; font-size: .7rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 6px; }
.sticky-note-v { font-family: var(--font-head); font-size: 1.1rem; font-weight: 700; color: var(--text-primary); line-height: 1.3; }
.sticky-note-sub { margin-top: 8px; font-size: 13px; color: var(--text-secondary); }
@media (max-width: 780px) {
  .sticky-board { grid-template-columns: 1fr; gap: 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .sticky-note { transition: none; opacity: 1; transform: rotate(var(--tilt)); }
}

/* Message-us speech bubble, not a photo+text split. */
.sticky-bubble { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: 26px; padding: 44px 48px; margin-bottom: 72px; }
.sticky-bubble-tail { position: absolute; left: 64px; bottom: -19px; width: 0; height: 0; border-left: 15px solid transparent; border-right: 15px solid transparent; border-top: 20px solid var(--border); }
.sticky-bubble-tail::after { content: ""; position: absolute; left: -13px; top: -19px; width: 0; height: 0; border-left: 13px solid transparent; border-right: 13px solid transparent; border-top: 18px solid var(--surface); }
@media (max-width: 640px) { .sticky-bubble { padding: 32px 24px; } }

/* Rubber-stamp trust row — a stamp-slam pop, not a fill-bar or a wipe. */
.sticky-stamps { display: flex; justify-content: center; gap: 40px; flex-wrap: wrap; margin: 8px 0 64px; }
.sticky-stamp { display: flex; flex-direction: column; align-items: center; text-align: center; width: 150px; }
.sticky-stamp-ring {
  --tilt: 0deg;
  width: 92px; height: 92px;
  border-radius: 50%;
  border: 2px dashed var(--brand-dark);
  display: flex; align-items: center; justify-content: center;
  padding: 10px;
  margin-bottom: 12px;
  transform: rotate(var(--tilt)) scale(0);
  opacity: 0;
  transition: transform .5s cubic-bezier(.34,1.56,.64,1), opacity .3s ease;
}
[data-theme="dark"] .sticky-stamp-ring { border-color: var(--gold); }
.sticky-stamp-ring .ico { width: 30px; height: 30px; color: var(--brand-dark); }
[data-theme="dark"] .sticky-stamp-ring .ico { color: var(--gold); }
.sticky-stamps.is-in .sticky-stamp-ring { transform: rotate(var(--tilt)) scale(1); opacity: 1; }
.sticky-stamps.is-in .sticky-stamp--a .sticky-stamp-ring { transition-delay: 0s; }
.sticky-stamps.is-in .sticky-stamp--b .sticky-stamp-ring { transition-delay: .15s; }
.sticky-stamps.is-in .sticky-stamp--c .sticky-stamp-ring { transition-delay: .3s; }
.sticky-stamp--a .sticky-stamp-ring { --tilt: -7deg; }
.sticky-stamp--b .sticky-stamp-ring { --tilt: 5deg; }
.sticky-stamp--c .sticky-stamp-ring { --tilt: -4deg; }
.sticky-stamp b { display: block; font-family: 'Roboto Mono', monospace; font-weight: 600; font-size: .78rem; letter-spacing: .04em; color: var(--brand-dark); line-height: 1.25; margin-bottom: 4px; }
[data-theme="dark"] .sticky-stamp b { color: var(--gold); }
.sticky-stamp span { font-size: 12.5px; color: var(--text-secondary); line-height: 1.4; }
@media (prefers-reduced-motion: reduce) {
  .sticky-stamp-ring { transition: none; opacity: 1; transform: rotate(var(--tilt)); }
}

/* Map, framed with washi tape instead of a plain card — .map-frame (in the
   markup alongside this class) still supplies the dark-theme iframe filter. */
.sticky-map {
  position: relative;
  padding: 0; overflow: hidden;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  margin-bottom: 40px;
}
.sticky-tape {
  position: absolute; top: -13px;
  width: 66px; height: 24px;
  background: color-mix(in srgb, var(--gold) 55%, transparent);
  box-shadow: 0 2px 4px rgba(0,0,0,.12);
  z-index: 1;
}
.sticky-tape--l { left: 22px; transform: rotate(-8deg); }
.sticky-tape--r { right: 22px; transform: rotate(7deg); background: color-mix(in srgb, var(--brand) 50%, transparent); }

/* =====================================================================
   About page — REBUILT FROM SCRATCH, second design. Punk / rock-and-roll,
   same brief as the business-page rebuild, but a different set of motifs
   so the two pages don't repeat each other: a spray-stencil hero instead
   of a gig-poster hero, a torn-flyer photo instead of a dotted frame, a
   film-strip ticker instead of hazard stripes, staple-cornered flyer tiles
   instead of laminates/bento, a taped guestbook quote instead of a plain
   spotlight card. Nothing here reuses the previous "poster" pass: no
   Fraunces, no watermark monuments, no dotted-gold rules, no ringed icons.
   Still on this site's own tokens — --accent is the spray-paint colour,
   never a literal neon palette. Shared trust widgets (.credibility-bar,
   .awards-strip) are left as the site's own generic components, same
   restraint the rest of the site uses for those.
   ===================================================================== */

/* ---- Hero: spray-stencil flyer ---- */
.punk-hero { position: relative; overflow: hidden; padding-top: 52px; padding-bottom: 12px; }
.punk-hero-splat {
  position: absolute; top: -12%; right: -6%; z-index: 0; pointer-events: none;
  width: 46vw; height: 46vw; max-width: 520px; max-height: 520px;
  background: radial-gradient(circle, var(--accent), transparent 68%);
  opacity: .14; filter: blur(2px);
}
.punk-hero-inner { position: relative; z-index: 1; }
.punk-stamp {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-body); font-size: .78rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-primary);
  border: 2px solid var(--text-primary); border-radius: 4px;
  padding: 6px 12px; margin-bottom: 20px;
  transform: rotate(-2deg);
}
.punk-stamp::before { content: "★"; color: var(--accent); }
/* Bungee: loaded only by this page's <link>, used only for the hero H1 —
   a bold stencil poster face, the loudest thing on this page. */
.punk-h1 {
  position: relative;
  font-family: 'Bungee', var(--font-head);
  font-weight: 400;
  letter-spacing: -.01em;
  font-size: clamp(2.6rem, 7.4vw, 5.4rem);
  line-height: 1.02;
  margin: 0 0 22px;
  text-transform: uppercase;
}
.punk-h1 span { position: relative; display: inline-block; color: var(--accent); }
.punk-lead { position: relative; font-size: 1.08rem; line-height: 1.6; color: var(--text-secondary); max-width: 62ch; margin: 0 0 34px; }

/* Stat strip scoped to this hero only — the shared .credibility-bar/.item
   markup and count-up JS are untouched; this just repaints them as four
   flat ink tabs instead of the site's default plain numbers. */
.punk-hero .credibility-bar { justify-content: flex-start; gap: 0; flex-wrap: wrap; }
.punk-hero .credibility-item {
  align-items: flex-start; text-align: left; min-width: 150px;
  padding: 14px 22px 14px 16px; border-left: 3px solid var(--accent);
}
.punk-hero .credibility-item:nth-child(2) { border-left-color: var(--brand-dark); }
[data-theme="dark"] .punk-hero .credibility-item:nth-child(2) { border-left-color: var(--brand); }
.punk-hero .credibility-item:nth-child(3) { border-left-color: var(--gold-contrast); }
[data-theme="dark"] .punk-hero .credibility-item:nth-child(3) { border-left-color: var(--gold); }
.punk-hero .credibility-item:nth-child(4) { border-left-color: var(--indigo); }

/* ---- Pull-quote — spray can lettering, torn paper strip ---- */
.punk-quote { position: relative; max-width: 760px; margin: 0 auto; text-align: center; }
.punk-quote-mark {
  display: block; font-family: 'Bungee', var(--font-head);
  font-size: 3.6rem; line-height: 1; color: var(--accent);
  opacity: .8; margin-bottom: -14px; transform: rotate(-3deg);
}
.punk-quote p { font-family: var(--font-head); font-weight: 700; font-size: clamp(1.2rem, 2.4vw, 1.7rem); line-height: 1.4; color: var(--text-primary); }
.punk-quote cite { font-size: 12.5px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .08em; font-style: normal; }

/* ---- Story split — a torn-edge photo, tilted, taped at two corners ---- */
.punk-story { display: grid; grid-template-columns: 1fr 1.15fr; gap: 56px; align-items: center; }
.punk-frame {
  position: relative; transform: rotate(-1.4deg);
  /* jagged torn-paper silhouette */
  clip-path: polygon(0% 2%, 4% 0%, 22% 1.5%, 40% 0%, 58% 1.8%, 76% 0%, 94% 1.5%, 100% 0%,
                      100% 96%, 96% 100%, 78% 98.2%, 60% 100%, 42% 98.5%, 24% 100%, 6% 98.2%, 0% 100%);
  box-shadow: 0 18px 34px -18px rgba(0,0,0,.4);
}
.punk-frame img { display: block; width: 100%; aspect-ratio: 4/3; object-fit: cover; }
.punk-frame::before, .punk-frame::after {
  /* tape strips, top-left and bottom-right */
  content: ""; position: absolute; width: 58px; height: 20px;
  background: color-mix(in srgb, var(--gold) 55%, var(--surface) 45%);
  opacity: .85; box-shadow: 0 2px 4px rgba(0,0,0,.18);
}
.punk-frame::before { top: -10px; left: 18px; transform: rotate(-8deg); }
.punk-frame::after { bottom: -10px; right: 18px; transform: rotate(-8deg); }
@media (max-width: 860px) { .punk-story { grid-template-columns: 1fr; gap: 40px; } }

/* ---- Film-strip ticker — sprocket holes, not hazard stripes (business
   page already used those) ---- */
.punk-strip { position: relative; overflow: hidden; white-space: nowrap; background: var(--text-primary); padding: 10px 0; }
.punk-strip::before, .punk-strip::after {
  content: ""; position: absolute; left: 0; right: 0; height: 9px;
  background-image: radial-gradient(circle, var(--bg) 3px, transparent 3.2px);
  background-size: 26px 100%; background-repeat: repeat-x;
  opacity: .5;
}
.punk-strip::before { top: 0; }
.punk-strip::after { bottom: 0; }
.punk-strip-track { display: inline-flex; gap: 16px; animation: punkStrip 34s linear infinite; padding: 0 8px; }
.punk-strip-track span { font-family: var(--font-head); font-size: .92rem; font-weight: 700; color: var(--bg); white-space: nowrap; }
.punk-strip-track span.dot { color: var(--accent); }
@keyframes punkStrip { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .punk-strip-track { animation: none; } }

/* ---- Features — a stapled flyer stack, not ringed icons ---- */
.punk-flyers { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-top: 8px; }
.punk-flyer {
  position: relative;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 4px;
  padding: 24px 18px 20px; text-align: center;
  transform: rotate(var(--fr, 0deg));
  box-shadow: 0 10px 20px -14px rgba(0,0,0,.3);
  transition: transform .25s ease, box-shadow .25s ease;
}
.punk-flyer:nth-child(1) { --fr: -1.4deg; }
.punk-flyer:nth-child(2) { --fr: 1deg; }
.punk-flyer:nth-child(3) { --fr: -.8deg; }
.punk-flyer:nth-child(4) { --fr: 1.3deg; }
.punk-flyer:hover { transform: rotate(0deg) translateY(-4px); box-shadow: 0 16px 28px -16px rgba(0,0,0,.35); }
.punk-flyer::before {
  /* staple */
  content: ""; position: absolute; top: -6px; left: 50%; margin-left: -10px;
  width: 20px; height: 8px; border-radius: 2px;
  background: color-mix(in srgb, var(--text-primary) 55%, transparent);
  transform: rotate(-4deg);
}
.punk-flyer-ic {
  display: flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; margin: 0 auto 14px;
  border-radius: 50%; background: var(--accent); color: #fff;
}
.punk-flyer:nth-child(2) .punk-flyer-ic { background: var(--brand-dark); }
[data-theme="dark"] .punk-flyer:nth-child(2) .punk-flyer-ic { background: var(--brand); }
.punk-flyer:nth-child(3) .punk-flyer-ic { background: var(--gold-contrast); }
[data-theme="dark"] .punk-flyer:nth-child(3) .punk-flyer-ic { background: var(--gold); color: #14100B; }
.punk-flyer:nth-child(4) .punk-flyer-ic { background: var(--indigo); }
.punk-flyer-ic .ico { width: 22px; height: 22px; }
.punk-flyer-ic span { font-family: var(--font-head); font-size: 1.15rem; font-weight: 700; }
.punk-flyer h3 { font-size: 1rem; margin: 0 0 8px; }
.punk-flyer p { font-size: 13px; color: var(--text-secondary); margin: 0; line-height: 1.5; }
@media (max-width: 860px) { .punk-flyers { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .punk-flyers { grid-template-columns: 1fr; } .punk-flyer { transform: none; } }

/* ---- Spotlight — a taped guestbook card, cross-fading, click-through
   dots. Same rotator mechanic as before (it works well) but restyled: a
   physical taped index card instead of plain centred italic type. ---- */
.punk-spotlight { max-width: 640px; margin: 0 auto; }
.punk-spotlight-track { position: relative; min-height: 260px; }
.punk-spotlight-slide {
  position: absolute; inset: 0;
  margin: 0; text-align: center;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 6px;
  padding: 34px 30px; box-shadow: 0 16px 30px -18px rgba(0,0,0,.35);
  opacity: 0; visibility: hidden; transform: rotate(-.8deg);
  transition: opacity .5s ease;
}
.punk-spotlight-slide::before {
  content: ""; position: absolute; top: -10px; left: 50%; margin-left: -30px;
  width: 60px; height: 20px;
  background: color-mix(in srgb, var(--gold) 55%, var(--surface) 45%);
  opacity: .85; transform: rotate(-3deg);
}
.punk-spotlight-slide.is-active { opacity: 1; visibility: visible; position: relative; }
.punk-spotlight-slide .stars { color: var(--gold); letter-spacing: 2px; font-size: 1.1rem; display: block; margin-bottom: 14px; }
.punk-spotlight-slide p { font-family: var(--font-head); font-weight: 700; font-size: clamp(1.05rem, 2vw, 1.3rem); line-height: 1.45; color: var(--text-primary); margin: 0 0 18px; }
.punk-spotlight-slide cite { display: block; font-style: normal; }
.punk-spotlight-slide cite b { display: block; font-family: var(--font-head); font-size: .95rem; }
.punk-spotlight-slide cite span { font-size: 12.5px; color: var(--text-muted); }
.punk-spotlight-dots { display: flex; justify-content: center; gap: 8px; margin-top: 22px; }
.punk-spotlight-dots button {
  width: 9px; height: 9px; padding: 0; border-radius: 2px;
  border: 1.5px solid var(--text-primary); background: transparent;
  cursor: pointer; transform: rotate(45deg);
}
.punk-spotlight-dots button.is-active { background: var(--accent); border-color: var(--accent); }
@media (prefers-reduced-motion: reduce) { .punk-spotlight-slide { transition: none; } }

/* =====================================================================
   Tours page (/tours/) — "Dispatch" rebuild, third design, new tactics
   only. Adapted from an editorial-white-studio, single-accent-flare
   PRINCIPLE (generous whitespace, huge display type, hairline borders,
   one saturated colour used at punctuation-level) — translated onto this
   site's own tokens: --accent (#CC4522, already a warm terracotta) plays
   the "flare" role, never a literal foreign palette. Framing device is a
   travel-magazine dispatch: an issue mast, numbered index cards instead
   of photo-forward tiles, a small real-data bar chart, outline-to-fill
   CTAs with a sweeping underline instead of solid pill buttons.
   Deliberately NOT reused from the two earlier passes: no full-bleed
   photo card (`.proposal-*`), no ticket-stub/perforation motif
   (`.ticket-*`), no Instrument Serif or JetBrains Mono loaded on this
   page. Filtering is untouched: still .tour-card[data-duration] +
   .chip[data-filter], same main.js selectors. Reveal-on-scroll follows
   the same `.is-in` + IntersectionObserver convention already used for
   [data-rc]/.biz-row/[data-sticky-board] — new target selectors only.
   ===================================================================== */

/* ---- Masthead hero + chart, one section ---- */
.dispatch-hero { padding-top: 48px; padding-bottom: 56px; }
.dispatch-hero-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: 48px; align-items: center; }
.dispatch-mast {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap;
  font-family: var(--font-body); font-size: 12.5px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted);
  padding-bottom: 14px; margin-bottom: 22px;
  border-bottom: 1px solid var(--border);
}
.dispatch-mast b { color: var(--accent); font-weight: 700; }
.dispatch-h1 {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(2.4rem, 5.4vw, 3.8rem);
  letter-spacing: -.02em; line-height: .98;
  margin: 0 0 18px;
}
.dispatch-h1 .dispatch-dot { color: var(--accent); }
.dispatch-lead { font-size: clamp(.94rem, 1.6vw + .5rem, 1.02rem); line-height: 1.58; color: var(--text-secondary); max-width: 52ch; margin: 0 0 28px; }

/* Compact stat row under the lead — no border strip, no 128px of section
   air, just a tight 4-up row that shares the copy column's width. Each
   number gets its own token colour (cycling brand/accent/indigo) plus a
   short colour tick above it — plain black on black read as an afterthought. */
.dispatch-stats-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; padding-top: 20px; border-top: 1px solid var(--border); }
.dispatch-stat { display: flex; flex-direction: column; gap: 5px; }
.dispatch-stat::before { content: ""; display: block; width: 20px; height: 3px; border-radius: 2px; background: var(--accent); }
.dispatch-stat:nth-child(2)::before { background: var(--brand); }
.dispatch-stat:nth-child(3)::before { background: var(--gold); }
.dispatch-stat:nth-child(4)::before { background: var(--indigo); }
.dispatch-stat .n { font-family: var(--font-head); font-size: clamp(1.35rem, 2vw, 1.7rem); font-weight: 700; letter-spacing: -.02em; color: var(--accent); }
.dispatch-stat:nth-child(2) .n { color: var(--brand-dark); }
[data-theme="dark"] .dispatch-stat:nth-child(2) .n { color: var(--brand); }
.dispatch-stat:nth-child(3) .n { color: var(--gold-contrast); }
[data-theme="dark"] .dispatch-stat:nth-child(3) .n { color: var(--gold); }
.dispatch-stat:nth-child(4) .n { color: var(--indigo); }
.dispatch-stat .l { font-size: 11px; color: var(--text-muted); font-weight: 500; }

/* Chart — no boxed card, no background (matches the rest of the page's
   no-card editorial look). A left hairline is the only thing separating
   it from the copy column; vertically centred with the headline block. */
.dispatch-chart-card { padding-left: 32px; border-left: 1px solid var(--border); }
.dispatch-chart-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 16px; }
.dispatch-chart-head h3 { font-family: var(--font-head); font-size: .95rem; margin: 0; }
.dispatch-chart-head span { font-size: 11px; color: var(--text-muted); }
.dispatch-bars { display: flex; flex-direction: column; gap: 10px; }
.dispatch-bar { display: grid; grid-template-columns: 96px 1fr 32px; align-items: center; gap: 10px; }
.dispatch-bar-label { font-size: 11px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dispatch-bar-track { height: 6px; border-radius: var(--radius-pill); background: var(--brand-tint); overflow: hidden; }
.dispatch-bar-fill {
  display: block; height: 100%; width: 0; border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent), var(--gold));
  transition: width 1s cubic-bezier(.3,.7,.2,1);
}
.dispatch-hero.is-in .dispatch-bar-fill { width: var(--v); }
.dispatch-bar-num { font-size: 11px; font-weight: 700; color: var(--text-muted); text-align: right; }
@media (prefers-reduced-motion: reduce) {
  .dispatch-bar-fill { transition: none; width: var(--v); }
}

/* Underline tabs, not pills — the flare colour marks only the active one.
   Sits directly above the grid, left-aligned with it. Below 640px it's a
   horizontal-scroll strip instead of wrapping — wrapped tabs broke their
   own baseline (uneven row heights, ragged underlines); one clean row you
   can swipe reads better at any width than two uneven ones. */
/* overflow-x:auto forces the y-axis to compute as auto too (spec: a
   non-visible x with a visible y converts the y to auto), so this row can
   clip its own content vertically if anything sits exactly at the edge —
   padding-top added as headroom, not just bottom. */
.dispatch-filters { margin-bottom: 26px; gap: 22px; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding: 4px 0 4px; }
.dispatch-filters::-webkit-scrollbar { display: none; }
.dispatch-filters .chip {
  background: none; border: none; border-radius: 0;
  padding: 4px 0 10px; font-family: var(--font-body); font-size: 14px; font-weight: 600;
  color: var(--text-muted); white-space: nowrap; flex: none;
  border-bottom: 2px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
.dispatch-filters .chip.active { background: none; color: var(--text-primary); border-bottom-color: var(--accent); }
.dispatch-filters .chip:hover { color: var(--text-primary); }
@media (max-width: 640px) {
  .dispatch-filters { gap: 18px; margin-bottom: 22px; mask-image: linear-gradient(90deg, #000 92%, transparent); }
  .dispatch-filters .chip { font-size: 13px; padding: 4px 0 8px; }
}

@media (max-width: 900px) {
  .dispatch-hero-grid { grid-template-columns: 1fr; gap: 28px; }
  .dispatch-chart-card { padding-left: 0; border-left: none; padding-top: 20px; border-top: 1px solid var(--border); }
}
@media (max-width: 640px) {
  .dispatch-hero { padding-top: 24px; padding-bottom: 28px; }
  .dispatch-lead { margin-bottom: 18px; }
  .dispatch-stats-row { grid-template-columns: repeat(2, 1fr); gap: 14px 18px; padding-top: 16px; }
  .dispatch-bar { grid-template-columns: 78px 1fr 28px; gap: 8px; }
  .dispatch-bar-label { font-size: 10.5px; }
}

/* ---- "Booking here" — punk zine bento, no panel background ----
   No boxed backdrop — torn color-block tiles float straight on the page,
   mixed rotation, hard offset shadows (no blur — flat, comic-panel). The
   ink outline and shadow colour both derive from --text-primary, so they
   flip automatically: near-black shadow/outline in light theme, a bright
   near-white one in dark theme (still reads as a hard punk shadow, just
   inverted — never a separate [data-theme] rule). One big showcase tile,
   four smaller ones. Tiles straighten and lift on hover. */
.dispatch-bento {
  position: relative;
  margin-bottom: 44px;
  opacity: 0; transform: translateY(14px);
  transition: opacity .5s ease, transform .5s ease;
}
.dispatch-bento[data-reveal].is-in { opacity: 1; transform: none; }
.dispatch-bento-head { max-width: 60ch; margin-bottom: 26px; }
.dispatch-bento-tag {
  display: inline-block; font-family: var(--font-body); font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: #12100D;
  background: var(--gold); padding: 4px 10px; border-radius: 3px;
  transform: rotate(-2deg); margin-bottom: 12px;
}
.dispatch-bento-head h3 { font-family: var(--font-head); font-size: clamp(1.3rem, 2.6vw, 1.7rem); color: var(--text-primary); margin: 0 0 8px; letter-spacing: -.01em; }
.dispatch-bento-head h3 em { font-style: normal; color: var(--accent); text-decoration: underline wavy; text-decoration-thickness: 2px; text-underline-offset: 3px; }
.dispatch-bento-head p { font-size: 13.5px; color: var(--text-secondary); margin: 0; }
.dispatch-bento-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(2, auto); gap: 16px;
}
.dispatch-bento-item {
  position: relative;
  display: flex; flex-direction: column; gap: 8px;
  padding: 18px; border-radius: 10px;
  background: var(--surface); color: var(--text-primary);
  border: 2px solid var(--text-primary);
  box-shadow: 5px 5px 0 var(--text-primary);
  transition: transform .25s ease, box-shadow .25s ease;
}
.dispatch-bento-item i { width: 22px; height: 22px; background-color: currentColor; }
.dispatch-bento-item b { font-family: var(--font-head); font-size: 14px; }
.dispatch-bento-item span { font-size: 12px; line-height: 1.4; color: var(--text-secondary); }
.dispatch-bento-item:hover { transform: rotate(0deg) translateY(-3px); box-shadow: 7px 7px 0 var(--text-primary); }
/* The showcase tile spans 2x2, so its own sparse content used to just sit
   centred in a lot of dead space — a small headline lost in a huge box.
   Fixed by making the content itself bigger and bottom-anchored (a poster,
   not an orphaned label): larger icon/heading/body, justify-content:
   flex-end so it reads as a deliberate feature card, not leftover space. */
.db-1 { grid-column: 1 / 3; grid-row: 1 / 3; background: var(--accent); color: #fff; transform: rotate(-1.5deg); justify-content: flex-end; padding: 26px; }
.db-1 b { font-size: 28px; line-height: 1.15; }
.db-1 span { color: rgba(255,255,255,.88); font-size: 15px; max-width: 42ch; }
.db-1 i { width: 42px; height: 42px; margin-bottom: 6px; }
.db-2 { grid-column: 3 / 4; grid-row: 1; transform: rotate(2deg); }
.db-3 { grid-column: 4 / 5; grid-row: 1; transform: rotate(-1deg); background: var(--gold); color: #14100B; }
.db-3 span { color: rgba(20,16,11,.7); }
.db-4 { grid-column: 3 / 4; grid-row: 2; transform: rotate(1.5deg); }
.db-5 { grid-column: 4 / 5; grid-row: 2; transform: rotate(-2deg); background: var(--brand); color: #fff; }
.db-5 span { color: rgba(255,255,255,.85); }
@media (prefers-reduced-motion: reduce) {
  .dispatch-bento { opacity: 1; transform: none; transition: none; }
  .dispatch-bento-item { transition: none; }
}
@media (max-width: 860px) {
  .dispatch-bento-grid { grid-template-columns: repeat(2, 1fr); grid-template-rows: auto; }
  .db-1 { grid-column: 1 / 3; grid-row: auto; }
  .db-2, .db-3, .db-4, .db-5 { grid-column: auto; grid-row: auto; }
}
@media (max-width: 520px) {
  .dispatch-bento-grid { grid-template-columns: 1fr; }
  .db-1, .db-2, .db-3, .db-4, .db-5 { grid-column: auto; transform: none; }
}

/* ---- Card grid, from scratch — a Polaroid stack, not another flat card ----
   Third card treatment on this page (after full-bleed proposal cards, then
   ticket stubs, then flat numbered index cards) — none of those tactics
   reused. Each tour is a physical printed photo: thick white/surface
   border, duration+price live IN the photo's own bottom margin like a
   handwritten caption, a circular stamp badge pins the index number to the
   corner, and every card sits at its own slight rotation (six-way cycle)
   like a scattered stack — straightens and lifts on hover. Title/rating/CTA
   sit below the photo object as normal editorial text, not inside a card
   shell. .dispatch-cta is unchanged (shared with the bento + orbit CTAs). */
.dispatch-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 40px 28px; padding-top: 10px; }
.tour-card.dispatch-card {
  position: relative;
  display: flex; flex-direction: column;
  background: none; border: none; box-shadow: none; border-radius: 0;
  /* Base .tour-card sets overflow:hidden (it clips OTHER card variants'
     photos to a rounded corner) — it doesn't get reset just because this
     rule wins on specificity, so it silently sliced the stamp badge in
     half where it pokes up above the card box. Must override explicitly. */
  overflow: visible;
  opacity: 0; transform: translateY(16px);
  transition: opacity .5s ease, transform .5s ease;
  transition-delay: calc(var(--i, 0) * 70ms);
}
.dispatch-grid.is-in .tour-card.dispatch-card { opacity: 1; transform: none; }

.dispatch-num {
  position: absolute; top: -13px; left: 16px; z-index: 3;
  width: 27px; height: 27px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-head); font-size: 11px; font-weight: 700;
  background: var(--surface); border: 1.5px solid var(--text-primary); color: var(--text-primary);
  transform: rotate(-8deg);
}

.dispatch-polaroid {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 10px 10px 44px;
  box-shadow: 0 12px 26px -16px rgba(0,0,0,.4), 0 2px 6px -2px rgba(0,0,0,.14);
  transform: rotate(var(--rot, 0deg));
  transition: transform .3s cubic-bezier(.2,.7,.3,1), box-shadow .3s ease;
}
.tour-card.dispatch-card:nth-child(6n+1) .dispatch-polaroid { --rot: -1.6deg; }
.tour-card.dispatch-card:nth-child(6n+2) .dispatch-polaroid { --rot: 1.1deg; }
.tour-card.dispatch-card:nth-child(6n+3) .dispatch-polaroid { --rot: -.7deg; }
.tour-card.dispatch-card:nth-child(6n+4) .dispatch-polaroid { --rot: 1.5deg; }
.tour-card.dispatch-card:nth-child(6n+5) .dispatch-polaroid { --rot: -1.2deg; }
.tour-card.dispatch-card:nth-child(6n+6) .dispatch-polaroid { --rot: .8deg; }
.tour-card.dispatch-card:hover .dispatch-polaroid {
  transform: rotate(0deg) translateY(-6px);
  box-shadow: 0 20px 36px -16px rgba(0,0,0,.45), 0 6px 12px -2px rgba(0,0,0,.18);
}

.dispatch-photo { display: block; position: relative; aspect-ratio: 1/1; overflow: hidden; border-radius: 2px; }
.dispatch-img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s cubic-bezier(.2,.7,.3,1); filter: saturate(.94); }
.tour-card.dispatch-card:hover .dispatch-img { transform: scale(1.05); filter: saturate(1.05); }
.dispatch-tag {
  position: absolute; top: 10px; left: 10px; z-index: 2;
  font-family: var(--font-body); font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: var(--accent); color: #fff;
  padding: 4px 9px; border-radius: 3px;
  transform: rotate(-2deg);
}
.dispatch-caption {
  position: absolute; left: 10px; right: 10px; bottom: 13px;
  display: flex; align-items: baseline; justify-content: space-between;
  font-family: var(--font-body); font-size: 11.5px; font-weight: 600; color: var(--text-muted);
  letter-spacing: .02em; text-transform: uppercase;
}
.dispatch-price { color: var(--brand-dark); font-weight: 700; }
[data-theme="dark"] .dispatch-price { color: var(--brand); }

.dispatch-body { padding: 18px 6px 0; display: flex; flex-direction: column; flex: 1; }
.dispatch-body h3 { font-family: var(--font-head); font-size: 1.1rem; margin: 0 0 6px; }
.dispatch-body p { font-size: 13px; line-height: 1.5; color: var(--text-secondary); margin: 0 0 14px; flex: 1; }
.dispatch-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.dispatch-rating { font-size: 12.5px; color: var(--text-muted); }
.dispatch-rating .stars { color: var(--gold); }
.dispatch-cta {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13.5px; font-weight: 700; color: var(--text-primary);
  padding: 8px 14px; border: 1.5px solid var(--text-primary); border-radius: var(--radius-pill);
  position: relative; overflow: hidden;
}
.dispatch-cta span { transition: transform .25s ease; }
.dispatch-cta::before {
  content: ""; position: absolute; inset: 0; background: var(--accent);
  transform: translateX(-101%); transition: transform .25s ease; z-index: -1;
}
.dispatch-cta:hover { border-color: var(--accent); color: #fff; }
.dispatch-cta:hover::before { transform: translateX(0); }
.dispatch-cta:hover span { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .tour-card.dispatch-card { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 520px) {
  .dispatch-grid { grid-template-columns: 1fr; }
}

/* ---- Beauty box: "follow the ride" — an orbit, not a photo grid ----
   Six ride photos circle a fixed YouTube hub like radar. The classic CSS
   clock-hand placement (rotate → translate → counter-rotate) sets each
   photo's angle once; a slow rotation on the whole ring plus an equal and
   opposite rotation on each photo cancels out (total orientation = 0 at
   every frame — see the math in the session log), so the ring visibly
   orbits while the photos themselves stay upright. The centre button sits
   OUTSIDE the ring, so it never moves. */
.dispatch-reel-wrap { padding-top: 12px; }
.dispatch-reel {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  text-align: center;
  opacity: 0; transform: translateY(18px);
  transition: opacity .6s ease, transform .6s ease;
}
.dispatch-reel-wrap.is-in .dispatch-reel { opacity: 1; transform: none; }
.dispatch-reel-head { max-width: 52ch; margin-bottom: 8px; }
.dispatch-reel-head .dispatch-mast { border: none; padding: 0; margin: 0 auto 12px; justify-content: center; color: var(--accent); }
.dispatch-reel-head h2 { font-family: var(--font-head); font-size: clamp(1.4rem, 3vw, 1.9rem); margin: 0 0 10px; }
.dispatch-reel-head p { font-size: 14px; line-height: 1.55; color: var(--text-secondary); margin: 0; }

.dispatch-orbit { position: relative; width: 380px; height: 380px; max-width: 100%; margin: 20px auto; }
.dispatch-orbit-ring { position: absolute; inset: 0; animation: dispatchOrbitSpin 60s linear infinite; }
.dispatch-orbit-lines { position: absolute; inset: 0; width: 100%; height: 100%; }
.dispatch-orbit-lines .ol-ring { fill: none; stroke: var(--border); stroke-width: 1; }
.dispatch-orbit-lines line { stroke: var(--border); stroke-width: 1; stroke-dasharray: 2 5; }
.dispatch-orbit-photo {
  position: absolute; top: 50%; left: 50%; width: 62px; height: 62px; margin: -31px;
  border-radius: 50%; overflow: hidden; display: block;
  border: 2px solid var(--bg); box-shadow: 0 2px 10px rgba(0,0,0,.22);
  transition: box-shadow .25s ease, border-color .25s ease;
}
.dispatch-orbit-photo img { width: 100%; height: 100%; object-fit: cover; }
/* Each circle (not just the photo inside it) grows and shrinks at its own
   random size and pace as it orbits — six different keyframe sequences,
   not one shared pulse, so the six never breathe in unison. The scale sits
   at the END of the same rotate/translate/counter-rotate chain that keeps
   the photo upright, so it multiplies the already-positioned circle in
   place rather than fighting the position math; each keyframe stop still
   carries the correct counter-rotation angle for that point in the shared
   60s ring rotation (0/90/180/270/360deg), only the scale value differs
   per photo. */
/* nth-child counts ALL children of .dispatch-orbit-ring, and the SVG is
   child 1 — so the six photos are children 2-7, not 1-6. Getting this
   wrong left the 6th photo matching no rule at all (no animation, no
   transform), which collapsed it to dead centre on top of the Watch
   button — the "Instagram broken" bug. */
.dispatch-orbit-photo:nth-child(2) { animation: dOrb1 60s linear infinite; }
.dispatch-orbit-photo:nth-child(3) { animation: dOrb2 60s linear infinite; }
.dispatch-orbit-photo:nth-child(4) { animation: dOrb3 60s linear infinite; }
.dispatch-orbit-photo:nth-child(5) { animation: dOrb4 60s linear infinite; }
.dispatch-orbit-photo:nth-child(6) { animation: dOrb5 60s linear infinite; }
.dispatch-orbit-photo:nth-child(7) { animation: dOrb6 60s linear infinite; }
@keyframes dispatchOrbitSpin { to { transform: rotate(360deg); } }
@keyframes dOrb1 {
  0%   { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -   0deg)) scale(1);    }
  25%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -  90deg)) scale(1.25); }
  50%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 180deg)) scale(.85);  }
  75%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 270deg)) scale(1.1);  }
  100% { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 360deg)) scale(1);    }
}
@keyframes dOrb2 {
  0%   { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -   0deg)) scale(.9);   }
  25%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -  90deg)) scale(.55);  }
  50%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 180deg)) scale(1.15); }
  75%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 270deg)) scale(.75);  }
  100% { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 360deg)) scale(.9);   }
}
@keyframes dOrb3 {
  0%   { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -   0deg)) scale(1.1);  }
  25%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -  90deg)) scale(.7);   }
  50%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 180deg)) scale(1.3);  }
  75%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 270deg)) scale(.95);  }
  100% { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 360deg)) scale(1.1);  }
}
@keyframes dOrb4 {
  0%   { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -   0deg)) scale(.85);  }
  25%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -  90deg)) scale(1.2);  }
  50%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 180deg)) scale(.6);   }
  75%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 270deg)) scale(1.05); }
  100% { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 360deg)) scale(.85);  }
}
@keyframes dOrb5 {
  0%   { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -   0deg)) scale(1);    }
  25%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -  90deg)) scale(.6);   }
  50%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 180deg)) scale(1.15); }
  75%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 270deg)) scale(1.3);  }
  100% { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 360deg)) scale(1);    }
}
@keyframes dOrb6 {
  0%   { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -   0deg)) scale(1.05); }
  25%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) -  90deg)) scale(1.3);  }
  50%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 180deg)) scale(.75);  }
  75%  { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 270deg)) scale(1);    }
  100% { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a) - 360deg)) scale(1.05); }
}
.dispatch-orbit-photo:hover {
  border-color: var(--accent); box-shadow: 0 4px 16px rgba(0,0,0,.3);
  z-index: 3; animation-play-state: paused;
}
.dispatch-orbit-center {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  z-index: 2; width: 108px; height: 108px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: var(--surface); border: 1.5px solid var(--border); box-shadow: 0 6px 22px rgba(0,0,0,.14);
}
.dispatch-orbit-center span:last-child { font-size: 11px; font-weight: 700; letter-spacing: .04em; color: var(--text-muted); }
.dispatch-orbit-center .dispatch-play-btn {
  width: 42px; height: 42px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff;
}
.dispatch-orbit-center .dispatch-play-btn svg { margin-left: 2px; }
.dispatch-orbit-center:hover .dispatch-play-btn { background: var(--brand-dark); }
[data-theme="dark"] .dispatch-orbit-center:hover .dispatch-play-btn { background: var(--brand); }
@media (prefers-reduced-motion: reduce) {
  .dispatch-reel { opacity: 1; transform: none; transition: none; }
  .dispatch-orbit-ring, .dispatch-orbit-photo { animation: none; }
  .dispatch-orbit-photo { transform: rotate(var(--a)) translate(150px) rotate(calc(-1 * var(--a))); }
}
@media (max-width: 560px) {
  .dispatch-orbit { width: 300px; height: 300px; }
  .dispatch-orbit-photo { width: 48px; height: 48px; margin: -24px; }
  /* Same six sequences, smaller orbit radius (115px, matches the shrunk
     ring) — nested @keyframes so they only apply at this width, same
     trick the position-only version used before. */
  @keyframes dOrb1 {
    0%   { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -   0deg)) scale(1);    }
    25%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -  90deg)) scale(1.25); }
    50%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 180deg)) scale(.85);  }
    75%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 270deg)) scale(1.1);  }
    100% { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 360deg)) scale(1);    }
  }
  @keyframes dOrb2 {
    0%   { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -   0deg)) scale(.9);   }
    25%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -  90deg)) scale(.55);  }
    50%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 180deg)) scale(1.15); }
    75%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 270deg)) scale(.75);  }
    100% { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 360deg)) scale(.9);   }
  }
  @keyframes dOrb3 {
    0%   { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -   0deg)) scale(1.1);  }
    25%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -  90deg)) scale(.7);   }
    50%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 180deg)) scale(1.3);  }
    75%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 270deg)) scale(.95);  }
    100% { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 360deg)) scale(1.1);  }
  }
  @keyframes dOrb4 {
    0%   { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -   0deg)) scale(.85);  }
    25%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -  90deg)) scale(1.2);  }
    50%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 180deg)) scale(.6);   }
    75%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 270deg)) scale(1.05); }
    100% { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 360deg)) scale(.85);  }
  }
  @keyframes dOrb5 {
    0%   { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -   0deg)) scale(1);    }
    25%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -  90deg)) scale(.6);   }
    50%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 180deg)) scale(1.15); }
    75%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 270deg)) scale(1.3);  }
    100% { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 360deg)) scale(1);    }
  }
  @keyframes dOrb6 {
    0%   { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -   0deg)) scale(1.05); }
    25%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) -  90deg)) scale(1.3);  }
    50%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 180deg)) scale(.75);  }
    75%  { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 270deg)) scale(1);    }
    100% { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a) - 360deg)) scale(1.05); }
  }
  .dispatch-orbit-center { width: 84px; height: 84px; }
  .dispatch-orbit-center .dispatch-play-btn { width: 34px; height: 34px; }
}
@media (max-width: 560px) and (prefers-reduced-motion: reduce) {
  .dispatch-orbit-photo { transform: rotate(var(--a)) translate(115px) rotate(calc(-1 * var(--a))); }
}

/* =====================================================================
   Phone country-code picker — flag + dial code + search dropdown.
   Wraps the existing .field-input phone number field; markup added by
   each booking form is a .phone-field with a .phone-cc trigger button
   and a .phone-cc-panel dropdown (main.js: initPhoneCountryPicker).
   ===================================================================== */
.phone-field { display: flex; gap: 8px; position: relative; }
.phone-cc {
  display: flex; align-items: center; gap: 6px;
  flex: 0 0 auto; padding: 0 12px; min-height: 50px;
  border-radius: var(--radius-sm); border: 1.5px solid var(--border);
  background: var(--bg); color: var(--text-primary);
  font-family: var(--font-body); font-size: 14px; font-weight: 600;
  cursor: pointer;
}
.phone-cc:hover { border-color: var(--brand); }
.phone-cc:focus-visible { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 18%, transparent); }
.phone-cc-flag { font-size: 18px; line-height: 1; }
.phone-cc-caret { font-size: 10px; opacity: .6; margin-left: 1px; }
.phone-field .phone-number-input { flex: 1 1 auto; min-width: 0; }
.phone-cc-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 20;
  width: 280px; max-width: 90vw;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
  padding: 10px;
}
.phone-cc-search {
  width: 100%; padding: 9px 12px; margin-bottom: 8px;
  border-radius: var(--radius-sm); border: 1.5px solid var(--border);
  background: var(--bg); color: var(--text-primary);
  font-family: var(--font-body); font-size: 13.5px;
}
.phone-cc-search:focus { outline: none; border-color: var(--brand); }
.phone-cc-list {
  list-style: none; margin: 0; padding: 0;
  max-height: 240px; overflow-y: auto;
}
.phone-cc-list li[data-dial] {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 8px; border-radius: 8px; cursor: pointer;
  font-size: 13.5px;
}
.phone-cc-list li[data-dial]:hover { background: var(--brand-tint); }
.phone-cc-opt-flag { font-size: 16px; flex: 0 0 auto; }
.phone-cc-opt-name { flex: 1 1 auto; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.phone-cc-opt-dial { flex: 0 0 auto; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.phone-cc-empty { padding: 10px 8px; color: var(--text-muted); font-size: 13px; text-align: center; }
@media (max-width: 420px) {
  .phone-cc-panel { width: 100%; }
  .phone-cc-dial { display: none; }  /* keep the flag + caret, save width on the smallest phones */
}

/* ===== Monster Bikes page (added 2026-08-29) ===================== */

/* The hero photo is dark in BOTH themes, so a ghost button styled for the
   page background disappears on it in light mode — dark ink on a dark photo.
   Scope the override to the hero so the button is always white-on-photo.
   Paint only: no size, spacing or border-width changes, per the [data-theme]
   invariant this file documents. */
.tour-hero-full .btn-ghost { color: #fff; border-color: rgba(255,255,255,.55); background: rgba(255,255,255,.08); }
.tour-hero-full .btn-ghost:hover { color: #fff; border-color: #fff; background: rgba(255,255,255,.18); }

.mb-tour-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: stretch; }
.mb-card {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px 22px 22px;
  box-shadow: var(--shadow);
  position: relative;
  overflow: hidden;
  /* Entrance is a transform+opacity lift on scroll. `backwards` fill, never
     `opacity:0` + `forwards` — an entrance animation must never be the only
     thing making an element visible (see the hero-rail lesson in CLAUDE.md). */
  animation: mbCardIn .5s cubic-bezier(.22,.7,.3,1) backwards;
}
.mb-card:nth-child(2) { animation-delay: .07s; }
.mb-card:nth-child(3) { animation-delay: .14s; }
@keyframes mbCardIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* A soft accent wash in the corner, so the cards read as designed objects
   rather than plain boxes. Sits under the content. */
.mb-card::before {
  content: ""; position: absolute; top: -60px; right: -60px;
  width: 180px; height: 180px; border-radius: 50%;
  background: radial-gradient(circle, var(--brand-tint), transparent 70%);
  opacity: .9; pointer-events: none;
}
.mb-card > * { position: relative; }
.mb-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.mb-card { transition: transform .22s ease, box-shadow .22s ease; }
.mb-card--private { border-color: var(--gold); }

.mb-card-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; min-height: 24px; }
.mb-card-dur {
  font-family: var(--font-head); font-weight: 700; font-size: 13px;
  letter-spacing: .04em; text-transform: uppercase; color: var(--brand-dark);
}
[data-theme="dark"] .mb-card-dur { color: var(--brand); }
.mb-card-tag:not(:empty) {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 999px;
  background: var(--gold); color: var(--gold-contrast);
}
.mb-card h3 { margin: 0 0 6px; font-size: 1.15rem; }
.mb-card > p { color: var(--text-muted); font-size: 14.5px; margin: 0 0 12px; }
.mb-card .ticks { margin: 0 0 16px; }
.mb-card .ticks li { font-size: 14px; }
.mb-card-foot {
  margin-top: auto; display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; padding-top: 12px; margin-bottom: 14px;
  border-top: 1px solid var(--border);
}
.mb-card-price { font-family: var(--font-head); font-weight: 700; font-size: 1.7rem; color: var(--accent); line-height: 1; }
.mb-card-times { font-size: 12.5px; color: var(--text-muted); text-align: right; }

@media (max-width: 900px) { .mb-tour-cards { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) {
  .mb-card { animation: none; transition: none; }
}
/* Route to the full Monster Bikes page from the homepage teaser. The homepage
   box only shows prices and the booking form; the routes live on the page. */
.mb-more { margin-top: 18px; }
/* The left column (two route diagrams) is far taller than the right one, which
   left a tall empty gap beside it. Sticking the right column keeps the
   inclusions, the practical notes and the rental prices beside whichever route
   the reader is looking at, and the dead space disappears. */
.mb-aside { position: sticky; top: calc(var(--header-h) + 20px); }
@media (max-width: 900px) { .mb-aside { position: static; } }

/* ---- Collapsible route maps -------------------------------------------
   Two full route diagrams stacked open pushed everything else far down the
   page. They are now <details>, closed by default: native, keyboard
   accessible and screen-reader friendly with no JS. */
.route-fold { margin-top: 32px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); overflow: hidden; }
.route-fold + .route-fold { margin-top: 16px; }
.route-fold > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 12px;
  padding: 18px 20px;
  font-family: var(--font-head); font-weight: 700; font-size: 1.05rem;
  color: var(--text-primary);
  transition: background .18s ease;
}
.route-fold > summary::-webkit-details-marker { display: none; }
.route-fold > summary:hover { background: var(--brand-tint); }
.route-fold > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.route-fold-h { flex: 1 1 auto; }
.route-fold-sub { font-family: var(--font-body); font-weight: 500; font-size: 13px; color: var(--text-muted); flex: none; }
/* Chevron drawn from borders so no icon asset is needed. */
.route-fold-chev {
  flex: none; width: 9px; height: 9px;
  border-right: 2px solid var(--text-muted); border-bottom: 2px solid var(--text-muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .22s ease;
}
.route-fold[open] > summary { background: var(--brand-tint); }
.route-fold[open] .route-fold-chev { transform: rotate(-135deg) translate(-2px, -2px); }
.route-fold-body { padding: 4px 20px 20px; }
.route-fold-body .snake { margin-top: 8px; }

/* Rental seats sit side by side. Two tall stacked boxes wasted the column. */
.mb-rental-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 420px) { .mb-rental-grid { grid-template-columns: 1fr; } }

/* On phones the hero CTAs sat right under the price line with no breathing
   room, so the buttons read as part of the price. */
@media (max-width: 680px) {
  .tour-hero-full .thf-price { margin-bottom: 18px; }
  .tour-hero-full .hero-cta { gap: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .route-fold > summary, .route-fold-chev { transition: none; }
}

/* ==========================================================================
   FAQ departure board (added 2026-08-31, v=139)
   Split-flap reveal on the tour-page FAQ. The question text is real text in
   the DOM at all times — the animation only swaps characters temporarily and
   restores the original string, so crawlers, AI readers and JS-off browsers
   all see the finished question. See the `flap board` module in main.js.
   ========================================================================== */
.faq-board .accordion-item {
  border-top: 1px solid var(--border);
  border-bottom: none;
  padding: 0;
  transition: background-color .18s ease;
}
.faq-board .accordion-item:last-of-type { border-bottom: 1px solid var(--border); }
.faq-board .accordion-item summary {
  padding: 18px 4px;
  gap: 16px;
  align-items: baseline;
}
.faq-board .accordion-item:hover { background: color-mix(in srgb, var(--border) 22%, transparent); }
.faq-board .accordion-item > p { padding: 0 4px 20px; max-width: 68ch; }

/* the flapping text itself */
.faq-board .flap {
  display: inline-block;
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
}
/* while a row is mid-flap the characters are stand-ins, so dim them slightly
   and let the settled text arrive at full contrast */
.faq-board .flap[data-flapping] {
  color: color-mix(in srgb, currentColor 62%, transparent);
  text-shadow: 0 0 12px color-mix(in srgb, currentColor 25%, transparent);
}
/* The shared .rock-faq skin styles *any* span inside a summary, because on the
   group page the only span is the +/x sign. Here the question text is a span
   too, so it inherited Bebas Neue, the accent colour and the 45deg open
   rotation — the question visibly flew across the page when a row opened.
   Scope those back to the sign. */
.faq-board .accordion-item summary .flap,
.faq-board .accordion-item[open] summary .flap {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  transform: none;
}

.faq-board .acc-sign {
  font-weight: 500;
  opacity: .55;
  transition: transform .2s ease, opacity .2s ease;
  flex: 0 0 auto;
}
.faq-board .accordion-item[open] .acc-sign { transform: rotate(45deg); opacity: 1; }

/* rows arrive one after another, like a board resetting */
.faq-board .accordion-item {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .35s ease, transform .35s ease, background-color .18s ease;
}
.faq-board.is-live .accordion-item { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .faq-board .accordion-item { opacity: 1; transform: none; transition: none; }
  .faq-board .flap[data-flapping] { color: inherit; text-shadow: none; }
}
