
/* ============================================================
   CostaBlancaScoot — site.css
   Mobile-first. Grouped: tokens, reset, layout, type, components.
   ============================================================ */

:root {
  --costa: #0F5C8C;
  --deep: #0A3D5D;
  --sol: #FFB020;
  --coral: #F4623A;
  --sand: #FBF4E4;
  --ink: #17324A;
  --green: #1F7A4D;
  --green-bg: #E7F3EC;
  --line: #EDE4CE;
  --muted: #5B6B7A;
  --white: #fff;

  --radius: 14px;
  --radius-sm: 8px;

  --space-xs: .35rem;
  --space-sm: .7rem;
  --space-md: 1.15rem;
  --space-lg: 2rem;
  --space-xl: 3.25rem;
  --space-2xl: 4.5rem;

  --content: 75rem;
  --prose: 68ch;

  --kop: 'Baloo 2', 'Arial Rounded MT Bold', 'Trebuchet MS', sans-serif;
  --tekst: 'Atkinson Hyperlegible', Verdana, 'Segoe UI', sans-serif;
}

/* ---------- fonts (self-hosted, no external requests) ---------- */
@font-face {
  font-family: 'Baloo 2'; font-style: normal; font-weight: 500 800;
  font-display: swap; src: url(/assets/fonts/baloo2-latin.26fb4610.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Baloo 2'; font-style: normal; font-weight: 500 800;
  font-display: swap; src: url(/assets/fonts/baloo2-latin-ext.dfd52ee2.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Atkinson Hyperlegible'; font-style: normal; font-weight: 400;
  font-display: swap; src: url(/assets/fonts/atkinson-400-latin.d64ba838.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Atkinson Hyperlegible'; font-style: normal; font-weight: 400;
  font-display: swap; src: url(/assets/fonts/atkinson-400-latin-ext.61eeb0eb.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Atkinson Hyperlegible'; font-style: normal; font-weight: 700;
  font-display: swap; src: url(/assets/fonts/atkinson-700-latin.140e2bd2.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Atkinson Hyperlegible'; font-style: normal; font-weight: 700;
  font-display: swap; src: url(/assets/fonts/atkinson-700-latin-ext.840ced16.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  font-family: var(--tekst);
  font-size: 1.125rem;          /* 18px floor, per the huisstijl */
  line-height: 1.65;
  color: var(--ink);
  background: var(--sand);
  -webkit-font-smoothing: antialiased;
  /* anywhere rather than break-word: only anywhere also lowers the min-content
     width, which is what lets a grid or flex track shrink around a long Dutch
     compound such as "mobiliteitshulpmiddelen" instead of being forced wide. */
  overflow-wrap: anywhere;
  word-break: normal;
}

img, svg, video { max-width: 100%; height: auto; }
img { display: block; }
/* An inline SVG with no intrinsic size falls back to 300x150 and can open the
   page horizontally. Give every one a sane default, wrapped in :where() so the
   rule carries zero specificity: written plainly it out-weighs every component
   class and silently shrinks the ones that set their own size. */
svg:where(:not([width]):not([height])) { width: 1.5em; height: 1.5em; }

/* ---------- layout ---------- */
.container { width: min(100% - 2rem, var(--content)); margin-inline: auto; }
@media (min-width: 48rem) { .container { width: min(100% - 3rem, var(--content)); } }

main { display: block; }
section { padding-block: var(--space-xl); }
section.tight { padding-block: var(--space-lg); }

.prose { max-width: var(--prose); }
.prose > * + * { margin-top: var(--space-md); }
.prose ul, .prose ol { padding-left: 1.35em; }
.prose li + li { margin-top: var(--space-xs); }

.stack > * + * { margin-top: var(--space-md); }
.lede { font-size: 1.24rem; line-height: 1.55; max-width: 44ch; }

/* ---------- typography ---------- */
/* anywhere, not break-word: it also lets the heading shrink below its longest
   word when computing min-content, which is what keeps a grid or flex parent
   from being forced wide at large text sizes. */
h1, h2, h3, h4 {
  font-family: var(--kop); line-height: 1.15; text-wrap: balance;
  overflow-wrap: anywhere;
}
h1 { font-size: clamp(2rem, 1.35rem + 3.1vw, 3.1rem); font-weight: 800; color: var(--deep); }
h2 { font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2.1rem); font-weight: 700; color: var(--deep); margin-bottom: var(--space-sm); }
h3 { font-size: clamp(1.2rem, 1.08rem + .6vw, 1.4rem); font-weight: 600; color: var(--costa); margin-bottom: var(--space-xs); }
h4 { font-size: 1.1rem; font-weight: 600; color: var(--costa); }

a { color: var(--costa); text-decoration: underline; text-underline-offset: .18em; text-decoration-thickness: .08em; }
a:hover { color: var(--deep); }
strong, b { font-weight: 700; }
small { font-size: .95rem; }

:focus-visible { outline: 3px solid var(--coral); outline-offset: 3px; border-radius: 4px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--sol); color: var(--ink); padding: 1rem 1.5rem;
  font-family: var(--kop); font-weight: 700; text-decoration: none;
  border-bottom-right-radius: var(--radius);
}
.skip-link:focus { left: 0; }

/* ---------- header ---------- */
.site-header { background: var(--costa); color: var(--white); }

/* Sticky menu. The whole header is about 190px on both a phone and a desktop,
   which is over a quarter of a phone screen, so only its lower part stays:
   the negative top lets the brand row scroll away and then pins the rest.
   On a desktop that is the menu row with the booking button, on a phone the
   flags and the menu button. site.js measures --stick-offset (how much may
   scroll away) and --sticky-h (what stays), because both depend on the
   breakpoint and the text size.

   Only with JavaScript: without it the phone menu is a full open list, and
   pinning that would fill the screen. Only on screens at least 36rem tall:
   the query is in rem, so 200% text zoom or a phone held landscape drops back
   to an ordinary header instead of a bar that covers the content (WCAG 1.4.10). */
@media (min-height: 36rem) {
  .js .site-header {
    position: sticky; top: calc(-1 * var(--stick-offset, 0px)); z-index: 50;
  }
  /* Anchors, the skip link and keyboard focus land below the pinned bar
     rather than under it (WCAG 2.4.11). */
  html.js { scroll-padding-top: calc(var(--sticky-h, 0px) + .75rem); }
}
/* A pinned header cannot scroll, so an open phone menu longer than the screen
   would leave its last links out of reach. It scrolls on its own instead. */
@media (min-height: 36rem) and (max-width: 63.999rem) {
  .js .site-nav.is-open {
    max-height: var(--nav-max, none); overflow-y: auto; overscroll-behavior: contain;
  }
}
.header-bar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--space-md); padding-block: var(--space-md); min-height: 4.5rem;
}
.wordmark {
  font-family: var(--kop); font-weight: 800; line-height: 1;
  /* Capped against the viewport, not just the root size. The brand name is set
     nowrap, so at 200% text-only zoom on a 320px phone it would otherwise be
     wider than the screen and force horizontal scrolling. Body text and the
     navigation still scale in full. */
  font-size: min(1.85rem, 8.5vw);
  color: var(--white); text-decoration: none; letter-spacing: -.5px;
  display: inline-flex; align-items: center; white-space: nowrap;
  min-height: 44px; padding-block: .35rem;
}
.wordmark .sun { color: var(--sol); }
.wordmark:hover { color: var(--white); }
@media (min-width: 48rem) { .wordmark { font-size: min(2.15rem, 8.5vw); } }

/* The menu button exists only when JavaScript is running. Without it the
   navigation stays a plain, visible list: taller on a phone, but complete.
   The .js class is set by a tiny inline script in <head>, so the collapsed
   state is in place before the first paint rather than flashing open. */
.nav-toggle {
  display: none; align-items: center; gap: .5rem;
  min-height: 56px; padding: .5rem 1rem;
  font-family: var(--kop); font-weight: 700; font-size: 1.05rem;
  background: transparent; color: var(--white);
  border: 2px solid rgba(255,255,255,.55); border-radius: 999px;
  cursor: pointer;
}
.nav-toggle svg { width: 1.25em; height: 1.25em; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.nav-toggle[aria-expanded="true"] .icon-menu { display: none; }
.nav-toggle[aria-expanded="false"] .icon-close { display: none; }

.site-nav { width: 100%; padding-bottom: var(--space-md); }
.nav-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: .15rem; }
/* Both selectors are required. A top-level item with a submenu wraps its link
   in .nav-row, which puts the link one level deeper and stops
   `.nav-list > li > a` from matching it. Listing only the direct child left
   those links with no colour rule at all: they inherited the dark body ink and
   went invisible on the blue header while still occupying their full width. */
.nav-list > li > a, .nav-list > li > .nav-row > a {
  display: block; padding: .85rem .25rem; min-height: 56px;
  color: var(--white); font-weight: 700; text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,.18);
}
/* Sol-yellow text on Costa-blue is only 3.92:1. Keep the text white and let a
   yellow rule carry the state, which is a non-text indicator and needs 3:1. */
.nav-list > li > a:hover, .nav-list > li > a:focus-visible,
.nav-list > li > .nav-row > a:hover, .nav-list > li > .nav-row > a:focus-visible {
  color: var(--white); text-decoration: underline;
  text-decoration-color: var(--sol); text-decoration-thickness: 3px; text-underline-offset: 5px;
}
.nav-list > li > a[aria-current="page"],
.nav-list > li > .nav-row > a[aria-current="page"] {
  color: var(--white); box-shadow: inset 0 -3px 0 var(--sol);
}

/* ---------- submenus ----------
   Without JavaScript the submenu is a plain nested list, always visible, and
   the disclosure button is hidden because it would do nothing. Everything
   below that only applies once .js is set. */
.nav-row { display: flex; align-items: center; gap: .25rem; min-width: 0; }
.nav-row > a { flex: 1 1 auto; min-width: 0; }
.sub-toggle { display: none; }
.sub-list {
  list-style: none; padding: 0 0 0 var(--space-md); margin: 0;
  display: flex; flex-direction: column; gap: .1rem;
}
.sub-list > li > a {
  display: block; padding: .6rem .25rem; min-height: 48px;
  color: var(--white); font-weight: 400; text-decoration: none;
  font-size: .98rem;
}
.sub-list > li > a:hover, .sub-list > li > a:focus-visible {
  text-decoration: underline; text-decoration-color: var(--sol);
  text-decoration-thickness: 3px; text-underline-offset: 5px;
}
.sub-list > li > a[aria-current="page"] { box-shadow: inset 0 -3px 0 var(--sol); }
.sub-list > li, .nav-row { min-width: 0; }

.js .sub-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; width: 48px; min-height: 48px; padding: 0;
  background: transparent; border: 0; border-radius: 8px;
  color: var(--white); cursor: pointer;
}
.js .sub-toggle:hover { background: rgba(255,255,255,.14); }
.icon-chevron { fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; transition: transform .18s ease; }
@media (prefers-reduced-motion: reduce) { .icon-chevron { transition: none; } }
.js .sub-toggle[aria-expanded="true"] .icon-chevron { transform: rotate(180deg); }
/* The list is a sibling of .nav-row, not of the button inside it, so the state
   is carried on the <li> rather than by a sibling combinator on the button. */
.js .has-sub > .sub-list { display: none; }
.js .has-sub.is-open > .sub-list { display: flex; }

.header-utility { display: flex; align-items: center; gap: var(--space-sm); flex-wrap: wrap; min-width: 0; }
.site-nav, .nav-extra, .nav-list > li { min-width: 0; }
.nav-extra { display: flex; flex-wrap: wrap; gap: var(--space-sm); margin-top: var(--space-md); align-items: center; }
/* Must wrap: at 200% text-only zoom the two pills are wider than a phone. */
/* Language choice as two flags. Deliberately nothing like a button: no pill,
   no border, no fill. The labelled pills this replaces had the same rounded
   outline as the booking button below them and read as a row of three.
   The current language carries the same yellow underline the menu uses for the
   current page; the other one is the link. Each is a 44px target around a
   28px flag. */
.lang-switch { display: inline-flex; gap: .15rem; align-items: center; min-width: 0; }
.lang-opt {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 .4rem;
  border-radius: 6px; color: var(--white); text-decoration: none;
}
.lang-switch a.lang-opt { color: var(--white); }
.lang-switch a.lang-opt:hover { background: rgba(255,255,255,.14); }
.lang-switch a.lang-opt:focus-visible { outline: 3px solid var(--sol); outline-offset: 2px; }
.lang-opt[aria-current="true"] { box-shadow: inset 0 -3px 0 var(--sol); border-radius: 0; }
/* A hairline white ring: the blue band of the Dutch flag otherwise merges
   into the blue header. */
.flag {
  display: block; width: 28px; height: 21px; border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(255,255,255,.7);
}

/* Phone and tablet, JavaScript running: collapse behind the button. */
@media (max-width: 63.999rem) {
  .js .nav-toggle { display: inline-flex; }
  .js .site-nav { display: none; }
  .js .site-nav.is-open { display: block; }
}

/* Desktop: the button is irrelevant. Brand and language sit on the first row,
   the navigation and the booking call to action on the second. Seven links,
   a language switch and a button do not fit one row without wrapping into a
   ragged block, which is the last thing this audience needs to read. */
@media (min-width: 64rem) {
  .header-bar { align-items: center; padding-bottom: 0; }
  .site-nav {
    width: 100%; display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-lg); padding-bottom: var(--space-md); flex-wrap: wrap;
  }
  .nav-list { flex-direction: row; align-items: center; gap: var(--space-lg); flex-wrap: wrap; }
  /* Between 64 and 80rem the menu with 2rem gaps plus the booking button is
     wider than the container (987px against 961px at 1024), so the button
     dropped to a row of its own. With the header pinned that spare row stayed
     on screen: a 194px bar, a quarter of a 1024x768 display. */
  @media (max-width: 79.999rem) { .nav-list { gap: 1.1rem; } }
  .nav-list > li > a, .nav-list > li > .nav-row > a { border-bottom: none; padding: .5rem 0; min-height: 44px; }
  .nav-extra { margin-top: 0; }

  /* Desktop: the submenu becomes a real dropdown panel. It is opened by hover,
     by keyboard focus anywhere inside the item, and by the button, so pointer,
     keyboard and touch each have a route in. position: relative on the <li>
     and a high z-index keep the panel above the hero that follows it. */
  .js .has-sub { position: relative; }
  .js .has-sub > .nav-row > a { border-bottom: none; padding: .5rem 0; min-height: 44px; }
  /* On a phone the parent link fills the row so the chevron sits at the right
     edge. In the horizontal desktop row that same flex-grow, combined with the
     min-width: 0 that keeps the header from overflowing, lets the label shrink
     to nothing: the link stays in the DOM but renders zero pixels wide. Pin it
     to its content width here. */
  .js .has-sub > .nav-row > a { flex: 0 0 auto; white-space: nowrap; }
  /* aria-expanded, mirrored onto .is-open, is the only thing that opens this
     panel. An earlier version also opened it from CSS on :hover and
     :focus-within, which gave two sources of truth: Escape closed the panel and
     put focus back on its own button, and :focus-within reopened it on the
     spot. Hover now lives in the script, where it can be limited to a real
     mouse and can defer to focus.

     Closed is display:none, not merely transparent or shifted, so the panel
     cannot contribute to scrollWidth or take focus. */
  .js .has-sub > .sub-list { display: none; }
  .js .has-sub.is-open > .sub-list {
    display: block; position: absolute; top: 100%; left: -.75rem; z-index: 60;
    min-width: 14rem; max-width: min(20rem, 90vw);
    padding: .35rem; margin-top: .35rem;
    background: var(--white); border-radius: 12px;
    border: 1px solid rgba(11,61,102,.12);
    box-shadow: 0 12px 32px rgba(11,61,102,.22);
  }
  /* Dark text on a white panel: the white-on-blue rules above do not apply
     here, and inheriting them would leave white text on white. */
  .js .has-sub > .sub-list > li > a {
    color: var(--costa); padding: .6rem .75rem; min-height: 44px;
    border-radius: 8px; font-size: 1rem;
  }
  .js .has-sub > .sub-list > li > a:hover,
  .js .has-sub > .sub-list > li > a:focus-visible {
    background: var(--zand); color: var(--costa); text-decoration: none;
  }
  .js .has-sub > .sub-list > li > a[aria-current="page"] {
    box-shadow: none; background: var(--zand); font-weight: 700;
  }
  .js .sub-toggle { width: 32px; min-height: 32px; }
}

/* The trail motif: exactly one per screen, in the header. */
.trail { display: block; width: 100%; height: 34px; }

/* ---------- buttons ----------
   Scoped so a descendant element selector cannot quietly beat the component. */
.btn, a.btn, button.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  min-height: 56px;
  /* Side padding must not scale without limit: at 200% text on a 320px screen
     a padded label is wider than the screen and cannot wrap out of trouble. */
  padding: .9rem min(1.75rem, 6vw);
  font-family: var(--kop); font-weight: 700; font-size: 1.15rem; line-height: 1.2;
  border: 2px solid transparent; border-radius: 999px;
  text-decoration: none; cursor: pointer; text-align: center;
}
.btn-primary, a.btn-primary { background: var(--sol); color: var(--ink); }
.btn-primary:hover, a.btn-primary:hover { background: #F0A312; color: var(--ink); }
.btn-secondary, a.btn-secondary { background: var(--costa); color: var(--white); }
.btn-secondary:hover, a.btn-secondary:hover { background: var(--deep); color: var(--white); }
.btn-onblue, a.btn-onblue { background: transparent; color: var(--white); border-color: rgba(255,255,255,.7); }
.btn-onblue:hover, a.btn-onblue:hover { background: rgba(255,255,255,.14); color: var(--white); }
.btn-quiet, a.btn-quiet { background: none; color: var(--costa); text-decoration: underline; text-underline-offset: 4px; padding: .9rem .4rem; }
.btn-block { width: 100%; }
/* A row of calls to action needs room to read as a decision point rather than
   as the next paragraph. The gap is the space between the buttons; margin-block
   is the space above and below the row, which the body copy above and the
   reassurance badge below were both sitting flush against. */
.btn-row {
  display: flex; flex-wrap: wrap; gap: var(--space-md); align-items: center;
  margin-block: var(--space-lg);
}
.btn-row > * { min-width: 0; max-width: 100%; }
/* Margins do not collapse through a flex container, so a badge or note placed
   directly after the row would otherwise butt up against it. */
.btn-row + * { margin-top: var(--space-md); }

/* ---------- badge ---------- */
.badge {
  display: inline-flex; align-items: center; gap: .6rem;
  flex-wrap: wrap; max-width: 100%;
  background: var(--green-bg); color: var(--green);
  font-weight: 700; font-size: 1rem; border-radius: 999px; padding: .6rem 1.1rem;
}
.badge svg { width: 1.4em; height: 1.4em; flex: none; }

/* ---------- hero ---------- */
.hero { background: var(--white); border-bottom: 1px solid var(--line); }
.hero-inner { display: grid; gap: var(--space-lg); padding-block: var(--space-xl); align-items: center; }
/* Grid and flex children default to a min-content floor, so a long heading or
   an unbreakable label pushes the track wider than the container instead of
   wrapping. Every such child below is told explicitly that it may shrink. */
.hero-inner > * { min-width: 0; }
.hero-media img { border-radius: var(--radius); width: 100%; }
.hero h1 { margin-bottom: var(--space-md); }
.hero .lede { margin-bottom: var(--space-md); }
@media (min-width: 64rem) {
  .hero-inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: var(--space-2xl); }
  .hero-copy { min-width: 0; }
}

/* ---------- page head (used where there is no photograph) ---------- */
.pagehead { background: var(--white); border-bottom: 1px solid var(--line); padding-block: var(--space-xl); }
.pagehead h1 { margin-bottom: var(--space-md); }

/* ---------- cards ---------- */
.grid { display: grid; grid-template-columns: 1fr; gap: var(--space-md); }
.grid > * { min-width: 0; }
@media (min-width: 40rem) { .grid-2, .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64rem) {
  .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; display: flex; flex-direction: column; min-width: 0;
  position: relative;
}
/* The whole card is the target, not just the heading link. Both anchors point
   at the same page, so the overlap changes nothing except how easy it is to
   hit with an unsteady hand. */
.card .card-cta a::after { content: ""; position: absolute; inset: 0; }
.card h3 a { position: relative; z-index: 1; }
.card:hover { border-color: var(--costa); }
.card:focus-within { outline: 3px solid var(--coral); outline-offset: 3px; }
.card-media img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.card-body { padding: var(--space-md); display: flex; flex-direction: column; gap: var(--space-sm); flex: 1 1 auto; }
.card-body h3 { margin: 0; }
.card-body p { margin: 0; }
.card-body .card-cta { margin-top: auto; padding-top: var(--space-xs); }
.card h3 a { text-decoration: none; }
.card h3 a:hover { text-decoration: underline; }

.panel {
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--space-lg);
}
.panel-green { background: var(--green-bg); border-color: #CFE5D8; }
.panel-blue { background: var(--costa); border-color: var(--costa); color: var(--white); }
.panel-blue h2, .panel-blue h3 { color: var(--white); }
/* :not(.btn) is load-bearing. A bare ".panel-blue a" is one class plus an
   element selector, which outweighs the single class on .btn-primary, so the
   yellow booking button inside this panel would render white on yellow at
   1.83:1 without it. */
.panel-blue a:not(.btn) { color: var(--white); }
.panel-sand { background: #F6EDD9; border-color: var(--line); }

/* ---------- maps ---------- */
.map { width: 100%; height: auto; display: block; border-radius: var(--radius); }
.mapwide { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--space-sm); }
.sister { width: 100%; }
.sister a { font-weight: 700; }

/* ---------- fleet models ---------- */
.model { padding: 0; overflow: hidden; }
.model-grid { display: grid; gap: 0; }
.model-grid > * { min-width: 0; }
.model-photo img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.model-body { padding: var(--space-lg); }
.model-body h3 { font-size: clamp(1.4rem, 1.2rem + 1vw, 1.8rem); color: var(--deep); }
.model-body p { margin-bottom: var(--space-md); }
.model-gallery { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px; }
.model-gallery img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
@media (min-width: 64rem) {
  .model-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); align-items: center; }
  .model-photo img { height: 100%; aspect-ratio: auto; min-height: 22rem; }
}

/* ---------- steps ---------- */
.steps { list-style: none; padding: 0; counter-reset: step; display: grid; gap: var(--space-md); }
.steps > li { counter-increment: step; display: grid; grid-template-columns: 3rem minmax(0, 1fr); gap: var(--space-md); align-items: start; }
.steps > li > * { min-width: 0; }
.steps > li::before {
  content: counter(step); grid-row: span 2;
  width: 3rem; height: 3rem; border-radius: 999px;
  background: var(--costa); color: var(--white);
  font-family: var(--kop); font-weight: 800; font-size: 1.4rem;
  display: grid; place-items: center;
}
@media (min-width: 48rem) { .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: start; } }

/* ---------- feature list ---------- */
.ticks { list-style: none; padding: 0; display: grid; gap: var(--space-sm); }
.ticks > li > * { min-width: 0; }
.ticks > li { display: grid; grid-template-columns: 1.6rem minmax(0, 1fr); gap: .7rem; align-items: start; }
.ticks > li::before {
  content: ""; width: 1.4rem; height: 1.4rem; margin-top: .18em; border-radius: 999px;
  background: var(--green-bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231F7A4D' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4.5 4.5L19 7'/%3E%3C/svg%3E") center / 68% no-repeat;
}

/* ---------- tables ----------
   The scroller must not sit in a bare 1fr grid track: min-content on that track
   would push the whole page wide despite overflow-x. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--radius); border: 1px solid var(--line); background: var(--white); min-width: 0; max-width: 100%; }
table { border-collapse: collapse; width: 100%; min-width: 34rem; }
caption { text-align: left; padding: var(--space-md) var(--space-md) 0; font-weight: 700; }
th, td { padding: .9rem 1rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line); }
thead th { background: var(--costa); color: var(--white); font-family: var(--kop); font-weight: 600; border-bottom: none; }
tbody tr:last-child th, tbody tr:last-child td { border-bottom: none; }
tbody th { font-weight: 700; }
td .unit { color: var(--muted); font-size: .95rem; }

/* ---------- price card ---------- */
.pricecard { background: var(--white); border: 2px solid var(--line); border-radius: var(--radius); overflow: hidden; display: flex; flex-direction: column; }
.pricecard-head { background: var(--costa); color: var(--white); font-family: var(--kop); font-weight: 700; font-size: 1.2rem; padding: .9rem 1.25rem; }
.pricecard-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-sm); padding: .8rem 1.25rem; border-bottom: 1px solid #F2EBD8; }
.pricecard-row b { font-family: var(--kop); font-weight: 700; }
.pricecard-foot { padding: var(--space-md) 1.25rem; margin-top: auto; }

/* ---------- FAQ ---------- */
.faq { display: grid; gap: var(--space-sm); }
.faq > *, .faq summary, .faq .faq-body { min-width: 0; }
.faq details { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); }
.faq summary {
  cursor: pointer; padding: var(--space-md); min-height: 56px;
  font-family: var(--kop); font-weight: 600; font-size: 1.15rem; color: var(--costa);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-sm);
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex: none; width: 1.1rem; height: 1.1rem;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230F5C8C' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E") center / contain no-repeat;
}
.faq details[open] summary::after { transform: rotate(180deg); }
.faq .faq-body { padding: 0 var(--space-md) var(--space-md); max-width: var(--prose); }
.faq .faq-body > * + * { margin-top: var(--space-sm); }

/* ---------- breadcrumbs ---------- */
.breadcrumb { padding-block: var(--space-sm); font-size: 1rem; }
.breadcrumb ol { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: .3rem .5rem; }
.breadcrumb li { display: flex; align-items: center; gap: .5rem; }
.breadcrumb li + li::before { content: "›"; color: var(--muted); }
.breadcrumb [aria-current="page"] { color: var(--muted); }

/* ---------- forms ---------- */
.form { display: grid; gap: var(--space-md); max-width: 40rem; }
/* align-content: start keeps each row at its content height. Without it, a
   field beside a taller neighbour (one with a hint line) is stretched to match,
   the default align-content spreads that extra height over the label row and
   the input row, and the input grows to 88px and drops below its neighbour. */
.field { display: grid; gap: .35rem; min-width: 0; align-content: start; }
.field label { font-weight: 700; }
.field .hint { font-size: 1rem; color: var(--muted); }
.field input, .field select, .field textarea {
  font: inherit; color: inherit; width: 100%; min-width: 0;
  padding: .8rem .9rem; min-height: 56px;
  background: var(--white); border: 2px solid #CBBFA4; border-radius: var(--radius-sm);
}
.field textarea { min-height: 8rem; resize: vertical; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { border-color: var(--costa); }
.field-row { display: grid; gap: var(--space-md); }
@media (min-width: 40rem) { .field-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Browsers give fieldset a UA min-inline-size of min-content, so it refuses to
   shrink and drags the form wider than the page. */
.fieldset-plain { border: 0; padding: 0; margin: 0; min-width: 0; }
.field label.choice { display: flex; gap: .8rem; align-items: flex-start; font-weight: 400; min-height: 56px; padding-block: .4rem; cursor: pointer; }
/* Qualified on purpose. ".field input" is one class plus an element selector
   and outweighs a bare ".tickbox", so without this the checkbox inherits the
   full-width, 56px-tall text-input sizing and shoves the label text off the
   right edge of the page. */
.field input.tickbox {
  width: 1.75rem; height: 1.75rem; min-height: 0; padding: 0;
  flex: none; margin-top: .2rem; accent-color: var(--costa);
}
.required { color: #B23A1D; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-note { font-size: 1rem; color: var(--muted); max-width: 40rem; }
.form-status { padding: var(--space-md); border-radius: var(--radius); font-weight: 700; }
.form-status[data-state="ok"] { background: var(--green-bg); color: var(--green); }
.form-status[data-state="error"] { background: #FBE9E4; color: #B23A1D; }

/* ---------- open [CHECK] marker (never survives to production) ---------- */
/* A fact that is not settled yet. This is ordinary copy addressed to the
   visitor, not an editorial marker, so it is set quietly: italic and muted,
   with no border or highlight drawing the eye to what is missing.
   --muted on white is 5.9:1, so it clears AA for body text. */
.pending { color: var(--muted); font-style: italic; }

/* ---------- meta / source lines ---------- */
.sourceline { font-size: 1rem; color: var(--muted); }
.updated { font-size: 1rem; color: var(--muted); }

/* ---------- footer ---------- */
.site-footer { background: var(--deep); color: #CFE4F2; padding-block: var(--space-xl); margin-top: var(--space-2xl); }
.site-footer h2 { color: var(--white); font-size: 1.15rem; margin-bottom: var(--space-sm); }
.site-footer a:not(.btn):not(.wordmark) { color: #CFE4F2; }
.site-footer a:not(.btn):not(.wordmark):hover { color: var(--sol); }
.footer-grid { display: grid; gap: var(--space-lg); }
@media (min-width: 40rem) { .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .footer-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.footer-grid ul { list-style: none; padding: 0; display: grid; gap: .4rem; }
.footer-grid li a { display: inline-block; padding: .3rem 0; }
/* Capped against the viewport like the header wordmark. A plain rem here grew
   to 425px at 200% text zoom on a 320px screen, which is wider than the page. */
.footer-brand .wordmark { font-size: min(1.6rem, 7.5vw); }
.footer-bottom { border-top: 1px solid rgba(255,255,255,.2); margin-top: var(--space-lg); padding-top: var(--space-md); font-size: 1rem; display: flex; flex-wrap: wrap; gap: var(--space-sm) var(--space-md); justify-content: space-between; }

/* ---------- utilities ---------- */
.center { text-align: center; }
.muted { color: var(--muted); }
.mt-lg { margin-top: var(--space-lg); }
.mt-md { margin-top: var(--space-md); }
.mb-lg { margin-bottom: var(--space-lg); }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.section-sand { background: #F6EDD9; }
.section-white { background: var(--white); }
