/* =========================================================
   TERASE SPĀRE — version 2
   Card stack on a sunset over Cieceres ezers. The page itself
   is the gradient: pale sky at the top, a band of low sun, then
   down through the water to the dark of the lake by the footer.

   Structure follows Cafe Terase v2 deliberately — same stack,
   same floating dock, same cream menu card. Everything that
   carries identity (palette, type, foliage, textures) is
   Spāre's own.
   ========================================================= */

:root {
  /* Sunset over Ciecere: pale sky at the top of the document, the sun low
     on the far shore, then down through the water to the dark of the lake.
     The wood stays the brand's own — it is the deck, not the page. */
  --sky:       #EDEFEA;   /* near-white at the very top */
  --sky-mid:   #86A9AC;
  --rose:      #E69E8E;   /* the rose gold in the band of low sun */
  --water:     #2E4F52;   /* petrol — blue still, but turned toward green */
  --deep:      #1A3335;
  --wood:      #2C2218;   /* the brand's dark wood, unchanged */
  --ink:       #08110F;   /* the lake after dark, green-black not blue-black */

  --cream:     #F5F0E8;   /* the menu card */
  --ivory:     #F0EADD;
  --sand:      #BFB09A;   /* dim text — deepened from the brand sand for contrast */
  --amber:     #D4922A;   /* the fire: prices, times, status, active states */
  --amber-lit: #E9B664;

  /* Archivo carries a width axis, so the display face can be set wide and
     light to sit with the SPARE wordmark instead of fighting it. Inter is
     kept for body text — proven against Latvian macrons on both sites.
     JetBrains Mono is the utility face: times, prices, temperatures. */
  --display: 'Archivo', 'Segoe UI', -apple-system, sans-serif;
  --body:    'Inter', -apple-system, 'Segoe UI', sans-serif;
  --mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --gut: clamp(.75rem, 2vw, 1.5rem);
  /* Ceiling in rem so the corner radius grows with everything else — a 24px
     radius on a 2100px card reads as a square corner. */
  --radius: clamp(14px, 2vw, 1.5rem);
  --dock-h: 5.75rem;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* The whole design scales off this one line above 1500px.

   Nearly every size in this file is a clamp whose ceiling is written in rem —
   clamp(.95rem, 1.3vw, 1.05rem) and so on. With no root font-size set, 1rem is
   whatever the browser default is and never moves, so every one of those
   ceilings is reached at roughly the same viewport width and the design stops
   growing. Making the root itself fluid lifts all of them together, and the
   ch-based measures follow, because ch is font-relative too.

   Written in rem rather than px on purpose: rem on the root element resolves
   against the *user's* default size, so somebody who has set 20px text keeps
   their preference and simply scales from there. A px ramp would overwrite it.

   The floor is held until 1500px so nothing below a large desktop changes —
   phones and ordinary laptops render exactly as they did. From there it runs
   linearly to 1.25x at 2560px and stops, so an ultrawide gets a bigger site
   rather than an endlessly bigger one. */
html {
  font-size: clamp(1rem, 0.38vw + 0.64rem, 1.25rem);
  background: var(--ink);
  scroll-behavior: smooth;
  scroll-padding-top: 1rem;
}

/* The gradient lives on <body> so it spans the whole document rather than
   repeating per viewport — that is what makes the page itself the sunset,
   instead of every screenful repeating the same sky.

   Two layers, not one. The ramp underneath runs sky to lake bed; the warm
   layer over it is transparent except for a band of low sun near the top and
   a long faint tail of afterglow below it. Compositing them keeps the rose
   reading as light falling on water — averaging the two into a single ramp
   would only give a muddy brown band.

   The ramp is not one hue. It starts near-white, turns through a pale
   blue-green, sits at petrol across the middle, and closes green-black — so
   the water reads warmer and greener the deeper it gets rather than staying
   the same flat blue all the way down.

   Both ends are pinned by legibility, not by taste. The transparent "Par
   mums" card sets ivory body copy straight onto this background from 13.5%
   to 33.7% of the document, so the ramp has to reach roughly 7:1 by 14% and
   hold it to 34%. That is why the pale end is compressed into the first
   eighth — which is fine, because the hero card covers exactly that, and the
   sky and the rose show in the gutters around it. */
body {
  background:
    linear-gradient(180deg,
      rgba(240,205,196,0)     0%,
      rgba(238,196,186,.34)   3%,
      rgba(230,158,142,.40)   7%,
      rgba(214,124,108,.30)  11%,
      rgba(190,104,96,.16)   16%,
      rgba(190,120,80,.07)   24%,
      rgba(200,140,60,.03)   36%,
      rgba(212,146,42,0)     48%),
    linear-gradient(180deg,
      var(--sky)      0%,
      #DCE3E0         3%,
      #B9CCCB         6%,
      var(--sky-mid)  9%,
      #4E7478        12%,
      var(--water)   14%,
      #26454A        22%,
      #1F3B3F        32%,
      var(--deep)    45%,
      #152B2B        58%,
      #102121        72%,
      #0C1817        86%,
      var(--ink)    100%);
  color: var(--ivory);
  font-family: var(--body);
  font-weight: 300;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  padding-bottom: var(--dock-h);
}

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul, dl { list-style: none; }

::selection { background: var(--amber); color: var(--ink); }
:focus-visible { outline: 2px solid var(--amber-lit); outline-offset: 3px; }

.skip-link {
  position: absolute; top: -100px; left: 1rem; z-index: 999;
  background: var(--amber); color: var(--ink);
  padding: .7rem 1.2rem; font-size: .85rem;
  transition: top .2s var(--ease);
}
.skip-link:focus { top: .5rem; }

/* =========================================================
   FOLIAGE — reeds on the near bank
   Photographic cutouts rather than line art: the clusters are
   already the sand tone of the palette.

   Fixed to the bottom of the viewport, not scattered down the
   document. Reeds grow at the water's edge, and the water's
   edge is the near side of the frame — so they hold their
   place while the cards slide past behind the page, the same
   way the dock holds its place in front of it. You are
   standing in them, looking out.

   z-index 0 keeps the whole layer under .stack, which sits at
   1, so every opaque card still occludes it for free.
   ========================================================= */
.foliage {
  position: fixed; inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Left warm rather than desaturated: pampas holding the last of the light is
   what these clusters actually are, and the sand tone is already the one the
   sunset band is casting. */
.sprig {
  position: absolute;
  bottom: 0;
  width: clamp(280px, 30vw, 520px);
  height: auto;
  filter: saturate(.95) brightness(.92) contrast(1.05);
}

/* Two clusters a side. The near pair is larger and stronger, the far pair is
   smaller, dimmer and slightly blurred — depth without parallax, which a
   fixed layer cannot have. Each is pushed out past the page edge so it reads
   as part of a bank that carries on out of frame, and down past its own base
   so the stems never end in mid-air. */
/* Three depths a side, not two. Each step in is smaller, dimmer, blurrier and
   pushed further down, so the bank thins toward the middle instead of ending
   at the gutters — which is what left the centre of the bottom band reading
   as empty. The innermost pair is only tips: enough to say the reeds carry
   on, not enough to become a subject. */
.sprig--near { opacity: .34; }
.sprig--far  { opacity: .18; filter: saturate(.8) brightness(.8) blur(1.5px); }
.sprig--mid  { opacity: .11; filter: saturate(.7) brightness(.72) blur(2.6px); }

.sprig--l1 { left:   0;    translate: -34% 14%; rotate: -4deg; }
.sprig--l2 { left:   9vw;  translate: -30% 22%; rotate:  5deg; width: clamp(200px, 20vw, 340px); }
.sprig--l3 { left:  20vw;  translate: -18% 36%; rotate:  7deg; width: clamp(140px, 14vw, 240px); }
.sprig--r1 { right:  0;    translate:  30% 12%; rotate:  3deg; }
.sprig--r2 { right:  8vw;  translate:  26% 24%; rotate: -6deg; width: clamp(200px, 20vw, 340px); }
.sprig--r3 { right: 19vw;  translate:  16% 34%; rotate: -8deg; width: clamp(140px, 14vw, 240px); }

/* =========================================================
   STACK + CARD SHELL
   ========================================================= */
/* Still capped — a wide monitor should get composed cards framed by the water
   rather than content stranded in the middle of a 2500px band — but the cap
   now moves instead of sitting at a flat 1500px, which left a 2560 monitor
   using 59% of its width and 530px of reeds down each side.

   Read the three parts outward: 96vw is the target, min() stops it at 2100px
   so an ultrawide still gets its frame, and max() holds the old 1500px floor
   so nothing at or below laptop width changes at all. */
.stack {
  position: relative; z-index: 1;   /* above the foliage */
  display: flex; flex-direction: column;
  gap: var(--gut);
  padding: var(--gut);
  max-width: max(1500px, min(96vw, 2100px));
  margin-inline: auto;
}

.card {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  isolation: isolate;
}

/* Aspect ratio sets the shape; max-height keeps a wide monitor from turning
   one card into a 1000px wall. */
.card--hero  { aspect-ratio: 16 / 9; min-height: 540px; max-height: 86svh; }
.card--film  { aspect-ratio: 21 / 9; min-height: 260px; max-height: 62svh; }
.card--visit { aspect-ratio: 16 / 9; min-height: 460px; max-height: 70svh; }

.card__bg {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
}
.card--hero  .card__bg { object-position: center 62%; }
.card--visit .card__bg { object-position: center 58%; }

/* Cool rather than neutral black: the photographs are warm golden-hour
   frames, and pulling their shadows toward the water's blue is what ties
   them to the page instead of leaving them sitting on top of it.

   Two directions, not one. The vertical pass alone is enough for a title, but
   the copy on these cards runs down the left-hand side and lands on open
   water and bright sky halfway down the frame, where a top-to-bottom scrim
   has already faded out. The horizontal pass holds that side down and clears
   entirely by two thirds across, so the photograph is never flattened. */
.card__scrim {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(to right, rgba(7,13,20,.66) 0%, rgba(7,13,20,.34) 34%,
                              rgba(7,13,20,.06) 62%, rgba(7,13,20,0) 78%),
    linear-gradient(to bottom, rgba(7,13,20,.72) 0%, rgba(7,13,20,.22) 38%,
                               rgba(7,13,20,.30) 62%, rgba(7,13,20,.84) 100%);
}

/* ---- head: wordmark, descriptor, buttons ---- */
.card__head {
  position: absolute; top: 0; left: 0;
  padding: clamp(1.25rem, 3vw, 2.5rem);
  max-width: 44ch;
}
/* Used by the cards that have no photograph, where the head sits in flow. */
.card__head--flat {
  position: static;
  max-width: 70rem; width: 100%;
  margin-inline: auto;
  padding: 0;
}

/* The hero is the real logo file rather than re-typeset text: the rule under
   "terase" and the dragonfly perched on the E are the mark, and neither
   survives being rebuilt out of web type. */
.wordmark { display: block; width: clamp(230px, 30vw, 26.25rem); }
.wordmark img { width: 100%; height: auto; }

.card__title {
  font-family: var(--display);
  font-weight: 300; font-stretch: 112%;
  font-size: clamp(1.85rem, 4.4vw, 3.1rem);
  line-height: 1.05;
  letter-spacing: .04em; text-transform: uppercase;
  text-wrap: balance;
}
.card__title--sm { font-size: clamp(1.5rem, 3vw, 2.2rem); }

.card__sub {
  margin-top: .7rem;
  font-size: clamp(.9rem, 1.5vw, 1.05rem);
  color: rgba(240, 234, 221, .84);
  max-width: 46ch;
}

/* An eyebrow that names what the card is, in the utility face. Used where
   the card carries data — hours, departures, temperatures. */
.eyebrow {
  font-family: var(--mono);
  font-size: .68rem; letter-spacing: .22em; text-transform: uppercase;
  color: var(--amber);
}

.pills { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.35rem; }
.pill {
  display: inline-block;
  padding: .65rem 1.3rem;
  border-radius: 100px;
  font-size: .82rem; letter-spacing: .06em;
  transition: transform .25s var(--ease), background .25s var(--ease), color .25s var(--ease);
}
.pill--light { background: var(--ivory); color: var(--wood); }
.pill--dark  { background: rgba(7,15,14,.62); color: var(--ivory); backdrop-filter: blur(8px); }
.pill:hover  { transform: translateY(-2px); }
.pill--dark:hover  { background: var(--amber); color: var(--wood); }
.pill--light:hover { background: var(--amber-lit); }

/* ---- hours, bottom-left ---- */
.card__hours {
  position: absolute; left: 0; bottom: 0;
  padding: clamp(1.25rem, 3vw, 2.5rem);
}
.card__hours--right { left: auto; right: 0; text-align: right; }
.card__hours--right .hours > div { justify-content: flex-end; }
.card__hours--right .hours dt { min-width: 0; }
.hours { font-family: var(--mono); font-size: .78rem; }
.hours > div { display: flex; gap: 1rem; }
.hours dt { min-width: 7.5em; color: rgba(240, 234, 221, .62); }
.hours dd { color: var(--ivory); }
.card__status {
  display: flex; align-items: center; gap: .45rem;
  margin-top: .55rem;
  font-family: var(--mono);
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--amber-lit);
}
.card__status:empty { display: none; }

/* Plain text, and the text itself is the target. No panel and no padding: the
   hours above start hard against the block's left edge, so anything that
   insets this copy — a chip, a leading glyph — pushed it out of that column
   and read as a misalignment. Amber-lit is the shade the old status line used,
   so the corner keeps its accent without gaining a third button.

   No underline either: the colour is the whole cue, and hover brightens it. */
.card__follow {
  display: inline-block;
  margin-top: .6rem;
  max-width: 19rem;
  color: var(--amber-lit);
  font-size: .72rem; line-height: 1.45;
  /* Evens the wrapped lines rather than orphaning a word. Ignored where
     unsupported. */
  text-wrap: balance;
  transition: color .25s var(--ease);
}
.card__follow:hover { color: #F5D69C; }

/* ---- floating mini map, bottom-right ---- */
.minimap {
  position: absolute; right: clamp(1rem, 2.5vw, 2rem); bottom: clamp(1rem, 2.5vw, 2rem);
  width: clamp(190px, 22vw, 16.875rem);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 18px 40px -14px rgba(0,0,0,.7);
}
/* Google's embed has no styling API, so the map is recoloured with a filter.
   Inverting alone gives a photo negative — the hue-rotate puts the hues back
   the right way round, which is what turns the inverted map into a dark one
   that still knows water from land. Tuned so the lake lands on the page's own
   petrol blue and the pin keeps its warmth against it. */
.minimap iframe {
  display: block; width: 100%; height: clamp(130px, 15vw, 11.25rem);
  border: 0;
  filter: invert(.93) hue-rotate(188deg) saturate(.62) brightness(.9) contrast(1.06) sepia(.18);
}
.minimap__label {
  display: block;
  padding: .6rem .8rem;
  background: rgba(7,15,14,.9);
  backdrop-filter: blur(8px);
  transition: background .25s var(--ease);
}
.minimap__label strong { display: block; font-size: .8rem; font-weight: 400; }
.minimap__label span   { display: block; font-size: .7rem; color: var(--sand); }
.minimap__label:hover  { background: var(--amber); color: var(--wood); }
.minimap__label:hover span { color: rgba(44,34,24,.75); }

/* ---- embers, over the hero only ----
   The oven is the reason the place exists; the sparks are the one piece of
   ambient motion on the page. Carried over from the first build. */
.embers {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  pointer-events: none;
}

/* =========================================================
   CARD 2 — THE STORY + THE FOUR
   Four photographs, offset into two diagonals: the food and the
   room on one, the deck and the boat on the other. The story
   holds the column beside them.
   ========================================================= */
/* Transparent on purpose: this is the card that lets the reeds through,
   behind the text and between the photographs. */
.card--quad {
  background: transparent;
  padding: clamp(1.25rem, 3vw, 2.5rem);
}

.quad {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(.6rem, 1.4vw, 1.1rem);
  max-width: 65rem;
  margin: clamp(1.5rem, 3vw, 2.5rem) auto 0;
  padding-block: 34px;   /* room for the offset */
}
.quad__cell {
  border-radius: calc(var(--radius) * .6);
  overflow: hidden;
}
.quad__cell img {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
  transition: transform 1s var(--ease);
}
.quad__cell:hover img { transform: scale(1.04); }

/* The Zezer's wordmark runs right up to the left edge of the original frame,
   so there is nothing spare to crop on that side. On desktop the cell is a
   little narrower than the file's 4:5 and the browser trims both sides — which
   ate the Z. Anchoring left takes the whole trim off the right, where there is
   only decking and water to lose. */
.quad__cell--b img { object-position: left center; }

.quad__cell--a, .quad__cell--c { transform: translateY(34px); }
.quad__cell--b, .quad__cell--d { transform: translateY(-34px); }

/* The two typographic cells. Same footprint as a photograph, so the
   diagonal composition holds; a wood-dark panel so they read as part of
   the deck rather than as empty slots. */
/* ---- the story, in card 2's left column ---- */
.say { max-width: 65rem; margin-inline: auto; }

.say__lead {
  font-family: var(--display);
  font-weight: 300; font-stretch: 112%;
  font-size: clamp(1.9rem, 4.2vw, 3.1rem);
  line-height: 1.06;
  letter-spacing: .035em; text-transform: uppercase;
  text-wrap: balance;
}
.say__lead em {
  font-style: normal;
  color: var(--amber);
}

.say__body { margin-top: clamp(1rem, 2vw, 1.5rem); }
/* A touch brighter than the rest of the page: this card lost its dark veil so
   the reeds could show through, which costs a little contrast. */
.say__body p {
  font-size: clamp(.95rem, 1.3vw, 1.05rem);
  color: rgba(240, 234, 221, .88);
  max-width: 58ch;
}
.say__body p + p { margin-top: 1rem; }

/* Only earns its place on wide screens, where the text column would otherwise
   run out before the photographs beside it do. */
.say__photo { display: none; }

/* =========================================================
   CARD 4 — MENU, on cream
   ========================================================= */
.card--menu { background: var(--cream); color: #2B2218; }

/* Full bleed across the top of the cream card. Shallow on purpose — it is an
   appetite cue, not a second hero, and the menu itself should still be the
   first thing on screen when the card is scrolled to. */
.menucard__band {
  overflow: hidden;
  border-bottom: 1px solid rgba(43, 34, 24, .12);
}
.menucard__band img {
  width: 100%;
  height: clamp(170px, 24vw, 20.625rem);
  object-fit: cover;
  /* High in the frame: the lens is focused on the toppings across the middle
     of the pie, and the near crust along the bottom edge is soft. */
  object-position: center 34%;
}

/* Deeper at the foot than the head: the allergen note is the last thing on
   the card and was ending barely 30px from its edge. */
.menucard {
  max-width: 73.75rem; margin-inline: auto;
  padding: clamp(2rem, 5vw, 4rem) clamp(1.5rem, 4vw, 3rem) clamp(3rem, 7vw, 5rem);
}
.menucard__head { text-align: center; padding-bottom: 2.2rem; border-bottom: 1px solid rgba(43,34,24,.18); }
.menucard__head .eyebrow { color: #8A6A30; }
.menucard__note {
  margin-top: .9rem;
  font-size: .92rem; line-height: 1.7;
  color: #6B5F4E;
  max-width: 48ch; margin-inline: auto;
}

/* One column, not two. Terase runs two because it has twenty-odd dishes;
   Spāre has eight pizzas, and splitting eight across two columns leaves one
   course stranded beside six with a column of white space between them. A
   short card set confidently down the middle reads as a choice — which it is,
   since everything here comes out of one oven. */
.courses {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  max-width: 41.25rem; margin-inline: auto;
}

.course { margin-top: 2.6rem; }
.course:first-child { margin-top: 0; }
.course__title {
  font-family: var(--display);
  font-weight: 400; font-stretch: 112%;
  font-size: .82rem; letter-spacing: .3em; text-transform: uppercase;
  text-align: center; color: #4B3D2A;
  margin-bottom: 1.4rem;
}
.course__title span {
  display: inline-block;
  padding-bottom: .45rem;
  border-bottom: 1px solid rgba(212, 146, 42, .55);
}

.dish { padding-block: .9rem; border-bottom: 1px solid rgba(43,34,24,.11); }
.dish:last-child { border-bottom: 0; }
.dish__head {
  display: flex; align-items: baseline; gap: .8rem;
  justify-content: space-between;
  font-size: 1rem;
}
.dish__name { font-weight: 400; }
.dish__price {
  font-family: var(--mono); font-size: .92rem;
  color: #9A6A18;
  white-space: nowrap;
}
.dish__desc { font-size: .84rem; line-height: 1.6; color: #665B4B; margin-top: .2rem; max-width: 54ch; }
.dish__all  { font-family: var(--mono); font-size: .68rem; color: #918571; white-space: nowrap; }

/* Marks a pikanta pizza. The chilli is drawn in the menu's own colours
   rather than the first build's red, which shouted on cream. */
.dish__spicy { display: inline-block; vertical-align: -1px; margin-left: .1rem; }

/* Konditoreja has no fixed card — it changes every weekend and lives on
   Instagram. Given its own block rather than a list of items that would
   go stale. */
.pastry {
  max-width: 41.25rem; margin-inline: auto;
  margin-top: 2.6rem; padding: clamp(1.3rem, 3vw, 2rem);
  border: 1px solid rgba(43,34,24,.16);
  border-radius: calc(var(--radius) * .5);
  background: rgba(212, 146, 42, .07);
}
.pastry p { font-size: .88rem; line-height: 1.7; color: #5F5443; }
.pastry__link {
  display: inline-flex; align-items: center; gap: .45rem;
  margin-top: .9rem;
  font-family: var(--mono); font-size: .78rem;
  color: #9A6A18;
  transition: color .25s var(--ease);
}
.pastry__link:hover { color: #2B2218; }

/* Shares the courses' column and its centring. Left-aligned and full-bleed it
   was the only ragged block on a card that is otherwise centred all the way
   down, and it read as something that had fallen off the bottom. */
.menucard__allergens {
  max-width: 41.25rem; margin-inline: auto;
  margin-top: 2.8rem; padding-top: 1.5rem;
  border-top: 1px solid rgba(43,34,24,.18);
  text-align: center; text-wrap: balance;
  font-size: .71rem; line-height: 1.8; color: #6F6553;
}
.menucard__allergens strong {
  display: block; font-family: var(--mono); font-weight: 400;
  letter-spacing: .18em; text-transform: uppercase;
  color: #4B3D2A; margin-bottom: .35rem;
}

/* =========================================================
   CARD 5 — THE BOAT
   The jetty leading out to the moored Zezer, behind the
   timetable. This card carries more content over its
   photograph than any other — a heading, two tour panels,
   two date boards and a review — so the scrim is heavier and
   flatter than the hero's, and the panels sit on their own
   frosted glass rather than trusting the scrim alone.
   ========================================================= */
.card--tours {
  padding: clamp(1.75rem, 4vw, 3.25rem) clamp(1.25rem, 3vw, 2.5rem);
  background: #1D160E;   /* under the photograph, and the fallback if it fails */
  border: 1px solid rgba(240, 234, 221, .08);
}
.card--tours .card__bg { object-position: center 34%; }
/* Warm rather than blue, unlike the other scrims: the deck is the one place
   on the page that should still read as wood at this hour. */
.card--tours .card__scrim {
  background:
    linear-gradient(to bottom, rgba(24,17,10,.80) 0%, rgba(20,14,9,.68) 34%,
                               rgba(17,12,8,.76) 70%, rgba(14,10,7,.88) 100%);
}

/* Centred, and the whole intro is one column: eyebrow, title, then the quote
   directly beneath, with a rule across to split them. The date boards below
   stay left-aligned inside their panels — the intro reads as the section's
   masthead, and the boards as the thing you act on. */
.tours__intro { max-width: 70rem; margin-inline: auto; text-align: center; }

.tours {
  display: grid; grid-template-columns: 1fr;
  gap: clamp(1rem, 2vw, 1.5rem);
  max-width: 70rem; margin: clamp(1.75rem, 3.5vw, 2.75rem) auto 0;
}

.tour {
  display: flex; flex-direction: column;
  padding: clamp(1.25rem, 2.6vw, 1.9rem);
  border-radius: calc(var(--radius) * .6);
  background: rgba(11, 9, 6, .62);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(240, 234, 221, .1);
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
.tour:hover { border-color: rgba(212, 146, 42, .4); background: rgba(11, 9, 6, .74); }

.tour__len {
  align-self: flex-start;
  font-family: var(--mono); font-size: .74rem; letter-spacing: .1em;
  color: var(--amber);
  padding: .25rem .7rem;
  border: 1px solid rgba(212, 146, 42, .38);
  border-radius: 100px;
}
.tour__title {
  font-family: var(--display);
  font-weight: 400; font-stretch: 108%;
  font-size: clamp(1.1rem, 1.9vw, 1.35rem);
  letter-spacing: .06em; text-transform: uppercase;
  margin-top: .9rem;
}
.tour__desc { font-size: .9rem; color: rgba(240, 234, 221, .78); margin-top: .6rem; max-width: 46ch; }

.tour__meta {
  display: flex; flex-wrap: wrap; gap: .35rem 1.25rem;
  margin-top: 1.1rem; padding-top: 1.1rem;
  border-top: 1px solid rgba(240, 234, 221, .1);
  font-family: var(--mono); font-size: .72rem;
  color: var(--sand);
}
.tour__meta li { display: flex; align-items: center; gap: .4rem; }
.tour__meta svg { flex: none; opacity: .7; }

/* Centred under the boards, on the same axis as the heading and the quote.
   The block was already centred; the text inside it was not, which read as a
   stray left-aligned line under two centred ones.

   Lifted out of the .6 grey it was in — this is the one line on the card that
   changes what someone has to do before they turn up, and at .8rem/.6 alpha it
   was quieter than the metadata inside the boards above it. Sand rather than
   amber: amber is the accent for times and prices here, and spending it on a
   footnote would outrank the departure times it sits beneath. */
.tours__note {
  max-width: 46rem;
  margin: clamp(1.5rem, 3vw, 2.25rem) auto 0;
  text-align: center; text-wrap: balance;
  font-size: .85rem; line-height: 1.6;
  color: var(--sand);
}

/* ---- the departure board ----
   Fienta fills these in. Styled as slats on a pier timetable: mono, an
   amber edge, times reading down the card. Markup comes from js/fienta.js. */
.tour__dates { margin-top: 1.35rem; }
.tour__dates-label,
.tour__dates .tour-card__dates-label {
  display: block;
  font-family: var(--mono); font-size: .66rem;
  letter-spacing: .2em; text-transform: uppercase;
  color: rgba(240, 234, 221, .5);
  margin-bottom: .7rem;
}
.tour__dates .tour-card__date-pills {
  display: flex; flex-wrap: wrap; gap: .4rem;
}
.tour__dates .date-pill {
  display: flex; flex-direction: column; gap: .1rem;
  padding: .5rem .85rem;
  border-radius: 8px;
  border-left: 2px solid var(--amber);
  background: rgba(240, 234, 221, .07);
  font-family: var(--mono); font-size: .8rem;
  color: var(--ivory);
  transition: background .25s var(--ease), transform .25s var(--ease);
}
.tour__dates .date-pill:hover { background: var(--amber); color: var(--wood); transform: translateY(-2px); }
.tour__dates .date-pill__sub { font-size: .66rem; color: var(--sand); }
.tour__dates .date-pill:hover .date-pill__sub { color: rgba(44,34,24,.8); }
.tour__dates .date-pill--sold-out {
  border-left-color: rgba(240, 234, 221, .25);
  color: rgba(240, 234, 221, .45);
  pointer-events: none;
}
.tour__dates .date-pill--sold-out .date-pill__sub { color: rgba(240, 234, 221, .35); }

.tour__dates .tour-card__offseason { font-size: .82rem; color: rgba(240, 234, 221, .6); }
.tour__dates .tour-card__offseason + a {
  display: inline-block; margin-top: .5rem;
  font-family: var(--mono); font-size: .74rem; color: var(--amber);
  border-bottom: 1px solid rgba(212, 146, 42, .4);
}
.tour__dates .tour-card__offseason + a:hover { color: var(--amber-lit); }

.tour__dates .tour-card__skeleton { display: flex; gap: .4rem; }
.tour__dates .tour-card__skeleton div {
  width: 72px; height: 44px; border-radius: 8px;
  background: rgba(240, 234, 221, .07);
  animation: pulse 1.4s ease-in-out infinite;
}
.tour__dates .tour-card__skeleton div:nth-child(2) { animation-delay: .18s; }
.tour__dates .tour-card__skeleton div:nth-child(3) { animation-delay: .36s; }
@keyframes pulse { 0%, 100% { opacity: .4; } 50% { opacity: .9; } }

/* ---- what people said, beside the heading ----
   A rule down the left rather than across the top: in its own column the
   quote needs to read as an aside to the standfirst, not as the next section
   after it. The rule collapses back to a top border once the grid stacks. */
.quotes {
  position: relative;
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
  border-top: 1px solid rgba(240, 234, 221, .12);
}
/* Class names below are the ones js/testimonials.js writes — the carousel
   is reused unchanged from the first build. */
.testimonials__track { position: relative; }
.testimonials__track--ready .testimonial-card {
  position: absolute; inset: 0;
  opacity: 0; pointer-events: none;
  transition: opacity .42s var(--ease);
}
.testimonials__track--ready .testimonial-card--visible { opacity: 1; pointer-events: auto; }

.testimonial-card__stars { color: var(--amber); letter-spacing: .22em; font-size: .78rem; }
.testimonial-card__text {
  margin-top: .7rem;
  font-size: clamp(.95rem, 1.5vw, 1.1rem); line-height: 1.65;
  color: rgba(240, 234, 221, .88);
  /* The measure stays capped even though the column is now the full 70rem —
     centred text is harder to track back to, so the lines have to stay short.
     margin-inline centres the capped block inside that width. */
  max-width: 62ch; margin-inline: auto;
}
.testimonial-card__footer {
  display: flex; align-items: center; justify-content: center; gap: .9rem;
  margin-top: .8rem;
  font-size: .78rem; color: var(--sand);
}
.testimonial-card__name { font-style: normal; }
.testimonial-card__source { display: inline-flex; align-items: center; gap: .35rem; font-family: var(--mono); font-size: .68rem; }

.testimonials__controls {
  display: flex; align-items: center; justify-content: center; gap: .75rem;
  margin-top: 1.1rem;
}
.testimonials__arrow {
  display: grid; place-items: center;
  width: 30px; height: 30px;
  border: 1px solid rgba(240, 234, 221, .16);
  border-radius: 100px;
  background: transparent; color: var(--sand);
  cursor: pointer;
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.testimonials__arrow:hover { color: var(--ivory); border-color: rgba(240, 234, 221, .4); }
.testimonials__dots { display: flex; gap: .35rem; }
.testimonials__dot {
  width: 6px; height: 6px; padding: 0;
  border: 0; border-radius: 100px;
  background: rgba(240, 234, 221, .22);
  cursor: pointer;
  transition: background .25s var(--ease), width .25s var(--ease);
}
.testimonials__dot--active { background: var(--amber); width: 16px; }

/* =========================================================
   CARD 6 — VISIT
   The aerial film runs behind the contact details. Motion is
   harder to read across than a still — the eye keeps chasing
   it — so the footage is held back and the scrim is heavier
   than the hero's, particularly down the left where the phone
   number and the address sit.
   ========================================================= */
/* The footage was shot at dusk and is dark to begin with — knocking it back
   further left the card a black rectangle. It is lifted here instead, and the
   scrim does the legibility work on its own, concentrated down the left where
   the phone number and the address sit rather than spread over everything. */
.card--visit .card__bg { filter: saturate(.95) brightness(1.12) contrast(.96); }
.card--visit .card__scrim {
  background:
    linear-gradient(to right, rgba(7,13,20,.76) 0%, rgba(7,13,20,.44) 36%,
                              rgba(7,13,20,.10) 66%, rgba(7,13,20,0) 86%),
    linear-gradient(to bottom, rgba(7,13,20,.44) 0%, rgba(7,13,20,.12) 40%,
                               rgba(7,13,20,.20) 66%, rgba(7,13,20,.60) 100%);
}

.card__details {
  position: absolute; left: 0; bottom: 0;
  padding: clamp(1.25rem, 3vw, 2.5rem);
  display: flex; flex-direction: column; gap: .3rem;
}
.detail { font-size: .95rem; color: rgba(240, 234, 221, .84); }
.detail--strong { font-family: var(--mono); font-size: 1.1rem; color: var(--ivory); }
.detail--fine { font-size: .78rem; color: var(--sand); margin-top: .3rem; }
/* Label and number on one line, so two numbers cost two rows rather than four
   in a block that is already sitting in the corner of a video. min-width holds
   the numbers in a column the way the opening hours align — 5rem clears the
   longest label in either language (KUĢĪTIS / BOAT). Baseline, not centre: the
   label is body face at .7rem and the number is mono at 1.1rem, and centring
   two different faces at two different sizes leaves both looking adrift. */
.detail--tel { display: flex; align-items: baseline; gap: .55rem; }
.detail__tag {
  font-family: var(--body);
  font-size: .7rem; font-weight: 400;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--sand);
  /* Sized for the longest label in either language — "Boat tours" — so both
     rows share one column and the two phone numbers start on the same x.
     min-width is a floor, not a cap: at 5rem the longer label simply grew and
     pushed its own number 4.7px right of the one above it. Shorten this and
     that misalignment comes back rather than the text clipping. */
  min-width: 5.5rem;
}
a.detail { width: fit-content; transition: color .25s var(--ease); }
a.detail:hover { color: var(--amber-lit); }

.wayfind { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: .9rem; }
.wayfind a {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .5rem .95rem;
  border-radius: 100px;
  border: 1px solid rgba(240, 234, 221, .18);
  background: rgba(7,15,14,.55);
  backdrop-filter: blur(8px);
  font-size: .78rem;
  transition: background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.wayfind a:hover { background: var(--amber); color: var(--wood); border-color: transparent; }

.socials { display: flex; gap: .9rem; margin-top: .9rem; color: var(--sand); }
.socials a { transition: color .25s var(--ease); }
.socials a:hover { color: var(--amber-lit); }

/* =========================================================
   FOOTER — the water has already gone dark by here
   ========================================================= */
.foot {
  position: relative; z-index: 1;
  padding: clamp(3rem, 8vh, 6rem) var(--gut) clamp(2rem, 5vh, 3rem);
}
/* The footer is the one place where the page and the bank occupy the same
   ground: the reeds are fixed to the bottom of the viewport, and this is what
   is there when you reach the bottom of the document. A veil painted inside
   the footer's own stacking context covers the bank without touching the
   cards, and settles the text back down. It reads as the water going dark,
   which is where the gradient was heading anyway. */
/* Runs past the footer's own box by the height of the dock. <body> carries
   that much bottom padding to keep the dock clear of the content, and it sits
   outside the footer — so a veil stopping at the footer's edge left a bright
   band of unveiled reeds in the last 92px of the page. */
.foot::before {
  content: ''; position: absolute; z-index: -1;
  inset: 0 0 calc(var(--dock-h) * -1) 0;
  background: linear-gradient(to bottom,
    rgba(8,17,15,0) 0%, rgba(8,17,15,.44) 22%,
    rgba(8,17,15,.72) 48%, rgba(8,17,15,.90) 78%, rgba(8,17,15,.94) 100%);
  pointer-events: none;
}

/* Centred as a group rather than stretched across the stack's full width.
   Three short lists do not fill that measure — spread out, the outer two sat
   right in the reeds while the middle of the page stood empty, which is what
   made it read as a hole rather than a footer. */
/* Two link columns, not three. The imprint has no heading, so as a third
   column it sat lower and wider than the other two and pulled the group's
   weight to the right of the page's centre line even while the grid itself
   was centred. Underneath, on its own rule, it balances. */
.foot__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, auto));
  justify-content: center;
  /* Column gap only — the imprint's own margin sets the vertical step, and a
     row gap here would stack on top of it. */
  gap: 0 clamp(2.5rem, 8vw, 6rem);
  max-width: 43.75rem;
  margin-inline: auto;
  text-align: center;
}
.foot__col {
  display: flex; flex-direction: column; align-items: center;
  gap: .45rem; font-size: .88rem;
}
.foot__col h3 {
  font-family: var(--mono); font-weight: 400; font-size: .66rem;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--amber); margin-bottom: .35rem;
}
.foot__col a { color: var(--sand); transition: color .25s var(--ease); }
.foot__col a:hover { color: var(--ivory); }
.foot__col--end {
  grid-column: 1 / -1;
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  padding-top: 1.2rem;
  border-top: 1px solid rgba(240, 234, 221, .1);
  gap: .2rem;
  color: var(--sand); font-size: .78rem;
}

/* =========================================================
   FLOATING DOCK
   Three groups: the state of the place, the links, the mark.
   ========================================================= */
.dock {
  position: fixed; left: 0; right: 0; bottom: clamp(.75rem, 2vh, 1.25rem);
  z-index: 200;
  display: flex; align-items: center; justify-content: center;
  gap: .5rem;
  padding-inline: var(--gut);
  pointer-events: none;
}
.dock > * { pointer-events: auto; }

.dock__group {
  display: flex; align-items: center; gap: .2rem;
  padding: .3rem;
  border-radius: 100px;
  background: rgba(7, 15, 14, .62);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(240, 234, 221, .12);
}
.dock__link {
  padding: .5rem 1.05rem;
  border-radius: 100px;
  font-size: .82rem; letter-spacing: .04em;
  color: var(--sand);
  transition: background .25s var(--ease), color .25s var(--ease);
}
.dock__link:hover { color: var(--ivory); }
.dock__link.is-active { background: var(--ivory); color: var(--wood); }

/* =========================================================
   WHAT'S PLAYING
   Leftmost in the dock, so it can never land on a card at any
   width. The panel opens upward out of the pill.
   ========================================================= */
.np { position: relative; }

.np__toggle {
  display: flex; align-items: center; gap: .6rem;
  padding: .5rem 1.1rem .5rem .9rem;
  border-radius: 100px;
  background: rgba(7, 15, 14, .62);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(240, 234, 221, .12);
  color: var(--ivory);
  font-family: var(--body);
  cursor: pointer;
  text-align: left;
  white-space: nowrap;
  transition: background .25s var(--ease), border-color .25s var(--ease);
}
.np__toggle:hover,
.np__toggle[aria-expanded="true"] {
  background: rgba(7, 15, 14, .82);
  border-color: rgba(212, 146, 42, .45);
}

/* Three bars, staggered — reads as sound without a logo. */
.np__eq { display: flex; align-items: flex-end; gap: 2px; height: 14px; }
.np__eq i {
  display: block; width: 2px; height: 100%;
  background: var(--amber);
  transform-origin: bottom;
  animation: eq .9s ease-in-out infinite;
}
.np__eq i:nth-child(2) { animation-delay: .18s; }
.np__eq i:nth-child(3) { animation-delay: .36s; }
@keyframes eq {
  0%, 100% { transform: scaleY(.28); }
  50%      { transform: scaleY(1); }
}
/* Paused or closed: the bars hold still and dim. */
.np--idle .np__eq i { animation: none; transform: scaleY(.28); background: var(--sand); }

.np__text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.np__label {
  font-family: var(--mono);
  font-size: .74rem; letter-spacing: .04em;
  color: var(--sand);
  transition: color .25s var(--ease);
}
.np__toggle:hover .np__label,
.np__toggle[aria-expanded="true"] .np__label { color: var(--ivory); }

/* Only shown once a live endpoint is supplying a track name. */
.np__track {
  font-family: var(--mono); font-size: .7rem;
  max-width: 22ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--amber-lit);
}
.np__track[hidden] { display: none; }
.np--live .np__label {
  font-size: .55rem; letter-spacing: .26em; text-transform: uppercase;
  color: var(--amber);
}

.np__panel {
  position: absolute; bottom: calc(100% + .5rem); left: 0;
  width: min(320px, calc(100vw - var(--gut) * 2));
  padding: .5rem;
  border-radius: 18px;
  background: rgba(7, 15, 14, .93);
  backdrop-filter: blur(18px);
  border: 1px solid rgba(240, 234, 221, .12);
}
.np__panel[hidden] { display: none; }

.np__embed iframe { display: block; width: 100%; border: 0; border-radius: 12px; }
.np__setup { padding: 1rem; font-size: .78rem; line-height: 1.6; color: var(--sand); }
.np__setup code { font-family: var(--mono); font-size: .92em; color: var(--amber); }

.np__open {
  display: block; margin-top: .5rem;
  padding: .6rem;
  border-radius: 12px;
  text-align: center;
  font-family: var(--mono);
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  background: rgba(240, 234, 221, .08);
  transition: background .25s var(--ease), color .25s var(--ease);
}
.np__open:hover { background: var(--amber); color: var(--wood); }

/* ---- language, riding inside the nav pill ---- */
.dock__sep {
  width: 1px; height: 18px;
  margin-inline: .4rem;
  background: rgba(240, 234, 221, .18);
}

.lang { display: flex; gap: .1rem; }
.lang__opt {
  padding: .5rem .6rem;
  border: 0; border-radius: 100px;
  background: transparent;
  color: var(--sand);
  font-family: var(--mono); font-size: .7rem;
  letter-spacing: .08em;
  cursor: pointer;
  transition: color .25s var(--ease), background .25s var(--ease);
}
.lang__opt:hover { color: var(--ivory); }
.lang__opt--active { background: rgba(240, 234, 221, .14); color: var(--ivory); }

.sheet__lang {
  display: flex; gap: .3rem;
  margin-top: .35rem; padding: .5rem;
  border-top: 1px solid rgba(240, 234, 221, .1);
}
.sheet__lang .lang__opt { flex: 1; padding-block: .8rem; font-size: .8rem; }

/* ---- the mark: spāre means dragonfly ---- */
.dock__mark {
  display: flex; align-items: center; gap: .55rem;
  padding: .45rem 1.05rem;
  border-radius: 100px;
  background: rgba(7, 15, 14, .62);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(240, 234, 221, .12);
  transition: background .25s var(--ease), color .25s var(--ease);
}
.dock__mark:hover { background: var(--amber); color: var(--wood); }
.dock__mark svg { flex: none; width: 22px; height: 22px; color: var(--amber); transition: color .25s var(--ease); }
.dock__mark:hover svg { color: var(--wood); }
.dock__mark-name {
  font-family: var(--display); font-weight: 400; font-stretch: 118%;
  font-size: .9rem; letter-spacing: .2em; text-transform: uppercase;
}

.dock__burger {
  display: none;
  width: 46px; height: 46px;
  border-radius: 100px;
  background: rgba(7, 15, 14, .62);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(240, 234, 221, .12);
  cursor: pointer;
  flex-direction: column; justify-content: center; align-items: center; gap: 5px;
}
.dock__burger span {
  display: block; height: 1px; width: 18px; background: var(--ivory);
  transition: transform .3s var(--ease);
}
.dock__burger[aria-expanded="true"] span:first-child { transform: translateY(3px) rotate(45deg); }
.dock__burger[aria-expanded="true"] span:last-child  { transform: translateY(-3px) rotate(-45deg); }

.sheet {
  position: fixed; left: var(--gut); right: var(--gut);
  bottom: calc(var(--dock-h) - .25rem);
  z-index: 199;
  display: flex; flex-direction: column;
  padding: .5rem;
  border-radius: 20px;
  background: rgba(7, 15, 14, .93);
  backdrop-filter: blur(18px);
  border: 1px solid rgba(240, 234, 221, .12);
}
.sheet[hidden] { display: none; }
.sheet a {
  padding: .9rem 1rem;
  border-radius: 14px;
  font-size: .95rem;
  transition: background .25s var(--ease);
}
.sheet a:hover { background: rgba(240, 234, 221, .08); }

/* =========================================================
   DESKTOP — use the width instead of centring a narrow column
   ========================================================= */
@media (min-width: 1024px) {

  /* The story sits in the column beside the photographs and stays put while
     they scroll, instead of occupying a card of its own. */
  .card--quad {
    display: grid;
    grid-template-columns: minmax(300px, 1fr) minmax(0, 1.55fr);
    gap: clamp(2.5rem, 5vw, 5rem);
    /* Stretch, not start: the two columns are set by different things — the
       left by how much copy there is, the right by the pictures' aspect —
       and they will never agree by accident. Left to size themselves the
       photographs ran out well above the text and left a hole the size of a
       picture in the bottom right of the card. Stretching lets the grid rows
       take whatever height the column has, so the two always end together. */
    align-items: stretch;
  }
  .card--quad .say {
    max-width: none; margin: 0;
    position: sticky; top: clamp(2rem, 8vh, 4.5rem);
    align-self: start;   /* sticky needs its own height, not the stretched one */
  }
  .card--quad .quad {
    max-width: none; margin: 0; padding-block: 34px;
    height: 100%;
    grid-template-rows: 1fr 1fr;
  }
  /* The cells now take their height from the row rather than from the file,
     so the crop does the adapting instead of the layout. */
  .card--quad .quad__cell { min-height: 0; }
  .card--quad .quad__cell img { height: 100%; aspect-ratio: auto; }

  .say__lead { font-size: clamp(2.1rem, 3.1vw, 3.1rem); }
  .say__body p { font-size: 1.02rem; }

  .say__photo {
    display: block;
    margin-top: clamp(1.75rem, 3vw, 2.75rem);
    border-radius: calc(var(--radius) * .6);
    overflow: hidden;
  }
  /* 2:3 matches the source, so the boathouse is filled rather than cropped. */
  .say__photo img {
    width: 100%; aspect-ratio: 2 / 3; object-fit: cover;
    transition: transform 1s var(--ease);
  }
  .say__photo:hover img { transform: scale(1.04); }

  /* Two tours side by side once there is room for both date boards. */
  .tours { grid-template-columns: 1fr 1fr; }

  /* The intro deliberately keeps its single stacked column here. An earlier
     build split it into two so the quote rode beside the heading; the rule
     between them then had to line up with the date boards below, which it
     could not do reliably because the two gaps were clamped at different
     rates. Stacked and centred, there is no seam to keep in register. */
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width: 860px) {
  .card--hero  { aspect-ratio: auto; min-height: 80svh; }
  .card--visit { aspect-ratio: auto; min-height: 68svh; }

  /* At phone width a 150px map is decoration, not navigation — drop the tile
     and keep the label as a directions pill so the hours get room. */
  .minimap {
    width: auto;
    right: var(--gut); bottom: var(--gut);
    border-radius: 100px;
  }
  .minimap iframe { display: none; }
  .minimap__label { padding: .55rem 1rem; }
  .minimap__label span { display: none; }

  /* A phone has no gutters — the cards run edge to edge, so the only place
     the bank can show is the strip below the last card and around the dock.
     The far pair is dropped and the near pair pulled further out, leaving a
     suggestion at each bottom corner rather than two plants in the way. */
  .sprig--far, .sprig--mid { display: none; }
  .sprig { width: min(260px, 62vw); }
  .sprig--l1 { translate: -44% 18%; }
  .sprig--r1 { translate:  40% 16%; }

  /* A portrait viewport crops the sides off a landscape frame, and the family
     on the jetty sits about two thirds across — centred, they end up jammed
     against the right edge or cut in half. Anchoring the crop on them instead
     of on the middle of the picture puts them back in the frame. */
  .card--hero .card__bg { object-position: 68% 58%; }

  /* Only the hero has a floating map to keep clear of. */
  .card--hero .card__hours { padding-right: 40%; }

  /* The closing card repeats the hours purely to balance the empty
     bottom-right of the desktop layout. On a phone there is no empty corner,
     they collide with the contact details, and the hero has shown them. */
  .card--visit .card__hours--right { display: none; }

  /* Its scrim leans left on desktop because the copy sits in a left column.
     At this width the copy spans the whole card, so that pass buys nothing
     and the standfirst lands on the brightest part of the footage. Straight
     top-to-bottom instead, and heavier at the head. */
  .card--visit .card__scrim {
    background:
      linear-gradient(to bottom, rgba(7,13,20,.74) 0%, rgba(7,13,20,.32) 34%,
                                 rgba(7,13,20,.36) 62%, rgba(7,13,20,.80) 100%);
  }

  .quad__cell--a, .quad__cell--c { transform: translateY(20px); }
  .quad__cell--b, .quad__cell--d { transform: translateY(-20px); }
  .quad { padding-block: 20px; }

  /* Already two columns and centred; just tighten the gap for phone width. */
  .foot__cols { gap: 0 2.5rem; }

  .dock__group--links { display: none; }
  .dock__burger { display: flex; }

  /* Collapses to the equalizer alone, so the dock reads
     [music] [SPĀRE] [menu] — three even weights. */
  .np__text { display: none; }
  .np__toggle {
    width: 46px; height: 46px;
    padding: 0; gap: 0;
    justify-content: center;
  }
  .dock__mark-name { font-size: .82rem; letter-spacing: .16em; }
  .dock { gap: .4rem; }

  /* Anchored to the viewport, not the pill — the pill sits at the left end of
     the dock, so a 320px panel hung off it would run past the right edge. */
  .np__panel {
    position: fixed;
    left: var(--gut); right: var(--gut);
    bottom: calc(var(--dock-h) - .25rem);
    width: auto;
  }
}

@media (max-width: 420px) {
  .card__head { max-width: none; padding-right: 1rem; }
  .hours { font-size: .72rem; }
  .hours dt { min-width: 6.5em; }
  .dock__mark-name { display: none; }
  .dock__mark { padding: .45rem .8rem; }
}

/* =========================================================
   REDUCED MOTION
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}
