/* KVADROTUR02 — фирменный #1976d2 + тёплый акцент, Roboto для текста,
   Russo One для заголовков. Публичная часть — "кинематографичная": тёмные
   секции с aurora-градиентами, полноэкранный hero, прозрачная шапка. */
@font-face {
  font-family: "Roboto";
  src: url("../fonts/roboto-cyrillic-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: "Roboto";
  src: url("../fonts/roboto-latin-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2212;
}

@font-face {
  font-family: "Roboto";
  src: url("../fonts/roboto-cyrillic-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: "Roboto";
  src: url("../fonts/roboto-latin-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2212;
}

@font-face {
  font-family: "Roboto";
  src: url("../fonts/roboto-cyrillic-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: "Roboto";
  src: url("../fonts/roboto-latin-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2212;
}

/* Display face for the logo and every heading: a single-weight sporty
   grotesque (SIL OFL), self-hosted like Roboto so the preload in base.html
   byte-matches this url — see the comment there. */
@font-face {
  font-family: "Russo One";
  src: url("../fonts/russo-one-cyrillic.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: "Russo One";
  src: url("../fonts/russo-one-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2212;
}

:root {
  --primary: #1976d2;
  /* --primary as bare channels, for every alpha variant of the brand color —
     keep in sync with --primary, or a rebrand leaves the tints behind */
  --primary-rgb: 25, 118, 210;
  --primary-bright: #2196f3;
  --primary-dark: #115293;
  --primary-deep: #0b3a66;
  --primary-soft: #e8f2fc;
  /* one gradient for every "brand-colored surface" (primary buttons, active
     chips) so they all shift hue together if the brand color ever changes */
  --primary-grad: linear-gradient(135deg, var(--primary-bright) 0%, var(--primary-dark) 100%);
  /* warm accent — the sunset light in the hero photo: eyebrow labels, the
     headline gradient, the live dots. Never a button: those stay brand-blue */
  --accent: #ff8a1f;
  --accent-rgb: 255, 138, 31;
  --accent-deep: #d95f00;
  --accent-grad: linear-gradient(92deg, #ffd08a 0%, var(--accent) 55%, #ff5d2e 100%);
  /* dark surfaces: hero scrim, ticker, "why us", inner-page intro, footer */
  --ink: #0b1420;
  --ink-2: #101d2d;
  --ink-3: #172a3f;
  --text: #16202b;
  --text-muted: #5b6b7b;
  --bg: #ffffff;
  --bg-alt: #f4f7fb;
  --bg-alt-deep: #eef4fa;
  --border: #e3e9f0;
  --error: #c62828;
  --success: #2e7d32;
  --warn: #ef6c00;
  --radius: 18px;
  --radius-sm: 12px;
  --radius-lg: 24px;
  --font-body: "Roboto", -apple-system, "Segoe UI", Arial, sans-serif;
  --font-display: "Russo One", "Roboto", "Arial Black", Impact, sans-serif;
  /* the UNWRAPPED header; the narrow-screen override below matches the
     wrapped two-row height (measured 100px in Chrome at 500px viewport).
     The hero and the inner-page intro pull themselves up under the header by
     exactly this much so the photo / dark band shows through the transparent
     header — if it drifts a few px the only cost is a slightly taller band */
  --header-h: 64px;
  --shadow-sm: 0 1px 2px rgba(16, 42, 67, 0.05), 0 2px 6px rgba(16, 42, 67, 0.06);
  --shadow-md: 0 6px 16px rgba(16, 42, 67, 0.09), 0 2px 4px rgba(16, 42, 67, 0.05);
  --shadow-lg: 0 24px 48px rgba(16, 42, 67, 0.16), 0 6px 12px rgba(16, 42, 67, 0.07);
  /* blue-tinted glow for brand-colored elements (CTA buttons) */
  --shadow-primary: 0 8px 24px rgba(var(--primary-rgb), 0.35);
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
}

::selection {
  background: var(--primary);
  color: #fff;
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* in-page anchors (#tours, #fleet, #booking-panel) land below the sticky
     header instead of under it */
  scroll-padding-top: calc(var(--header-h) + 12px);
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
}

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

a {
  color: var(--primary);
}

/* keeps multi-line headings from leaving a lone word on the last line;
   browsers without text-wrap: balance simply ignore it */
h1,
h2,
h3 {
  text-wrap: balance;
}

h1,
h2 {
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
}

h1 {
  font-size: clamp(1.9rem, 4.2vw, 2.9rem);
  line-height: 1.08;
  letter-spacing: 0.01em;
  margin: 0.4em 0;
}

h2 {
  font-size: clamp(1.55rem, 3.4vw, 2.4rem);
  line-height: 1.1;
  letter-spacing: 0.01em;
  margin: 1em 0 0.5em;
}

h3 {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0.8em 0 0.4em;
}

code {
  background: var(--bg-alt);
  padding: 0 4px;
  border-radius: 3px;
}

small,
.muted {
  color: var(--text-muted);
}

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.container {
  max-width: 1140px;
  margin: 0 auto;
  padding: 0 20px;
}

.container.narrow {
  max-width: 760px;
}

.section {
  padding: 88px 0;
}

.section-alt {
  background: linear-gradient(180deg, var(--bg-alt) 0%, var(--bg-alt-deep) 100%);
}

/* Section header: eyebrow + heading (+ lead) on the left, an optional link
   on the right that drops under them on narrow screens */
.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px 32px;
  flex-wrap: wrap;
  margin-bottom: 40px;
}

.section-head h2 {
  margin: 0;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
  color: var(--accent-deep);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.eyebrow::before {
  content: "";
  width: 28px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}

.section-lead {
  margin: 0;
  color: var(--text-muted);
  max-width: 60ch;
}

.section-head .section-lead {
  margin-top: 14px;
}

.section-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  padding-bottom: 6px;
  transition: gap 0.25s var(--ease-out);
}

.section-link:hover {
  gap: 14px;
}

/* Dark "aurora" surface: two blurred colored blobs behind a deep-navy ground.
   Used by "why us", the inner-page intro and the footer. */
.section-dark {
  position: relative;
  overflow: hidden;
  background: var(--ink);
  color: #fff;
}

.section-dark::before {
  content: "";
  position: absolute;
  inset: -30%;
  pointer-events: none;
  /* no filter: blur() — the gradients are soft on their own, and a blurred
     160%-sized layer under a dozen backdrop-filter surfaces is what makes a
     mid-range phone drop frames while scrolling */
  background:
    radial-gradient(42% 50% at 18% 30%, rgba(var(--primary-rgb), 0.5), transparent 80%),
    radial-gradient(38% 48% at 84% 72%, rgba(var(--accent-rgb), 0.32), transparent 80%);
}

.section-dark > .container {
  position: relative;
}

.section-dark .eyebrow {
  color: #ffb45e;
}

.section-dark .section-lead {
  color: rgba(255, 255, 255, 0.72);
}

/* Header / footer */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.82);
  /* saturate keeps the blurred hero photo vivid instead of milky */
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
  border-bottom: 1px solid rgba(227, 233, 240, 0.7);
  transition: background 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}

/* without the blur, 82% white over the dark hero photo is not enough ground
   for the nav text — go nearly opaque instead */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-header {
    background: rgba(255, 255, 255, 0.95);
  }
}

/* While the header sits over the hero photo / the dark intro band it goes
   transparent with white text — js/site.js toggles this as you scroll. With
   JS off the header simply keeps its glass look over the photo. */
.site-header.is-over-hero {
  background: linear-gradient(180deg, rgba(6, 14, 24, 0.5) 0%, rgba(6, 14, 24, 0) 100%);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom-color: transparent;
}

.admin-header {
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 24px;
  min-height: var(--header-h);
  flex-wrap: wrap;
}

/* below ~525px the logo + nav + phone pill stop fitting on one row and the
   pill wraps under them — keep --header-h honest about it */
@media (max-width: 530px) {
  :root {
    --header-h: 100px;
  }
}

.logo {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.3rem;
  text-decoration: none;
  color: var(--text);
  letter-spacing: 0.04em;
  transition: color 0.35s ease;
}

.logo span {
  color: var(--primary);
  transition: color 0.35s ease;
}

.logo small {
  font-weight: 400;
  color: var(--text-muted);
}

.site-header.is-over-hero .logo {
  color: #fff;
}

.site-header.is-over-hero .logo span {
  color: #64b5f6;
}

.main-nav {
  display: flex;
  gap: 26px;
  flex: 1;
}

.main-nav a {
  position: relative;
  padding: 4px 0;
  text-decoration: none;
  color: var(--text);
  font-weight: 500;
  transition: color 0.2s ease;
}

.main-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s var(--ease-out);
}

.main-nav a:hover {
  color: var(--primary);
}

.main-nav a:hover::after {
  transform: scaleX(1);
}

.site-header.is-over-hero .main-nav a {
  color: rgba(255, 255, 255, 0.9);
}

.site-header.is-over-hero .main-nav a:hover {
  color: #fff;
}

.header-phone {
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  color: var(--primary-dark);
  background: var(--primary-soft);
  border: 1px solid transparent;
  padding: 8px 18px;
  border-radius: 999px;
  transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.header-phone:hover {
  background: var(--primary);
  color: #fff;
}

.site-header.is-over-hero .header-phone {
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.32);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.site-header.is-over-hero .header-phone:hover {
  background: rgba(255, 255, 255, 0.24);
}

/* Hero: photo courtesy of the Buhta Kila partner page (buhtakila.ru).
   The pinned-photo effect is deliberately NOT background-attachment: fixed —
   that disables composited scrolling and repaints the full-viewport image
   every frame, which is exactly the scroll jank it caused here. Instead the
   photo lives on a position:fixed child (.hero-bg): a fixed layer costs
   nothing to scroll past, and unlike background-attachment this also works
   on iOS. clip-path is what turns the viewport-sized fixed layer into a
   window through the hero; without it the photo would show through every
   transparent section below. clip-path does not create a containing block
   for fixed descendants (transform/filter/contain would) — add one of those
   to .hero and the pinning silently dies. */
.hero {
  position: relative;
  clip-path: inset(0);
  /* Never remove this: the text below is white, and everything that makes it
     readable lives on .hero-bg. If that div is ever dropped from the template
     the headline lands on deep blue instead of on the white page. It is safe
     to paint under .hero-bg because clip-path makes .hero a stacking context,
     and a negative-z-index child paints AFTER its parent's background. */
  background: var(--primary-deep);
  color: #fff;
  display: flex;
  align-items: center;
  /* The hero pulls itself up under the sticky header (negative margin) and
     pads the same amount back, so the photo runs edge to edge behind the
     transparent header and the text still starts below it. Full viewport
     height: svh (small viewport) rather than lvh so the CTA is not pushed
     below the fold while the iOS toolbar is expanded; the plain vh line is
     the fallback for browsers without the unit. */
  margin-top: calc(-1 * var(--header-h));
  min-height: 100vh;
  min-height: 100svh;
  padding: calc(var(--header-h) + 48px) 0 96px;
}

/* flex centering: the container stops filling the row unless told to.
   NOT position: relative — .hero-scroll is absolute and must anchor to the
   hero's bottom edge, not to the container that ends at the stats row */
.hero > .container {
  width: 100%;
}

.hero-bg {
  /* Sized to the LARGE viewport rather than inset:0, so collapsing the iOS
     toolbar mid-scroll cannot resize this layer and make `cover` re-centre
     the photo — that shows up as a twitch exactly while scrolling. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 100vh;
  height: 100lvh;
  /* behind the hero's in-flow content, i.e. the text */
  z-index: -1;
  /* fallback while the photo loads (or if it never does) */
  background: var(--primary-deep);
  overflow: hidden;
}

/* The photo is an <img srcset> in the template, not a CSS background: the
   template's url_for gives it the ?v cache-buster (a CSS url() cannot), and
   srcset lets the browser pick a smaller variant where the pixels suffice
   (the sizes math lives in home.html — cover on this 100lvh layer is
   height-driven, so it is deliberately not 100vw). Both the img and the
   ::after scrim fill this fixed layer, so the scrim stays pinned WITH the
   photo — it must never move to .hero. The slow settle from 1.08 to 1 is
   the "Ken Burns" opening; transform on the img cannot break the fixed
   positioning of its parent. */
.hero-bg img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform-origin: 60% 50%;
  animation: hero-zoom 14s var(--ease-out) both;
}

@keyframes hero-zoom {
  from {
    transform: scale(1.08);
  }

  to {
    transform: scale(1);
  }
}

/* The scrim is two-sided: dark on the left where the headline sits and
   along the top edge under the transparent header, fading to nothing over
   the ATVs on the right, then sinking into ink at the bottom so the hero
   dissolves into the ticker below instead of ending in a hard line.
   ::after paints over the img by tree order — no z-index needed. */
.hero-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(100deg,
      rgba(6, 18, 32, 0.8) 0%,
      rgba(6, 18, 32, 0.5) 42%,
      rgba(6, 18, 32, 0.08) 74%),
    linear-gradient(180deg,
      rgba(6, 14, 24, 0.45) 0%,
      rgba(6, 14, 24, 0) 28%,
      rgba(6, 14, 24, 0) 62%,
      rgba(11, 20, 32, 0.92) 100%);
}

/* Entrance: kicker, headline, lead, buttons and stats rise in one after
   another. fill-mode both keeps the from-state until each delay elapses. */
.hero-kicker,
.hero h1,
.hero-sub,
.hero-actions,
.hero-stats {
  animation: hero-in 0.9s var(--ease-out) both;
}

.hero h1 {
  animation-delay: 0.1s;
}

.hero-sub {
  animation-delay: 0.25s;
}

.hero-actions {
  animation-delay: 0.38s;
}

.hero-stats {
  animation-delay: 0.55s;
}

@keyframes hero-in {
  from {
    opacity: 0;
    transform: translateY(26px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.hero-kicker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 24px;
  padding: 8px 16px 8px 11px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.24);
  background: rgba(255, 255, 255, 0.1);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.live-dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.6);
  animation: live-pulse 2.2s ease-out infinite;
}

@keyframes live-pulse {
  70% {
    box-shadow: 0 0 0 9px rgba(var(--accent-rgb), 0);
  }

  100% {
    box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0);
  }
}

.hero h1 {
  font-size: clamp(2.5rem, 6.4vw, 4.6rem);
  line-height: 0.98;
  letter-spacing: 0.005em;
  margin: 0 0 24px;
  max-width: 16ch;
  text-shadow: 0 4px 28px rgba(3, 12, 24, 0.55);
}

/* the second line of the headline in the sunset gradient. Clipped text
   cannot carry a text-shadow (it would show through the letters), so the
   glow is a drop-shadow filter instead. */
.hero-title-accent {
  display: block;
  color: #ffb45e;
  text-shadow: none;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero-title-accent {
    background: var(--accent-grad);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    filter: drop-shadow(0 6px 22px rgba(var(--accent-rgb), 0.3));
  }
}

.hero-sub {
  font-size: clamp(1.05rem, 1.7vw, 1.25rem);
  /* medium weight: regular strokes dissolve into the busy photo where the
     scrim has already faded */
  font-weight: 500;
  color: rgba(255, 255, 255, 0.9);
  max-width: 540px;
  margin: 0 0 34px;
  text-shadow: 0 1px 8px rgba(7, 26, 44, 0.55);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

.hero-stats {
  list-style: none;
  margin: 48px 0 0;
  padding: 24px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 18px 44px;
  border-top: 1px solid rgba(255, 255, 255, 0.22);
}

.hero-stats li {
  min-width: 120px;
}

/* a phone gets two figures per row instead of a tower of three */
@media (max-width: 600px) {
  .hero-stats {
    gap: 18px 24px;
  }

  .hero-stats li {
    flex: 1 1 40%;
    min-width: 0;
  }

  /* the pill cannot hold the kicker on one line here — plain text wraps
     more gracefully than a two-line capsule */
  .hero-kicker {
    padding: 0;
    border: 0;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    font-size: 0.72rem;
    line-height: 1.6;
    text-shadow: 0 1px 6px rgba(7, 26, 44, 0.6);
  }
}

.hero-stats strong {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.9rem, 3.6vw, 2.7rem);
  line-height: 1;
  margin-bottom: 4px;
  text-shadow: 0 2px 14px rgba(3, 12, 24, 0.5);
}

.hero-stats span {
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.8);
}

/* a small "mouse" at the bottom edge whose wheel drifts down — the one
   invitation to scroll a full-screen hero needs */
.hero-scroll {
  position: absolute;
  left: 50%;
  bottom: 28px;
  width: 26px;
  height: 42px;
  margin-left: -13px;
  border: 2px solid rgba(255, 255, 255, 0.55);
  border-radius: 14px;
  opacity: 0;
  animation: hero-in 0.9s var(--ease-out) 1.1s both;
}

.hero-scroll::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 8px;
  width: 4px;
  height: 8px;
  margin-left: -2px;
  border-radius: 2px;
  background: #fff;
  animation: hero-wheel 1.8s ease-in-out infinite;
}

@keyframes hero-wheel {
  0% {
    opacity: 0;
    transform: translateY(0);
  }

  30% {
    opacity: 1;
  }

  100% {
    opacity: 0;
    transform: translateY(14px);
  }
}

@media (max-height: 640px), (max-width: 600px) {
  .hero-scroll {
    display: none;
  }
}

/* Ticker: one endless line under the hero. The track holds the list FOUR
   times and slides by exactly one copy (a quarter), so every frame is
   identical to the one a cycle earlier — no seam. Four rather than two
   because the loop is only seamless while the copies still on screen cover
   the viewport: one copy of the Russian strings is ~1.7k px, and a 2560 px
   monitor would see bare ink at the end of each cycle with just two. */
.ticker {
  position: relative;
  overflow: hidden;
  background: var(--ink);
  color: #fff;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.ticker-track {
  display: flex;
  width: max-content;
  animation: ticker 40s linear infinite;
}

.ticker:hover .ticker-track {
  animation-play-state: paused;
}

.ticker-list {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
}

.ticker-list li {
  display: inline-flex;
  align-items: center;
  gap: 26px;
  padding: 15px 26px 15px 0;
  font-family: var(--font-display);
  font-size: 0.92rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}

.ticker-list li::after {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}

@keyframes ticker {
  to {
    transform: translateX(-25%);
  }
}

/* Buttons */
.btn {
  display: inline-block;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 10px 22px;
  font-size: 1rem;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  background: var(--bg-alt);
  color: var(--text);
  transition: background 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease, filter 0.2s ease, border-color 0.2s ease;
}

.btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.btn:active {
  transform: none;
  box-shadow: none;
}

.btn-primary {
  position: relative;
  overflow: hidden;
  background: var(--primary-grad);
  color: #fff;
  box-shadow: var(--shadow-sm);
}

/* a light sweep crosses the button on hover — the gradient itself cannot
   transition, so this is what makes the CTA feel alive. Moved with a
   transform (compositor only), never with `left` (a layout per frame). */
.btn-primary::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 45%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  transform: translateX(-160%) skewX(-20deg);
  transition: transform 0.6s ease;
}

.btn-primary:hover {
  filter: brightness(1.08);
  box-shadow: var(--shadow-primary);
}

.btn-primary:hover::after {
  transform: translateX(290%) skewX(-20deg);
}

/* frosted white button for dark grounds (hero, CTA band) */
.btn-glass {
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.4);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.btn-glass:hover {
  background: rgba(255, 255, 255, 0.24);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

.btn-lg {
  padding: 16px 36px;
  font-size: 1.1rem;
  font-weight: 600;
  border-radius: 999px;
}

/* the glow belongs to the color, not the size: a large secondary button must
   not pick up a brand-blue halo */
.btn-primary.btn-lg {
  box-shadow: var(--shadow-primary);
}

.btn-block {
  width: 100%;
}

.btn-ghost {
  background: transparent;
  border-color: var(--border);
  padding: 6px 12px;
  font-size: 0.9rem;
}

.btn-danger,
.btn-ghost.btn-danger {
  color: var(--error);
  border-color: var(--error);
  background: transparent;
}

.btn-danger:not(.btn-ghost) {
  background: var(--error);
  color: #fff;
}

.inline-form {
  display: inline;
}

/* Tour and ATV cards share one visual language — every rule that is the same
   for both lives here once; only the body internals differ below */
.tour-grid,
.atv-grid {
  display: grid;
  gap: 28px;
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
}

.tour-card,
.atv-card {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg);
  box-shadow: var(--shadow-sm);
  transition: transform 0.4s var(--ease-out), box-shadow 0.4s ease, border-color 0.4s ease;
}

.tour-card:hover,
.atv-card:hover {
  transform: translateY(-8px);
  border-color: transparent;
  box-shadow: var(--shadow-lg);
}

/* A column flex chain from the grid item down to the link: the grid stretches
   every card to the tallest in its row, and each level passes that height on
   so the last body element can be pushed down with margin-top: auto. Without
   it the meta/link floats directly under the description and lands at a
   different height in every card — the ragged edge reads as broken alignment. */
.tour-card-link,
.atv-card-link {
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* the photo frame: the image scales inside it on hover without pushing the
   body around; flex-shrink: 0 holds the frame when the body grows past the
   card. The price / spec chip sits in its bottom-left corner. */
.tour-card-media,
.atv-card-media {
  position: relative;
  display: block;
  overflow: hidden;
  flex: 0 0 auto;
}

/* the photo keeps one frame whatever the upload's aspect ratio, so a portrait
   shot cannot stretch its card taller than the rest of the row */
.tour-card img,
.tour-card-placeholder,
.atv-card img,
.atv-card-placeholder {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  background: var(--bg-alt);
}

.tour-card img,
.atv-card img {
  transition: transform 0.8s var(--ease-out);
}

.tour-card:hover img,
.atv-card:hover img {
  transform: scale(1.07);
}

/* no upload yet: an ink-to-blue gradient with the brand glow, not a grey box */
.tour-card-placeholder,
.atv-card-placeholder {
  display: block;
  background:
    radial-gradient(60% 70% at 80% 20%, rgba(var(--accent-rgb), 0.35), transparent 70%),
    linear-gradient(135deg, var(--ink-3) 0%, var(--primary-deep) 100%);
}

/* the bottom of the photo darkens so the chip and the card body read as one
   piece; ::after paints over the img by tree order */
.tour-card-media::after,
.atv-card-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(6, 14, 24, 0) 50%, rgba(6, 14, 24, 0.55) 100%);
  pointer-events: none;
}

.card-chip {
  position: absolute;
  z-index: 1;
  left: 16px;
  bottom: 14px;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.94);
  color: var(--primary-deep);
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.4;
  box-shadow: var(--shadow-sm);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.tour-card-body,
.atv-card-body {
  padding: 20px 22px 22px;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
}

.tour-card-body h3,
.atv-card-body h3 {
  margin: 0 0 8px;
  font-size: 1.2rem;
  line-height: 1.25;
}

.tour-card-body p {
  margin: 0 0 14px;
  color: var(--text-muted);
  font-size: 0.95rem;
}

.tour-card-meta {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  font-size: 0.92rem;
  color: var(--text-muted);
}

.tour-card-meta .price {
  color: var(--primary);
  font-weight: 700;
  font-size: 1.05rem;
}

/* "Details" with an arrow that slides away from the word on hover;
   margin-left: auto keeps it on the right when there is no duration */
.card-more {
  display: inline-flex;
  margin-left: auto;
  align-items: center;
  gap: 6px;
  color: var(--primary);
  font-weight: 600;
  font-size: 0.95rem;
  transition: gap 0.25s var(--ease-out);
}

.tour-card:hover .card-more,
.atv-card:hover .card-more {
  gap: 12px;
}

/* Inner-page intro: breadcrumbs + title on the dark aurora band. Like the
   hero it pulls itself up under the header so the band shows through the
   transparent header state. */
.page-intro {
  margin-top: calc(-1 * var(--header-h));
  padding: calc(var(--header-h) + 36px) 0 48px;
}

.page-intro h1 {
  margin: 8px 0 0;
  font-size: clamp(1.9rem, 4.6vw, 3.2rem);
  text-shadow: 0 4px 24px rgba(3, 12, 24, 0.4);
}

.page-intro .section-lead {
  margin-top: 14px;
}

/* room for the cover photo that rises up into the band (see .tour-hero) */
.page-intro-overlap {
  padding-bottom: 130px;
}

.page-intro + .section {
  padding-top: 40px;
}

.breadcrumbs {
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.65);
  margin: 0;
}

.breadcrumbs a {
  color: rgba(255, 255, 255, 0.85);
  text-decoration: none;
}

.breadcrumbs a:hover {
  color: #fff;
  text-decoration: underline;
}

/* duration / price chips under the tour title */
.tour-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 18px 0 0;
}

.tour-meta span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.24);
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.92);
  font-size: 0.95rem;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.tour-meta .price {
  color: #fff;
  font-weight: 700;
  background: rgba(var(--accent-rgb), 0.28);
  border-color: rgba(var(--accent-rgb), 0.55);
}

/* the cover rises out of the intro band: negative margin equal to the extra
   room .page-intro-overlap reserved. Section is not a stacking context, so
   z-index lifts the photo over the band's edge. */
.tour-hero,
.atv-hero {
  position: relative;
  z-index: 1;
  display: block;
  cursor: zoom-in;
  margin: -140px 0 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}

.tour-hero img,
.atv-hero img {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
  transition: transform 0.8s var(--ease-out);
}

.tour-hero:hover img,
.atv-hero:hover img {
  transform: scale(1.03);
}

.tour-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: 40px;
  margin-top: 40px;
}

@media (max-width: 900px) {
  .tour-layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

.tour-description > :first-child,
.atv-description > :first-child {
  margin-top: 0;
}

.tour-description {
  font-size: 1.05rem;
}

.tour-gallery,
.atv-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px;
  margin: 24px 0;
}

.tour-gallery a,
.atv-gallery a {
  display: block;
  border-radius: var(--radius-sm);
  overflow: hidden;
  cursor: zoom-in;
  box-shadow: var(--shadow-sm);
}

.tour-gallery img,
.atv-gallery img {
  aspect-ratio: 4/3;
  object-fit: cover;
  transition: transform 0.5s var(--ease-out);
}

.tour-gallery a:hover img,
.atv-gallery a:hover img {
  transform: scale(1.06);
}

.tour-video {
  margin: 16px 0;
  border-radius: var(--radius-sm);
}

/* Nearest-ride card on the home page: the one thing on the page with a date
   on it, so it gets the dark cinematic treatment instead of a white card */
.nearest-session-section {
  padding-bottom: 0;
}

.nearest-session {
  position: relative;
  display: grid;
  /* photo | text. minmax(0,…) or a wide photo would refuse to shrink and push
     the text column past the container on narrow desktops */
  grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-lg);
  color: #fff;
  background:
    radial-gradient(50% 70% at 100% 0%, rgba(var(--primary-rgb), 0.45), transparent 70%),
    radial-gradient(40% 60% at 30% 100%, rgba(var(--accent-rgb), 0.22), transparent 70%),
    linear-gradient(135deg, var(--ink-3) 0%, var(--ink) 70%);
  box-shadow: var(--shadow-lg);
}

.nearest-session-textonly {
  grid-template-columns: minmax(0, 1fr);
}

.nearest-session-media {
  position: relative;
  /* the photo cell has no intrinsic height of its own — without this it
     collapses to the image's aspect ratio and the card looks torn in half */
  min-height: 100%;
}

.nearest-session-media img {
  width: 100%;
  height: 100%;
  min-height: 280px;
  object-fit: cover;
  display: block;
}

/* the photo blends into the dark body on its right edge */
.nearest-session-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(11, 20, 32, 0) 70%, rgba(11, 20, 32, 0.6) 100%);
  pointer-events: none;
}

.nearest-session-body {
  padding: 36px 38px;
}

.nearest-session h3 {
  margin: 2px 0 12px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1.1;
  letter-spacing: 0.01em;
}

.nearest-session-badge {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  color: #ffb45e;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
}

.nearest-session-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #4ade80;
  box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.55);
  animation: nearest-pulse 2.4s ease-out infinite;
}

@keyframes nearest-pulse {
  70% {
    box-shadow: 0 0 0 9px rgba(74, 222, 128, 0);
  }

  100% {
    box-shadow: 0 0 0 0 rgba(74, 222, 128, 0);
  }
}

.nearest-session-when {
  margin: 0 0 4px;
  font-size: clamp(1.25rem, 2.6vw, 1.55rem);
  font-weight: 700;
  color: #fff;
}

.nearest-session-lead {
  margin: 0 0 16px;
  color: rgba(255, 255, 255, 0.78);
  max-width: 52ch;
}

/* the tour's own description, written by the admin — the markup inside is
   whatever nh3 let through, so every child needs a sane default here */
.nearest-session-description {
  margin: 0 0 18px;
  max-width: 62ch;
  color: rgba(255, 255, 255, 0.78);
}

.nearest-session-description > :first-child {
  margin-top: 0;
}

.nearest-session-description > :last-child {
  margin-bottom: 0;
}

.nearest-session-description p {
  margin: 0 0 10px;
}

.nearest-session-description ul,
.nearest-session-description ol {
  margin: 0 0 10px;
  padding-left: 20px;
}

.nearest-session-description li {
  margin-bottom: 4px;
}

/* an admin heading must not out-shout the tour title above it */
.nearest-session-description h2,
.nearest-session-description h3,
.nearest-session-description h4 {
  margin: 14px 0 6px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1.05rem;
  text-transform: none;
  letter-spacing: 0;
  color: #fff;
}

.nearest-session-description a {
  color: #90caf9;
}

.nearest-session-description img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

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

.nearest-session-facts li {
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  padding: 5px 14px;
  background: rgba(255, 255, 255, 0.08);
  font-size: 0.92rem;
  color: rgba(255, 255, 255, 0.88);
}

.nearest-session-group {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin: 0 0 22px;
  font-size: 0.98rem;
}

.nearest-session-riders {
  color: rgba(255, 255, 255, 0.72);
}

.nearest-session-seats {
  color: #4ade80;
  font-weight: 600;
}

/* few machines left — the one number on this card worth a second glance */
.nearest-session-seats.is-scarce {
  color: #ffb45e;
}

.nearest-session-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 22px;
}

.nearest-session-more {
  color: #90caf9;
  font-weight: 500;
  text-decoration: none;
}

.nearest-session-more:hover {
  text-decoration: underline;
}

.nearest-session-hint {
  margin: 14px 0 0;
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.6);
  max-width: 58ch;
}

@media (max-width: 860px) {
  .nearest-session {
    grid-template-columns: minmax(0, 1fr);
  }

  .nearest-session-media img {
    min-height: 200px;
    max-height: 260px;
  }

  .nearest-session-media::after {
    background: linear-gradient(180deg, rgba(11, 20, 32, 0) 60%, rgba(11, 20, 32, 0.7) 100%);
  }

  .nearest-session-body {
    padding: 26px 22px;
  }
}

/* Fleet section on the home page */
.atv-card-more {
  display: inline-block;
  margin-top: auto;  /* the whole point: pin to the bottom of the card */
  padding-top: 14px;
  border-top: 1px solid var(--border);
  color: var(--primary);
  font-weight: 600;
  font-size: 0.95rem;
}

.atv-card-body p {
  margin: 0 0 14px;
  color: var(--text-muted);
  font-size: 0.95rem;
}

.atv-specs {
  list-style: none;
  padding: 0;
  margin: 0 0 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
}

.atv-specs li {
  background: var(--bg-alt);
  border-radius: 999px;
  padding: 3px 12px;
  font-size: 0.85rem;
  color: var(--text-muted);
  white-space: nowrap;
}

/* ATV detail page — same visual language as the tour page, so the rules are
   shared rather than duplicated (see .tour-hero / .tour-gallery / .tour-layout) */
.atv-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 40px;
  margin-top: 40px;
}

@media (max-width: 900px) {
  .atv-layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

.atv-panel {
  position: relative;
  overflow: hidden;
  background: linear-gradient(160deg, var(--ink-3) 0%, var(--ink) 100%);
  color: #fff;
  border-radius: var(--radius-lg);
  padding: 26px 26px 28px;
  align-self: start;
  box-shadow: var(--shadow-lg);
}

.atv-panel::before {
  content: "";
  position: absolute;
  inset: -40% -40% auto auto;
  width: 70%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--primary-rgb), 0.5), transparent 70%);
  pointer-events: none;
}

.atv-panel > * {
  position: relative;
}

.atv-panel h2 {
  margin: 0 0 16px;
  font-size: 1.4rem;
}

.atv-panel .muted {
  color: rgba(255, 255, 255, 0.72);
}

.atv-spec-list {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 16px;
  margin: 0 0 18px;
}

.atv-spec-list dt {
  color: rgba(255, 255, 255, 0.65);
}

.atv-spec-list dd {
  margin: 0;
  font-weight: 700;
}

.atv-panel-phone {
  margin: 14px 0 0;
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.72);
}

.atv-panel-phone a {
  color: #fff;
  font-weight: 600;
}

/* "Why us" — frosted cards on the dark aurora section */
.features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
  gap: 22px;
}

.feature {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.11);
  border-radius: var(--radius-lg);
  padding: 30px 28px 28px;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition: transform 0.35s var(--ease-out), background 0.35s ease, border-color 0.35s ease;
}

.feature:hover {
  transform: translateY(-5px);
  background: rgba(255, 255, 255, 0.09);
  border-color: rgba(255, 255, 255, 0.26);
}

.feature-icon {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  margin-bottom: 20px;
  border-radius: 16px;
  color: #fff;
  background: linear-gradient(135deg, rgba(var(--primary-rgb), 0.55), rgba(var(--accent-rgb), 0.35));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}

.feature-icon svg {
  width: 26px;
  height: 26px;
}

.feature h3 {
  margin: 0 0 8px;
  font-size: 1.15rem;
}

.feature p {
  margin: 0;
  color: rgba(255, 255, 255, 0.72);
}

/* "How it works" — four numbered steps joined by a dotted line on wide screens */
.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
  gap: 22px;
}

.step {
  position: relative;
  padding: 28px 24px 26px;
  border-radius: var(--radius-lg);
  background: var(--bg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  transition: transform 0.35s var(--ease-out), box-shadow 0.35s ease;
}

.step:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-md);
}

/* outlined numeral — text-stroke is the whole look; browsers without it get
   a plain blue digit via the color fallback */
.step-num {
  display: block;
  margin-bottom: 14px;
  font-family: var(--font-display);
  font-size: 2.8rem;
  line-height: 1;
  color: var(--primary);
}

@supports (-webkit-text-stroke: 1px #000) {
  .step-num {
    color: transparent;
    -webkit-text-stroke: 1.5px var(--primary);
  }
}

.step h3 {
  margin: 0 0 8px;
  font-size: 1.12rem;
}

.step p {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.95rem;
}

/* Closing CTA band before the footer */
.cta-band {
  position: relative;
  overflow: hidden;
  padding: 88px 0;
  color: #fff;
  background:
    radial-gradient(45% 80% at 85% 50%, rgba(var(--accent-rgb), 0.45), transparent 70%),
    linear-gradient(120deg, var(--primary-dark) 0%, var(--primary) 55%, var(--primary-bright) 100%);
}

.cta-band-inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px 48px;
  flex-wrap: wrap;
}

.cta-band .eyebrow {
  color: #ffd08a;
}

.cta-band .eyebrow::before {
  background: #ffd08a;
}

.cta-band h2 {
  margin: 0 0 12px;
  font-size: clamp(1.8rem, 4vw, 2.8rem);
  text-shadow: 0 4px 24px rgba(3, 12, 24, 0.3);
}

.cta-band p {
  margin: 0;
  max-width: 52ch;
  color: rgba(255, 255, 255, 0.86);
  font-size: 1.05rem;
}

.cta-band-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 22px;
}

/* the primary button sits on a ground that is already brand-blue — a white
   button is what stands out there */
.cta-band .btn-primary {
  background: #fff;
  color: var(--primary-dark);
  box-shadow: 0 10px 30px rgba(3, 12, 24, 0.25);
}

.cta-band .btn-primary::after {
  background: linear-gradient(90deg, transparent, rgba(var(--primary-rgb), 0.18), transparent);
}

.cta-band-phone {
  color: #fff;
  font-family: var(--font-display);
  font-size: 1.3rem;
  letter-spacing: 0.02em;
  text-decoration: none;
  white-space: nowrap;
}

.cta-band-phone:hover {
  text-decoration: underline;
}

/* Lightbox: the <dialog> element supplies Esc-to-close and the focus trap,
   here it is stretched to the full viewport so a click outside the photo
   lands on the dialog itself — that is how lightbox.js detects backdrop
   clicks. */
.lightbox {
  border: 0;
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  max-width: 100vw;
  max-height: 100vh;
  /* dvh tracks the iOS toolbar so the close button stays reachable;
     the vh lines above are the fallback for browsers without it */
  height: 100dvh;
  max-height: 100dvh;
  background: transparent;
  display: none;
  align-items: center;
  justify-content: center;
  /* overflow:hidden on body does not stop iOS touch scrolling — the overlay
     itself has to refuse to scroll and to pass scrolling through.
     touch-action: none is also what lets a touch drag pan the zoomed photo
     (lightbox.js), and it costs native pinch-zoom inside the overlay: the
     deliberate trade is tap-to-zoom + drag instead of pinch. Restoring pinch
     means tracking two pointers by hand, not deleting this line — deleting it
     gives the page back to the scroller. */
  overscroll-behavior: contain;
  touch-action: none;
}

.lightbox[open] {
  display: flex;
}

.lightbox::backdrop {
  background: rgba(9, 16, 24, 0.92);
}

.lightbox figure {
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius-sm);
}

.lightbox img {
  max-width: min(94vw, 1600px);
  max-height: 86vh;
  width: auto;
  height: auto;
  cursor: zoom-in;
  transition: transform 0.25s ease;
}

.lightbox img.is-zoomed {
  transform: scale(2.2);
  cursor: zoom-out;
}

.lightbox button {
  position: fixed;
  z-index: 1;
  border: 0;
  border-radius: 999px;
  width: 44px;
  height: 44px;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease;
}

.lightbox button:hover {
  background: rgba(255, 255, 255, 0.28);
}

.lightbox-close {
  top: 16px;
  right: 16px;
}

.lightbox-prev {
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
}

.lightbox-next {
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
}

.lightbox-counter {
  position: fixed;
  bottom: 12px;
  left: 0;
  right: 0;
  margin: 0;
  text-align: center;
  color: rgba(255, 255, 255, 0.75);
  font-size: 0.9rem;
}

.lightbox-open {
  overflow: hidden;
}

/* Booking form */
.booking-panel {
  position: sticky;
  top: calc(var(--header-h) + 16px);
  align-self: start;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px 26px 26px;
  background: var(--bg);
  box-shadow: var(--shadow-lg);
  /* brand stripe along the top edge — border-image would kill the radius */
  background-image: linear-gradient(90deg, var(--primary-bright), var(--primary-dark) 60%, var(--accent));
  background-repeat: no-repeat;
  background-size: 100% 5px;
}

.booking-panel h2 {
  margin: 0 0 18px;
  font-size: 1.45rem;
}

.field {
  margin-bottom: 14px;
}

.field label {
  display: block;
  font-weight: 500;
  margin-bottom: 4px;
  font-size: 0.95rem;
}

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="date"],
.field input[type="number"],
.field input[type="password"],
.field select,
.field textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  background: var(--bg-alt);
  transition: border-color 0.2s ease, background 0.2s ease;
}

.field input:hover,
.field select:hover,
.field textarea:hover {
  border-color: var(--primary);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 2px solid var(--primary);
  outline-offset: -1px;
  background: var(--bg);
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

/* the inputs line up even when one label wraps to two lines ("Количество
   квадроциклов" next to "Дата") — the label takes the slack, not the input */
.field-row .field {
  display: flex;
  flex-direction: column;
}

.field-row .field label {
  flex: 1 0 auto;
}

.field-row .field .flatpickr-input+input {
  margin-top: 0;
}

.field-error input,
.field-error select,
.field-error textarea {
  border-color: var(--error);
}

/* Flatpickr theme: match site colors */
.flatpickr-day.selected,
.flatpickr-day.selected:hover {
  background: var(--primary);
  border-color: var(--primary);
}

.flatpickr-day.today {
  border-color: var(--primary);
}

.flatpickr-day.today:hover,
.flatpickr-day.today:focus {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

.flatpickr-months .flatpickr-prev-month:hover svg,
.flatpickr-months .flatpickr-next-month:hover svg {
  fill: var(--primary);
}

.error {
  color: var(--error);
  font-size: 0.88rem;
  margin: 4px 0 0;
}

.checkbox {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  font-weight: 400 !important;
}

.checkbox input {
  margin-top: 3px;
}

.field-website {
  position: absolute;
  left: -9999px;
  top: -9999px;
  height: 0;
  overflow: hidden;
}

.booking-note {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin: 10px 0 0;
}

.availability {
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  margin: 0 0 12px;
}

.availability-ok {
  background: #e8f5e9;
  color: var(--success);
}

.availability-warn {
  background: #fff3e0;
  color: var(--warn);
}

.availability-none {
  background: #ffebee;
  color: var(--error);
}

.availability-unknown {
  background: var(--bg-alt);
  color: var(--text-muted);
}

.availability-price {
  font-size: 1.05rem;
  margin: 0 0 12px;
}

.booking-success {
  text-align: center;
  padding: 20px 8px;
}

.booking-success h3,
.booking-success h1 {
  color: var(--success);
}

/* the full "thank you" page: a big check mark over the summary */
.booking-success-page {
  padding: 24px 8px 8px;
}

.booking-success-page h1 {
  font-size: clamp(1.6rem, 3.6vw, 2.4rem);
}

.success-mark {
  display: grid;
  place-items: center;
  width: 84px;
  height: 84px;
  margin: 0 auto 8px;
  border-radius: 50%;
  color: #fff;
  background: linear-gradient(135deg, #43a047, #2e7d32);
  box-shadow: 0 12px 30px rgba(46, 125, 50, 0.3);
  animation: pop-in 0.6s var(--ease-out) both;
}

.success-mark svg {
  width: 40px;
  height: 40px;
}

@keyframes pop-in {
  from {
    opacity: 0;
    transform: scale(0.6);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* Contacts: one card per channel, the map underneath */
/* two wide columns, not four narrow ones: an e-mail address must never be
   broken mid-word just to fit a card */
.contact-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

@media (max-width: 640px) {
  .contact-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.contact-card {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  padding: 24px 22px;
  border-radius: var(--radius-lg);
  background: var(--bg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  /* same free-text address as the footer — keep a long token inside the card */
  min-width: 0;
  overflow-wrap: anywhere;
  transition: transform 0.35s var(--ease-out), box-shadow 0.35s ease;
}

.contact-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
}

.contact-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  color: #fff;
  background: var(--primary-grad);
}

.contact-icon svg {
  width: 22px;
  height: 22px;
}

.contact-card h3 {
  margin: 0 0 4px;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.contact-card p {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 500;
}

.contact-card a {
  text-decoration: none;
}

.contact-card a:hover {
  text-decoration: underline;
}

.socials {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.socials a {
  display: inline-flex;
  align-items: center;
  padding: 8px 18px;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text);
  font-weight: 500;
  text-decoration: none;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.socials a:hover {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

.contacts-socials {
  margin-top: 28px;
}

.map-embed {
  margin-top: 32px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

.map-embed iframe {
  width: 100%;
  min-height: 400px;
  border: 0;
  display: block;
}

.legal h2 {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1.2rem;
  text-transform: none;
  letter-spacing: 0;
}

.error-page {
  text-align: center;
  padding: 48px 0;
}

/* the maintenance page has no site header — it carries its own logo */
.error-page .logo {
  display: inline-block;
  margin-bottom: 16px;
}

/* the big outlined status code above the message */
.error-code {
  display: block;
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: clamp(5rem, 18vw, 9rem);
  line-height: 1;
  color: var(--primary);
}

@supports (-webkit-text-stroke: 1px #000) {
  .error-code {
    color: transparent;
    -webkit-text-stroke: 2px var(--primary);
  }
}

.error-page p {
  color: var(--text-muted);
  max-width: 48ch;
  margin: 0 auto 24px;
}

/* Footer */
.site-footer {
  color: #eceff1;
  padding: 64px 0 32px;
}

.site-footer a {
  color: #90caf9;
  text-decoration: none;
}

.site-footer a:hover {
  color: #fff;
  text-decoration: underline;
}

.footer-inner {
  display: grid;
  /* min(220px, 100%): a viewport narrower than the column floor shrinks the
     column instead of pushing it past the right edge */
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 36px 32px;
}

/* the address and working hours are free text from the admin — a long token
   (a map link, an address typed without spaces) must wrap inside its column
   rather than push the footer wider than the viewport. min-width: 0 lets the
   grid item shrink below its content; overflow-wrap does the actual wrapping */
.footer-inner > div {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* the browser's 1em paragraph margins put the first line of the phone and
   policy columns 16px below the logo — drop them so the columns share a top
   edge and the stacked mobile layout does not double up gap + margin */
.footer-inner p {
  margin: 0 0 10px;
  color: rgba(255, 255, 255, 0.78);
}

.footer-inner p:last-child {
  margin-bottom: 0;
}

.footer-heading {
  margin: 0 0 14px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}

.logo-footer {
  display: inline-block;
  color: #fff;
  font-size: 1.6rem;
  margin-bottom: 10px;
}

.footer-tagline {
  max-width: 34ch;
}

.site-footer .socials a {
  border-color: rgba(255, 255, 255, 0.2);
  color: #fff;
}

.site-footer .socials a:hover {
  background: #fff;
  border-color: #fff;
  color: var(--ink);
  text-decoration: none;
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
  margin-top: 48px;
  padding-top: 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 0.9rem;
}

.copyright {
  color: rgba(255, 255, 255, 0.55);
}

/* Admin */
.admin-body {
  background: var(--bg-alt);
}

.admin-body h1,
.admin-body h2 {
  font-family: var(--font-body);
  font-weight: 700;
  text-transform: none;
  letter-spacing: -0.01em;
}

.admin-main {
  padding: 24px 16px 48px;
}

.page-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.panel {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  margin: 20px 0;
}

.panel-danger {
  border-color: var(--error);
}

.login-box {
  max-width: 380px;
  margin: 60px auto;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
  box-shadow: var(--shadow-sm);
}

.flash {
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  margin: 12px 0;
}

.flash-success {
  background: #e8f5e9;
  color: var(--success);
}

.flash-error {
  background: #ffebee;
  color: var(--error);
}

.table {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg);
  font-size: 0.95rem;
}

.table th,
.table td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

.table th {
  background: var(--bg-alt);
  font-weight: 500;
}

.table-bookings {
  display: block;
  overflow-x: auto;
}

.badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 500;
  background: var(--bg-alt);
  color: var(--text-muted);
}

.badge-new {
  background: #e3f2fd;
  color: var(--primary);
}

.badge-delivering {
  background: #fff8e1;
  color: #b28704;
}

.badge-delivered {
  background: #e8f5e9;
  color: var(--success);
}

.badge-failed {
  background: #ffebee;
  color: var(--error);
}

.badge-unavailable {
  background: #fff3e0;
  color: var(--warn);
}

.badge-cancelled {
  background: #eceff1;
  color: var(--text-muted);
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin: 20px 0;
}

.stat {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  text-decoration: none;
  color: inherit;
  text-align: center;
}

.stat-value {
  display: block;
  font-size: 1.8rem;
  font-weight: 700;
}

.stat-label {
  color: var(--text-muted);
  font-size: 0.85rem;
}

.filter-nav {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.filter-nav a {
  text-decoration: none;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text);
  font-size: 0.9rem;
}

.filter-nav a.active {
  background: var(--primary-grad);
  color: #fff;
  border-color: transparent;
}

.media-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 20px;
}

.media-item {
  margin: 0;
}

.media-item img {
  border-radius: var(--radius-sm);
}

.media-item figcaption {
  display: flex;
  gap: 6px;
  margin-top: 6px;
  flex-wrap: wrap;
}

.video-list {
  padding-left: 18px;
}

.video-list li {
  margin-bottom: 8px;
}

.actions {
  white-space: nowrap;
}

.actions .btn {
  margin-bottom: 4px;
}

/* Scroll reveal: js/site.js adds .has-reveal to <html> only once it has an
   IntersectionObserver ready to flip .is-visible on — so with JS off, a
   blocked script or reduced motion nothing is ever hidden. --i is the
   card's index in its grid, set inline by the template, for the stagger.

   Only the HIDDEN state is styled: a `.is-visible { transform: none }` rule
   would outrank every card's :hover lift for good. The transition list
   replaces the cards' own (higher specificity), so it carries their hover
   properties too — and the delay is cleared once visible, or every hover
   would wait for the stagger. */
.has-reveal .reveal {
  transition: opacity 0.7s var(--ease-out), transform 0.5s var(--ease-out),
    box-shadow 0.4s ease, border-color 0.4s ease, background 0.35s ease;
}

.has-reveal .reveal:not(.is-visible) {
  opacity: 0;
  transform: translateY(28px);
  transition-delay: calc(var(--i, 0) * 90ms);
}

/* Motion is decoration here — anyone who asked the OS to reduce it gets the
   same layout with everything simply appearing in place. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
  }

  .tour-card:hover,
  .atv-card:hover,
  .feature:hover,
  .step:hover,
  .contact-card:hover,
  .btn:hover {
    transform: none;
  }

  .tour-card:hover img,
  .atv-card:hover img,
  .tour-hero:hover img,
  .atv-hero:hover img,
  .tour-gallery a:hover img,
  .atv-gallery a:hover img {
    transform: none;
  }

  /* a pinned hero background is parallax — content sliding over a stationary
     photo is exactly the motion this setting asks to avoid; absolute makes
     the photo scroll with the hero like a plain background, and height:100%
     resizes it from the viewport back to the hero box */
  .hero-bg {
    position: absolute;
    height: 100%;
  }

  .hero-scroll {
    display: none;
  }
}
