/*--------------------------------------------------------------
# Vivid Enhancements & Premium Touches
--------------------------------------------------------------*/

/* 1. Tropical Coral Glow (Buttons) */
.btn-primary,
.btn-accent,
.btn-submit {
  box-shadow: 0 4px 15px color-mix(in srgb, var(--btn-color), transparent 60%) !important;
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) !important;
}

.btn-primary:hover,
.btn-accent:hover,
.btn-submit:hover {
  transform: translateY(-3px) !important;
  box-shadow: 0 8px 25px color-mix(in srgb, var(--btn-color), transparent 40%) !important;
  background-color: var(--btn-hover-color) !important;
  border-color: var(--btn-hover-color) !important;
}

/* Secondary Button Glows (Outline/White) */
.btn-outline,
.btn-light {
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) !important;
}

/* No shadow on the hover. A white "shadow" does not read as a shadow at all,
   only as a halo around the button, which is a decorative light effect rather
   than a lift. The translate carries the hover on its own. */
.btn-outline:hover,
.btn-light:hover {
  transform: translateY(-3px) !important;
}


/* 2. Premium Accent Edges & Soft Shadows (Cards and Forms) */
.booking-form,
.tour-card,
.feature-card,
.destination-tile,
.service-item,
.booking-summary,
.booking-form-container {
  border-top: 4px solid var(--accent-color);
  /* Premium Edge */
  box-shadow: 0 10px 30px rgba(17, 17, 17, 0.08) !important;
  /* Soft Cool Navy Shadow */
  transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1) !important;
}

/* Alternate Gold Edge for specifics if needed */
.tour-badge.luxury,
.badge-offer.limited {
  border-top: 2px solid var(--accent-color);
  box-shadow: 0 4px 15px color-mix(in srgb, var(--accent-color), transparent 60%) !important;
}

/* 3. Micro-Animations (Card Hover states) */
.tour-card:hover,
.feature-card:hover,
.service-item:hover {
  transform: translateY(-8px) !important;
  box-shadow: 0 15px 40px rgba(17, 17, 17, 0.15) !important;
  /* Deepens the navy shadow on hover */
}


/* 4. Dark section backgrounds.
   These used to carry a 135deg gradient from var(--default-color) to #000. On a
   .dark-background block --default-color resolves to #ffffff, so the "deep
   gradient" was actually white to black: a grey diagonal wash behind the page
   headers and the footer that fought with the white type sitting on it.
   Flat brand black instead. The `background-color` shorthand is deliberate: the
   page headers set their own background-image, and `background` would wipe it. */
.dark-background,
.footer-newsletter,
.cta-section {
  background-color: #111111 !important;
  border-top: none;
  /* remove any default edges on dark sections */
}

/* A little more colour in the header photography and the hero footage. The
   plates come off the camera a touch flat for a valley this green, and with
   the scrim gone there is nothing left to hide it.

   On the page headers the photograph is the SECTION's own background, so a
   filter on the element would drag the heading through it too. backdrop-filter
   on the ::before works instead: it filters only what is already painted
   behind that layer -- the photograph -- while the type, which paints after
   it, comes through untouched.

   The video is a real element, so it takes a plain filter. Both are kept
   modest: past about 1.2 the greens go synthetic and skin tones turn orange,
   which on the carnival footage is very obvious. */
.page-title::before {
  -webkit-backdrop-filter: saturate(1.18);
  backdrop-filter: saturate(1.18);
}

.travel-hero .hero-background video,
.travel-hero .hero-background img {
  filter: saturate(1.15);
}

/* The landmark plates are a background on the wrapper, so the same ::before
   trick applies -- the caption band is that ::before's sibling and keeps its
   own colour. */
.travel-tour-details .tour-hero .hero-image-wrapper {
  position: relative;
}

.travel-tour-details .tour-hero .hero-image-wrapper::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  -webkit-backdrop-filter: saturate(1.18);
  backdrop-filter: saturate(1.18);
}

/* Page headers carry photography, so their ground is the image, not the fill.
   The scrim in main.css (.page-title:before) is what keeps the type readable. */
.page-title.dark-background {
  background-color: #111111 !important;
  background-size: cover !important;
  background-position: center !important;
  background-repeat: no-repeat !important;
}

/* 5. Secondary section ground.
   A flat surface, not a wash. This carried a 3% gold-to-cyan diagonal gradient
   across every quiet section on the site: invisible at that strength, and a
   decorative 135deg gradient on a page background is the template reflex the
   rest of this pass is removing. The sections carry their accents through
   their own headings, marks and rules, which is where colour belongs. */
.light-background {
  background-image: none !important;
  background-color: var(--surface-color) !important;
}


/* General Input Focus Glow */
.form-control:focus,
.form-select:focus {
  box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--btn-color), transparent 75%) !important;
  border-color: var(--accent-color) !important;
}



/* 6. Hero Booking Form Wrapper Override for Visibility */
.travel-hero .booking-form-wrapper {
  background: var(--surface-color) !important;
  border-radius: 8px !important;
  box-shadow: 0 10px 30px color-mix(in srgb, var(--default-color), transparent 85%) !important;
  /* Ensuring the form stays visible over the dark hero image */
  position: relative;
  z-index: 10;
}
/* 7. Typography on the brand-red section band (--tertiary-accent).
   Red is a dark ground (relative luminance ~0.15), so the type on it is white
   and the small pill badge flips to the off-white/near-black pairing. Black
   text on this red measures ~3.5:1, under the 4.5:1 minimum, which is why the
   previous dark heading colour is not reused here. */
#why-choose-us {
  background-color: var(--tertiary-accent) !important;
}

/* The eyebrow is a bare label everywhere now, so on this red band it only
   needs a colour that holds against it. Gold measures 1.8:1 on the red and is
   unusable here; the off-white measures 5.3:1. */
#why-choose-us .section-title .section-eyebrow {
  color: var(--background-color) !important;
}

/* The 10px gap between eyebrow and heading that used to be patched in here is
   now in the base sheet: .section-title selects h3 alongside div, so every
   section-title block on every route gets it. Only the colour override for this
   band's red ground remains. */
#why-choose-us .section-title h2,
#why-choose-us .section-title h3,
#why-choose-us .section-title > div > span {
  color: var(--contrast-color) !important;
}

#why-choose-us .section-title p {
  color: color-mix(in srgb, var(--contrast-color) 88%, transparent) !important;
  max-width: 640px;
  margin: 18px auto 0;
}

#why-choose-us .section-title .description-title {
  color: var(--secondary-accent) !important; /* brand gold accent against the red */
}

/* The band opens tighter than the rest of the page. .section gives every
   section 60px of top padding and .section-title adds 60px below itself, which
   stacked into a gap the red ground made impossible to ignore -- on a white
   section the same space reads as breathing room. */
#why-choose-us.section {
  padding-top: 34px;
}

#why-choose-us .section-title {
  padding-bottom: 22px;
}

/* The template opens 5rem between a .why-us section title and its cards. On a
   white section that is breathing room; on this red ground it is 80px of flat
   colour between the lead line and the first tile, which is what the client
   was looking at. Cut to a third of it -- the band still has air, but the lead
   and the tiles now read as one block. */
#why-choose-us .why-choose-section {
  margin-top: 28px;
}

/* Essential Sites eyebrow on the near-black band. The gold it inherits
   measures 6.2:1 there and needs nothing else; this rule exists only to undo
   the cyan wash the capsule carried. */
#featured-destinations .section-title .section-eyebrow {
  background-color: transparent !important;
}

/* The two sector buttons under the intro copy. Same flex-gap treatment as the
   hero row so the pair never sits flush when it wraps on narrow screens. */
#featured-destinations .sector-buttons {
  gap: 14px 16px;
}

/* .btn-primary and .btn-outline only carry brand styling inside the hero
   (main.css L1147-1179). Anywhere else, .btn-primary falls through to
   Bootstrap's default blue and .btn-outline gets no rule at all, which on this
   near-black band renders as dark text on dark. These mirror the hero
   treatment so the pair reads as the same button system. */
#featured-destinations .sector-buttons .btn {
  padding: 12px 30px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-radius: 50px;
  transition: all 0.3s ease;
}

/* The pair reads as one choice, not a primary and a fallback: both sit as
   outlines on the dark band and both fill gold on hover, so neither sector is
   presented as the preferred one. .btn-primary is still in the markup, so it is
   overridden here rather than left to its hero treatment. */
#featured-destinations .sector-buttons .btn.btn-primary,
#featured-destinations .sector-buttons .btn.btn-outline {
  background-color: transparent !important;
  border: 1px solid var(--contrast-color) !important;
  color: var(--contrast-color) !important;
  /* The global .btn-primary glow (L9) is a halo on this near-black band, not a
     lift, and only one of the pair would carry it. */
  box-shadow: none !important;
}

#featured-destinations .sector-buttons .btn.btn-primary:hover,
#featured-destinations .sector-buttons .btn.btn-outline:hover {
  background-color: var(--btn-color) !important;
  border-color: var(--btn-color) !important;
  color: #ffffff !important;
  box-shadow: none !important;
  transform: translateY(-2px) !important;
}

/* Same fall-through on the affiliate partner CTAs in the landmark pages: they
   are plain Bootstrap .btn-primary with no brand rule of their own, so without
   this they render Bootstrap blue (rgb(13, 110, 253)) -- a colour that is not
   in the palette at all. Colour only; padding, font and radius stay on
   Bootstrap's defaults so the buttons keep their dimensions.

   .lmn-actions is the newspaper layout's strip. .tour-start-times was the
   container before that redesign and no longer exists in the markup; it is
   kept in the selector only because main.css still styles it, so a future
   revert does not silently take the colour with it. */
.travel-tour-details .lmn-actions .btn.btn-primary,
.travel-tour-details .tour-start-times .btn.btn-primary {
  background-color: var(--secondary-accent);
  border-color: var(--secondary-accent);
  color: var(--contrast-color);
}

/* The darker hover comes from the global .btn-primary:hover at the top of this
   file, which is !important and already resolves to --btn-hover-color (#A66F08,
   the darker gold). A local hover rule here would simply lose to it, so this
   only restates the text colour, which that rule does not set. */
.travel-tour-details .lmn-actions .btn.btn-primary:hover,
.travel-tour-details .tour-start-times .btn.btn-primary:hover {
  color: var(--contrast-color);
}

/* Cards keep dark text on their light surface. */
#why-choose-us .feature-card h4,
#featured-destinations .tour-card h4 {
  color: var(--default-color) !important;
}

#why-choose-us .feature-card p,
#featured-destinations .tour-card p {
  /* --muted-color, not the raw Tailwind gray-700 this was. docs/style.md gives
     that token its own name precisely because pages kept writing these greys
     by hand, and a blue-tinted grey next to the brand ink reads as a different
     black. */
  color: var(--muted-color) !important;
}

/* 8. Wordmark
   Replaces the inherited Eliot's Adventures logo artwork. Text, not an image,
   so there is no placeholder asset to forget about, swap these rules for an
   <img> once real Cajamarca.com branding exists. Heights match the logo files
   they replaced (48px header, 80px footer block) so the layout is unchanged. */
.header .logo .header-wordmark {
  display: block;
  line-height: 48px;
  font-family: 'SFC La Pura', 'Armonia Forte', system-ui, sans-serif;
  font-size: 26px;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: #fff;
  white-space: nowrap;
}

.header .logo .header-wordmark .wordmark-tld {
  opacity: 0.7;
  font-size: 0.7em;
}

/* Footer uses the full lockup, vicunas above the wordmark, so the mark
   reads as the complete brand at the close of the page. */
.footer .footer-about .footer-logo {
  display: block;
  width: 400px;
  max-width: 100%;
  height: auto;
  margin-bottom: 12px;
}

@media (max-width: 991.98px) {
  .footer .footer-about .footer-logo { width: 300px; }
}

@media (max-width: 1199.98px) {
  .header .logo .header-wordmark { font-size: 24px; }
}

/* Header logo artwork: the stacked vicuna lockup, positioned so only the
   vicunas break out above the pill while the wordmark stays down inside it.

   Measured from the source art (1820x983): the vicunas occupy the top 0-700px
   and the CAJAMARCA.COM wordmark block sits at 710-983px, so the wordmark's
   centre is at 86.1% of the image height. Anchoring on that percentage is what
   makes this work at any size: the img is absolutely positioned at the vertical
   centre of the pill and then pulled up by 86.1% of its own height, which lands
   the wordmark centred in the bar and leaves the vicunas hanging above it.
   Centring the whole image instead is what pushed the `.com` below the pill.

   Because the img is absolute, it is out of flow and the pill's 70px height is
   driven entirely by the nav, unchanged. The link keeps a fixed-width column so
   the nav does not shift; widths are the rendered width (height x 1.851) plus a
   few px. The header gains padding-top to give the vicunas somewhere to go, so
   the pill sits lower down the viewport but is not itself resized. */
.header {
  height: 120px;
  padding-top: 40px;
}

.header .logo {
  position: relative;
  align-self: stretch;
  flex: 0 0 160px;
  width: 160px;
}

.header .logo img.header-logo {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-86.1%);
  height: 84px;
  width: auto;
  max-width: none;
  /* The artwork is forced to pure white (main.css), which is fine over the dark
     pill but leaves the overhanging vicunas invisible on the light-background
     pages (/travel-tips, /privacy, /terms, the 404). A tight dark halo on the
     strokes fixes that without a per-route class: over the pill and the dark
     heroes it is imperceptible, and on a white page it is what draws the
     outline. Two stacked shadows because the art is thin open linework - the
     1px pass defines the strokes, the softer pass seats the shape. */
  filter: brightness(0) invert(1)
          drop-shadow(0 0 1px rgba(0, 0, 0, 0.9))
          drop-shadow(0 1px 4px rgba(0, 0, 0, 0.55));
}

@media (max-width: 1400px) {
  .header .logo { flex-basis: 146px; width: 146px; }
  .header .logo img.header-logo { height: 78px; }
}

/* Below 1200px the nav collapses to the drawer, so the logo only shares the bar
   with the burger and can stay generous; the header keeps enough padding above
   the pill for the vicunas at this size (0.861 x 72 - 35 = ~27px of overhang). */
@media (max-width: 1199.98px) {
  .header {
    height: 104px;
    padding-top: 34px;
  }

  .header .logo { flex-basis: 136px; width: 136px; }
  .header .logo img.header-logo { height: 72px; }
}

/* 10. Hero legibility over video.
   The clip is bright (sky, pale plaza stone) and its content changes constantly,
   so white text cannot rely on the footage staying dark. Two layers fix it
   without touching the artwork:
     1. a scrim anchored to the left, where the text column sits, fading out to
        the right so the footage stays visible;
     2. a soft shadow on the type itself, which carries the letterforms over any
        bright frame that still shows through.
   A black outline was the other option; it thickens the heading face's already
   heavy strokes and muddies the counters, so shadow + scrim is used instead.

   The scrim is gone entirely: the client wants the footage, not a dimmed
   version of it. Only the scrim ever darkened the video -- a text-shadow is
   local to the glyphs and costs the picture nothing -- so the shadows were
   deepened and left to carry legibility on their own. */
.travel-hero .hero-overlay {
  background: none;
}

.travel-hero .hero-text .hero-title {
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.9),
    0 2px 6px rgba(0, 0, 0, 0.85),
    0 4px 20px rgba(0, 0, 0, 0.8),
    0 8px 44px rgba(0, 0, 0, 0.7);
}

.travel-hero .hero-text .hero-subtitle {
  opacity: 1;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.9),
    0 2px 6px rgba(0, 0, 0, 0.85),
    0 3px 16px rgba(0, 0, 0, 0.8),
    0 6px 34px rgba(0, 0, 0, 0.7);
}

/* No scrim on narrow screens either: the footage stays clear at every width
   and the shadows above carry the type. */

/* 12. Header that retreats on the way down.
   Layout.jsx toggles .nav-hidden on <body> from a scroll listener. The offset
   below is the one number the sticky filter bar keys off, so both move as one:
   header height while the header is visible, zero once it has slid away. */
:root {
  --sticky-offset: 120px;
}

@media (max-width: 1199.98px) {
  :root { --sticky-offset: 104px; }
}

body.nav-hidden {
  --sticky-offset: 0px;
}

.header {
  transition: transform 0.3s ease, background-color 0.5s, box-shadow 0.5s;
  /* No will-change: transform here. It would make the header a containing
     block for fixed-position descendants, and the mobile menu (.navmenu,
     position: fixed; inset: 0) would then size itself to the 80px header and
     clip its own list away instead of covering the viewport. */
}

body.nav-hidden .header {
  transform: translateY(-100%);
}

/* Keyboard users must never lose the nav, so keyboard focus inside the header
   pins it open whatever the scroll direction said.
   :focus-visible, not :focus-within: clicking a nav link leaves focus on that
   link, and :focus-within would then pin the header open for the rest of the
   visit, which is exactly what happened after any in-site navigation. */
.header:has(:focus-visible) {
  transform: none !important;
}

/* With the mobile menu open the header carries the menu itself, so hiding it
   on scroll would take the open menu off screen with it. */
body.mobile-nav-active .header {
  transform: none !important;
}

/* 13. Filter bar that sticks under the header.
   Long lists mean the pills scroll out of reach, forcing a trip back to the
   top to change filter. Sticking them keeps the control with the content.
   The row sits inside a .col-12 that also wraps the card grid, so the sticky
   element stays parked for exactly as long as there are cards beside it. */
.travel-tours .destination-filters {
  position: sticky;
  top: var(--sticky-offset);
  z-index: 996; /* under the header (997), over the cards */
  background: var(--background-color);
  margin-left: -12px;
  margin-right: -12px;
  padding: 14px 12px;
  box-shadow: 0 6px 18px rgba(17, 17, 17, 0.06);
  transition: top 0.3s ease;
}

/* On a phone the eight pills wrap onto four rows, 222px tall, which is over a
   quarter of the viewport for a bar that never scrolls away. One row that
   scrolls sideways instead, the usual chip-row pattern. */
@media (max-width: 767.98px) {
  .travel-tours .destination-filters {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .travel-tours .destination-filters::-webkit-scrollbar {
    display: none;
  }

  .travel-tours .destination-filters li {
    flex: 0 0 auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .header,
  .travel-tours .destination-filters {
    transition: none;
  }
}

/* 11. Hero button row.
   Six buttons wrap onto two rows at most desktop widths. Bootstrap's me-3
   only spaced them horizontally, so the wrapped rows sat flush against each
   other. A flex gap spaces both axes and stays correct at any wrap point. */
.travel-hero .hero-text .hero-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 18px;
}

/* One treatment for all six, replacing the primary-plus-outlines split.

   They also need a ground of their own now. The scrim came off the footage, so
   a transparent button with a white hairline sat on whatever the video happened
   to be showing -- white sky behind a white border is nothing at all. A dark
   glass fill gives every button the same ground at every frame, and blurs what
   is behind it just enough to settle the label without dimming the picture
   around it.

   Hover goes to brand gold rather than cyan: gold is this site's action colour
   everywhere else, and against a valley of greens and sky blues it is the one
   accent that does not sit inside the photograph's own palette. */
.travel-hero .hero-text .hero-buttons .btn.btn-outline {
  background-color: rgba(10, 12, 14, 0.34);
  -webkit-backdrop-filter: blur(3px) saturate(1.1);
  backdrop-filter: blur(3px) saturate(1.1);
  border: 1.5px solid rgba(255, 255, 255, 0.85);
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
}

.travel-hero .hero-text .hero-buttons .btn.btn-outline:hover,
.travel-hero .hero-text .hero-buttons .btn.btn-outline:focus-visible {
  background-color: var(--btn-color);
  border-color: var(--btn-color);
  color: #fff;
  text-shadow: none;
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.3);
}

/* 9. Header wordmark `.com` span.
   main.css sets font-family on the bare `span` element, and that direct rule
   beats inheritance, so the `.com` inside the wordmark fell back to Inter
   while the rest of the logo used the display face. Force it to inherit.
   Header only: the footer wordmark uses Armonia Forte. */
.header .logo .header-wordmark .wordmark-tld {
  font-family: inherit;
}

/* The mosaic's own call to action. .btn-primary only carries brand styling
   inside the hero (main.css L1147-1179), so everywhere else it falls through
   to Bootstrap's default blue -- #0d6efd, a colour that appears nowhere in
   this palette and was sitting under a section whose pill is cyan and whose
   links are gold. Brand gold, in the same pill the About page's CTA uses. */
#news-advice .btn.btn-primary {
  background-color: var(--btn-color);
  border-color: var(--btn-color);
  color: var(--contrast-color);
  padding: 12px 30px;
  border-radius: 50px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  transition: all 0.3s ease;
}

#news-advice .btn.btn-primary:hover,
#news-advice .btn.btn-primary:focus-visible {
  background-color: var(--btn-hover-color);
  border-color: var(--btn-hover-color);
  color: var(--contrast-color);
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  #news-advice .btn.btn-primary:hover {
    transform: none;
  }
}

/* 12. News & Advice mosaic (homepage).
   A magazine-style tile grid: photo, dark scrim, title overlaid at the bottom.
   Deliberately NOT the .tour-card treatment used by Essential Sites — the
   editorial section should read as a different kind of content at a glance.

   Desktop layout, six tiles on a 3-column grid of 190px rows:

     +-----------------+--------+
     |                 |   2    |
     |        1        +--------+
     |    (lead, 2x2)  |   3    |
     +--------+--------+--------+
     |   4    |   5    |   6    |
     |  (2r)  |  (2r)  |  (2r)  |
     +--------+--------+--------+

   The lead tile anchors the block; tiles 2 and 3 stack beside it at half its
   height; the bottom row matches the lead's height so the block closes square.
   Below 992px every tile becomes a uniform 4:3 in two columns, and at phone
   widths they stack into one column at 16:10. */
.news-mosaic {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 190px;
  gap: 18px;
}

.news-tile {
  position: relative;
  display: block;
  grid-column: span 1;
  grid-row: span 2;
  overflow: hidden;
  border-radius: 12px;
  text-decoration: none;
  background: #111;
  isolation: isolate;
}

/* Lead tile: double-wide, and the same height as the two tiles stacked beside
   it (2 x 190px + one 18px gap). */
.news-tile--lead {
  grid-column: span 2;
  grid-row: span 2;
}

/* The two tiles alongside the lead are half-height; every tile after them
   returns to the default two-row span. */
.news-tile--half {
  grid-row: span 1;
}

.news-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.6s ease;
}

.news-tile:hover img,
.news-tile:focus-visible img {
  transform: scale(1.06);
}

/* Scrim. Sits above the photo, below the text, and is strongest at the bottom
   where the title lands so the headline stays readable on any image. */
.news-tile::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(17, 17, 17, 0.78) 0%, rgba(17, 17, 17, 0.35) 42%, rgba(17, 17, 17, 0.05) 72%);
}

.news-tile-body {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 1;
  padding: 22px 24px;
  color: #fff;
}

.news-tile-meta {
  display: block;
  margin-bottom: 8px;
  /* 11.5px; the date and category under each headline. */
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent-color);
}

.news-tile-title {
  margin: 0;
  font-family: var(--heading-font);
  font-size: 1.18rem;
  line-height: 1.25;
  color: #fff;
}

.news-tile--lead .news-tile-title {
  font-size: 1.8rem;
}

.news-tile--half .news-tile-title {
  font-size: 1.05rem;
}

.news-tile-excerpt {
  margin: 10px 0 0;
  font-size: 0.9rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.86);
}

/* The excerpt only fits on the lead tile; everywhere else the title and date
   carry the tile on their own. */
.news-tile:not(.news-tile--lead) .news-tile-excerpt {
  display: none;
}

.news-tile:focus-visible {
  outline: 3px solid var(--accent-color);
  outline-offset: 3px;
}

@media (max-width: 991.98px) {
  .news-mosaic {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: auto;
  }

  .news-tile,
  .news-tile--lead,
  .news-tile--half {
    grid-column: span 1;
    grid-row: auto;
    aspect-ratio: 4 / 3;
  }

  .news-tile--lead .news-tile-title,
  .news-tile--half .news-tile-title {
    font-size: 1.2rem;
  }

  .news-tile--lead .news-tile-excerpt {
    display: none;
  }
}

@media (max-width: 575.98px) {
  .news-mosaic {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .news-tile,
  .news-tile--lead,
  .news-tile--half {
    aspect-ratio: 16 / 10;
  }

  .news-tile-body {
    padding: 18px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .news-tile img {
    transition: none;
  }

  .news-tile:hover img {
    transform: none;
  }
}

/* Getting Around on the homepage sits on the brand cyan rather than the pale
   accent wash, so the band reads as a break between the two card sections.
   Cyan is a light ground (relative luminance ~0.45), so everything on it goes
   near-black: the type, the icons and the button. White would measure ~2:1 and
   fail, which is why nothing here inherits the usual dark-section treatment.
   The rules are specific to #getting-around; .light-background elsewhere keeps
   the 3% wash. */
#getting-around.light-background {
  background-image: none !important;
  background-color: var(--accent-color) !important;
}

/* #getting-around is no longer rendered by any page -- the homepage section
   was removed at the client's request and the content lives on
   /getting-here. Kept with the capsule stripped, in case the band returns. */
#getting-around .section-title .section-eyebrow {
  background-color: transparent !important;
  color: var(--default-color) !important;
}

/* The client asked for the section heading in white. It measures ~2:1 on the
   cyan, so it carries a shadow to hold its edges; the body copy below stays
   near-black and does the readable work. */
#getting-around .section-title h2,
#getting-around .section-title h3 {
  color: #ffffff !important;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}

#getting-around .lead,
#getting-around .fs-5 {
  color: #111111 !important;
}

#getting-around .fs-5 i {
  color: #111111 !important;
}

#getting-around .btn.btn-primary {
  background-color: #111111;
  border-color: #111111;
  color: #ffffff;
  padding: 12px 30px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-radius: 50px;
  transition: all 0.3s ease;
  /* Section 1 gives every .btn-primary a gold glow, which turns muddy against
     cyan behind a black button. Dark shadow instead. */
  box-shadow: 0 4px 15px rgba(17, 17, 17, 0.35) !important;
}

#getting-around .btn.btn-primary:hover {
  box-shadow: 0 8px 25px rgba(17, 17, 17, 0.45) !important;
  background-color: #000000 !important;
  border-color: #000000 !important;
  transform: translateY(-2px);
}

/* ---------------------------------------------------------------------------
   14. Brand icon watermarks.

   The designer's six marks -- spiral, wave, llama, bird, figure and sun --
   exported from resources/icons/PNG into /assets/icons/ in the five brand
   values, named <mark>-<colour>.png, plus a tile-<mark>-<colour>.png of each:
   the same art on a taller transparent canvas. CSS can repeat a background but
   cannot put air between the repeats, so the spacing lives in the file.

   Opt-in, by class:

     <section className="section section-mark scatter-b split-up-sun split-down-llama">

   Two rules shape the system.

   FIRST: a section's marks must scale with its height. A page of listings is
   ten times taller than a two-paragraph band, and three marks placed by
   percentage left the long ones looking empty and crushed the short ones into
   a pile. So the scatter is two vertical COLUMNS, one down each side, each
   repeating with background-repeat's `space` keyword: whole marks, evenly
   distributed, never clipped, as many as the section is tall. One band gets
   one or two; a long listing page gets six or eight, on its own.

   SECOND: no mark is ever cut by a seam without continuing on the other side.
   `space` guarantees the columns are never clipped, and the only thing allowed
   to touch a horizontal edge is the continuity pair:

     .split-down-<mark> / .split-up-<mark> -- the mark is halved by the boundary
     between two bands, the top half at the bottom of one section and the
     bottom half at the top of the next, same width and same horizontal offset,
     so the figure rejoins across the seam. Applied as a pair, in DOM order, on
     sections that actually touch. Where the grounds differ the two halves take
     their own band's colour and the shape still carries across.

   Colour is picked for the ground:

     (none)      white and #fcfbf9 -- each mark in its own brand colour
     .on-colour  the red and cyan bands -- cream
     .on-dark    near-black grounds -- cyan, since cream reads as grey haze

   Weight is one number per ground, --section-mark-opacity. The marks are line
   art rather than solid shapes, so they need more of it than a filled
   watermark would.
--------------------------------------------------------------------------- */

.section-mark {
  position: relative;
  /* The columns hang off the side edges, so they read as a cropped pattern
     rather than as stickers placed in the corners. This is also what keeps
     them from adding a horizontal scrollbar.

     `clip` rather than `hidden`, with hidden as the fallback: `hidden` makes
     the section a SCROLL CONTAINER, and a position:sticky child then sticks to
     that box instead of to the viewport. That is what put the Things to Do
     filter strip 120px below the section's top edge, parked on top of the
     first heading. `clip` crops exactly the same way without creating a scroll
     container, so sticky children keep working. */
  overflow: hidden;
  overflow: clip;
  --section-mark-opacity: 0.17;
  /* Light grounds: each mark keeps its own brand colour, so the texture
     changes hue as well as shape down a page. */
  --mk-spiral: url("/assets/icons/spiral-cyan.png");
  --mk-wave: url("/assets/icons/wave-cyan.png");
  --mk-llama: url("/assets/icons/llama-gold.png");
  --mk-bird: url("/assets/icons/bird-terracotta.png");
  --mk-figure: url("/assets/icons/figure-gold.png");
  --mk-sun: url("/assets/icons/sun-terracotta.png");
  --tk-spiral: url("/assets/icons/tile-spiral-cyan.png");
  --tk-wave: url("/assets/icons/tile-wave-cyan.png");
  --tk-llama: url("/assets/icons/tile-llama-gold.png");
  --tk-bird: url("/assets/icons/tile-bird-terracotta.png");
  --tk-figure: url("/assets/icons/tile-figure-gold.png");
  --tk-sun: url("/assets/icons/tile-sun-terracotta.png");
}

/* Every direct child, not only .container: several sections on this site put
   their content in a bare <div> or break it out of the container entirely, and
   a static child would paint under the positioned layers. */
.section-mark > * {
  position: relative;
  z-index: 1;
}

/* ::before carries the two side columns, ::after the halves of the split
   pairs. Keeping them apart is what lets a section do both at once. */
.section-mark::before,
.section-mark::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--section-mark-opacity);
}

/* `space` on the vertical axis: whole tiles, evenly distributed, pinned to the
   two ends, never clipped. The horizontal axis stays no-repeat so each column
   is a single file of marks. */
.section-mark::before {
  background-repeat: no-repeat space, no-repeat space;
}

.section-mark::after {
  background-repeat: no-repeat;
}

/* Grounds ------------------------------------------------------ */

/* Red and cyan bands: cream is a tint of both. */
.section-mark.on-colour {
  --section-mark-opacity: 0.20;
  --mk-spiral: url("/assets/icons/spiral-cream.png");
  --mk-wave: url("/assets/icons/wave-cream.png");
  --mk-llama: url("/assets/icons/llama-cream.png");
  --mk-bird: url("/assets/icons/bird-cream.png");
  --mk-figure: url("/assets/icons/figure-cream.png");
  --mk-sun: url("/assets/icons/sun-cream.png");
  --tk-spiral: url("/assets/icons/tile-spiral-cream.png");
  --tk-wave: url("/assets/icons/tile-wave-cream.png");
  --tk-llama: url("/assets/icons/tile-llama-cream.png");
  --tk-bird: url("/assets/icons/tile-bird-cream.png");
  --tk-figure: url("/assets/icons/tile-figure-cream.png");
  --tk-sun: url("/assets/icons/tile-sun-cream.png");
}

/* Near-black grounds: cyan, which also matches the link colour these sections
   already use. Cream at this size reads as grey haze. */
.section-mark.on-dark {
  --section-mark-opacity: 0.18;
  --mk-spiral: url("/assets/icons/spiral-cyan.png");
  --mk-wave: url("/assets/icons/wave-cyan.png");
  --mk-llama: url("/assets/icons/llama-cyan.png");
  --mk-bird: url("/assets/icons/bird-cyan.png");
  --mk-figure: url("/assets/icons/figure-cyan.png");
  --mk-sun: url("/assets/icons/sun-cyan.png");
  --tk-spiral: url("/assets/icons/tile-spiral-cyan.png");
  --tk-wave: url("/assets/icons/tile-wave-cyan.png");
  --tk-llama: url("/assets/icons/tile-llama-cyan.png");
  --tk-bird: url("/assets/icons/tile-bird-cyan.png");
  --tk-figure: url("/assets/icons/tile-figure-cyan.png");
  --tk-sun: url("/assets/icons/tile-sun-cyan.png");
}

/* Scatter -------------------------------------------------------
   One column down each side, a different mark in each. Widths are generous --
   these are meant to be seen -- and the negative offsets run each column half
   off the edge so it reads as pattern rather than as decoration placed in a
   margin. The figure is the one narrow mark (393x745), so it takes a smaller
   width than the rest.

   Four-value background-position syntax (edge, offset, edge, offset): the
   three-value form is invalid and would drop the whole declaration. */

.scatter-a::before {
  background-image: var(--tk-spiral), var(--tk-sun);
  background-position: left -150px top 0, right -140px top 40px;
  background-size: 420px auto, 400px auto;
}

.scatter-b::before {
  background-image: var(--tk-wave), var(--tk-bird);
  background-position: left -170px top 30px, right -180px top 0;
  background-size: 440px auto, 460px auto;
}

.scatter-c::before {
  background-image: var(--tk-llama), var(--tk-figure);
  background-position: left -150px top 0, right -90px top 50px;
  background-size: 400px auto, 280px auto;
}

.scatter-d::before {
  background-image: var(--tk-spiral), var(--tk-sun);
  background-position: left -160px top 60px, right -150px top 0;
  background-size: 400px auto, 430px auto;
}

.scatter-e::before {
  background-image: var(--tk-figure), var(--tk-bird);
  background-position: left -80px top 0, right -190px top 40px;
  background-size: 290px auto, 460px auto;
}

.scatter-f::before {
  background-image: var(--tk-llama), var(--tk-wave);
  background-position: left -140px top 40px, right -180px top 0;
  background-size: 380px auto, 450px auto;
}

/* Continuity ----------------------------------------------------
   Two layers, both off by default. Each pair's height is the rendered height
   at that width -- width x (source height / source width) -- and the offset is
   half of it, so the two halves meet exactly on the boundary. The x offsets
   sit between 20% and 72%, clear of the columns at the edges. */
.section-mark::after {
  /* --split-scale lets the whole pair system shrink in one place. It is 1 here
     and reduced on phones, where the full-size marks are wider than the column
     of text they sit behind. Every width and offset below goes through it, so a
     pair's two halves stay aligned at any scale. */
  --split-scale: 1;
  background-image: var(--split-up-img, none), var(--split-down-img, none);
  background-position:
    left var(--split-up-x, 0) top calc(var(--split-up-h, 0px) * var(--split-scale) / -2),
    left var(--split-down-x, 0) bottom calc(var(--split-down-h, 0px) * var(--split-scale) / -2);
  background-size:
    calc(var(--split-up-w, 0px) * var(--split-scale)) auto,
    calc(var(--split-down-w, 0px) * var(--split-scale)) auto;
}

.split-down-sun  { --split-down-img: var(--mk-sun);  --split-down-w: 360px; --split-down-h: 322px; --split-down-x: 22%; }
.split-up-sun    { --split-up-img:   var(--mk-sun);  --split-up-w:   360px; --split-up-h:   322px; --split-up-x:   22%; }

.split-down-llama { --split-down-img: var(--mk-llama); --split-down-w: 320px; --split-down-h: 319px; --split-down-x: 64%; }
.split-up-llama   { --split-up-img:   var(--mk-llama); --split-up-w:   320px; --split-up-h:   319px; --split-up-x:   64%; }

.split-down-wave { --split-down-img: var(--mk-wave); --split-down-w: 440px; --split-down-h: 196px; --split-down-x: 38%; }
.split-up-wave   { --split-up-img:   var(--mk-wave); --split-up-w:   440px; --split-up-h:   196px; --split-up-x:   38%; }

.split-down-bird { --split-down-img: var(--mk-bird); --split-down-w: 420px; --split-down-h: 246px; --split-down-x: 54%; }
.split-up-bird   { --split-up-img:   var(--mk-bird); --split-up-w:   420px; --split-up-h:   246px; --split-up-x:   54%; }

.split-down-spiral { --split-down-img: var(--mk-spiral); --split-down-w: 340px; --split-down-h: 367px; --split-down-x: 30%; }
.split-up-spiral   { --split-up-img:   var(--mk-spiral); --split-up-w:   340px; --split-up-h:   367px; --split-up-x:   30%; }

.split-down-figure { --split-down-img: var(--mk-figure); --split-down-w: 240px; --split-down-h: 455px; --split-down-x: 70%; }
.split-up-figure   { --split-up-img:   var(--mk-figure); --split-up-w:   240px; --split-up-h:   455px; --split-up-x:   70%; }

/* The footer is not a .section, so it takes .section-mark.on-dark for the
   colours and the same two-column treatment. */
.footer.dark-background::before {
  background-image: var(--tk-spiral), var(--tk-wave);
  background-position: left -170px top 0, right -180px top 40px;
  background-size: 400px auto, 440px auto;
}

/* Phones: one column rather than two -- at 375px two columns meet in the middle
   of the text.

   The split halves are kept. They were switched off here, which meant that on
   the viewport most of this site's traffic arrives at, the rule docs/style.md
   calls the one that holds the system together -- a mark halved by a seam and
   continuing into the next band -- did not run at all, and the cultural motif
   system came down to a single faint column per section. The objection it was
   turned off for was real at full size: a 440px wave behind a 390px screen is
   wider than the text column and the eye cannot see where it continues. Scaling
   the pair down answers that without losing the seam, so --split-scale drops
   rather than display going to none. The columns move to the right edge, and the
   pairs sit between 22% and 70% from the left, so the two layers stay clear of
   each other. */
@media (max-width: 767.98px) {
  .section-mark::after {
    --split-scale: 0.52;
  }

  .section-mark::before {
    background-image: var(--tk-spiral);
    background-position: right -120px top 0;
    background-size: 280px auto;
    background-repeat: no-repeat space;
  }

  .scatter-b::before { background-image: var(--tk-bird); background-size: 300px auto; }
  .scatter-c::before { background-image: var(--tk-llama); background-size: 260px auto; }
  .scatter-d::before { background-image: var(--tk-sun); background-size: 280px auto; }
  .scatter-e::before { background-image: var(--tk-figure); background-size: 190px auto; }
  .scatter-f::before { background-image: var(--tk-wave); background-size: 300px auto; }

  .footer.dark-background::before {
    background-image: var(--tk-spiral);
    background-size: 260px auto;
  }

}

/*--------------------------------------------------------------
# Why Visit: the brand marks in the feature circles
# These were Bootstrap glyphs, which the base sheet colours with `color`.
# They are now the designer's PNGs, so the circle's hover state -- which fills
# with cyan and expects the glyph to turn white -- would otherwise leave a cyan
# mark on a cyan ground. brightness(0) invert(1) repaints any image white, the
# same trick the footer wordmark uses.
--------------------------------------------------------------*/
.why-us .feature-icon img {
  width: 42px;
  height: 42px;
  object-fit: contain;
  transition: filter 0.3s ease;
}

.why-us .feature-card:hover .feature-icon img {
  filter: brightness(0) invert(1);
}

@media (prefers-reduced-motion: reduce) {
  .why-us .feature-icon img {
    transition: none;
  }
}

/*--------------------------------------------------------------
# Photo credits
# The attribution CC BY and CC BY-SA require, folded into one control instead
# of a grey line under every photograph.
#
# It opens SIDEWAYS. The names unroll to the right of the pill, so nothing
# below moves -- a credit should not push the grid it is crediting down the
# page. grid-template-columns 0fr -> 1fr is what makes that animate to a
# content-sized width without measuring anything in JavaScript.
--------------------------------------------------------------*/
.photo-credits {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
  font-size: 13px;
  color: color-mix(in srgb, var(--default-color) 55%, white);
}

.photo-credits-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  padding: 6px 14px 6px 12px;
  border: 1px solid color-mix(in srgb, var(--default-color) 12%, white);
  border-radius: 99px;
  background: none;
  color: inherit;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}

.photo-credits-toggle:hover,
.photo-credits.is-open .photo-credits-toggle {
  border-color: var(--accent-color);
  color: var(--accent-color);
}

.photo-credits-caret {
  width: 0;
  height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.photo-credits.is-open .photo-credits-caret {
  transform: rotate(90deg);
}

.photo-credits-count {
  opacity: 0.7;
  font-weight: 400;
}

/* The sliding panel. Closed is a zero-width track; open is the content's own
   width. The inner element does the clipping, because a grid track cannot. */
.photo-credits-panel {
  display: grid;
  grid-template-columns: 1fr;
  min-width: 0;
}

.photo-credits-panel > ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 24px;
  min-width: 0;
}

/* Closed by default. index.html carries a <noscript> rule that reopens it, so
   a reader without JavaScript sees the names rather than a dead button. */
.photo-credits .photo-credits-panel {
  grid-template-columns: 0fr;
  opacity: 0;
  transition:
    grid-template-columns 0.45s cubic-bezier(0.22, 0.61, 0.36, 1),
    opacity 0.3s ease 0.05s;
}

.photo-credits .photo-credits-panel > ul {
  overflow: hidden;
  flex-wrap: nowrap;
  white-space: nowrap;
}

/* Grouping by photographer keeps this short in practice, but a place with
   several different authors could still outrun the row. Scroll rather than
   clip: a name cut in half is not attribution. */
.photo-credits.is-open .photo-credits-panel > ul {
  overflow-x: auto;
  scrollbar-width: thin;
}

.photo-credits.is-open .photo-credits-panel {
  grid-template-columns: 1fr;
  opacity: 1;
}

.photo-credits li {
  line-height: 1.5;
}

/* "Photo by" — the word that turns a row of names into a sentence. */
.photo-credits-by {
  opacity: 0.65;
}

/* The photographer: a text link, to the file's own page. */
.photo-credits-author {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--default-color) 30%, white);
}

.photo-credits-author:hover {
  color: var(--accent-color);
  text-decoration-color: currentColor;
}

/* The author's other photographs, each a link to its own file page. Grouping
   by photographer must not cost the other six their source: a reader who wants
   photograph four should be able to reach photograph four. */
.photo-credits-more {
  display: inline-flex;
  gap: 3px;
  margin-left: 5px;
}

.photo-credits-more a {
  display: inline-grid;
  place-items: center;
  /* The "+3" chip that opens the rest of the credits. At 10.5px and 60% ink
     it was both under the size floor and under 4.5:1; the box grows with the
     type so the chip keeps its shape. */
  min-width: 20px;
  height: 20px;
  padding: 0 4px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--default-color) 7%, white);
  color: var(--muted-color);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  transition: background-color 0.18s ease, color 0.18s ease;
}

.photo-credits-more a:hover {
  background: var(--accent-color);
  color: #fff;
}

/* The licence: a chip, not a text link. Both go somewhere, and they used to
   look identical -- two underlined words side by side read as one phrase
   chopped up rather than as two destinations. The chip says "a different kind
   of thing, also clickable" without needing to be explained. */
/* Credits are fine print, but fine print is still meant to be read: 11.5px
   sat under the floor. 13px keeps them the smallest text in the list while
   staying legible. */
.photo-credits-licence {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 8px;
  border: 1px solid color-mix(in srgb, var(--default-color) 15%, white);
  border-radius: 99px;
  color: color-mix(in srgb, var(--default-color) 60%, white);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 0.18s ease, color 0.18s ease;
}

.photo-credits-licence:hover {
  border-color: var(--accent-color);
  color: var(--accent-color);
}

/* The "changes were made" note a CC BY licence asks for. Plain muted text
   rather than a second chip: it is a statement about the photograph, not a
   third destination, and two chips side by side read as a pair of links. */
.photo-credits-modified {
  color: color-mix(in srgb, var(--default-color) 55%, white);
  font-size: 13px;
  white-space: nowrap;
}

/* A phone has no room to unroll sideways: eight credits on one line would run
   off the screen. Below 768px the panel opens downward instead, which is the
   same two properties animating a row rather than a column. */
@media (max-width: 767.98px) {
  .photo-credits {
    display: block;
  }

  .photo-credits-panel {
    grid-template-rows: 1fr;
    grid-template-columns: none;
  }

  .photo-credits .photo-credits-panel {
    grid-template-rows: 0fr;
    grid-template-columns: none;
    transition:
      grid-template-rows 0.4s cubic-bezier(0.22, 0.61, 0.36, 1),
      opacity 0.3s ease 0.05s;
  }

  .photo-credits.is-open .photo-credits-panel {
    grid-template-rows: 1fr;
    grid-template-columns: none;
  }

  .photo-credits .photo-credits-panel > ul {
    flex-wrap: wrap;
    white-space: normal;
    padding-top: 10px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .photo-credits-caret,
  .photo-credits .photo-credits-panel {
    transition: none;
  }
}

/*--------------------------------------------------------------
# Gallery, grouped by place
# One heading per place with its photographs beneath it. The heading is the
# only thing naming the place now -- the per-tile captions repeating it under
# forty tiles is what made the flat grid read as a dump -- so it carries a
# rule above it to separate one group from the next.
--------------------------------------------------------------*/
.gallery-group + .gallery-group {
  margin-top: 44px;
  padding-top: 40px;
  border-top: 1px solid color-mix(in srgb, var(--default-color) 10%, white);
}

.gallery-group-title {
  margin: 0 0 20px;
  font-size: clamp(20px, 2vw, 26px);
  font-weight: 700;
  color: var(--heading-color);
  letter-spacing: -0.01em;
}

.gallery-group-title a {
  color: inherit;
}

.gallery-group-title a:hover {
  color: var(--accent-color);
}

/*--------------------------------------------------------------
# Where to Stay (/hotels)
# Builds on .travel-tours .tour-card, which already owns the shell, the 250px
# image crop and the meta row. Only the accommodation-specific pieces live
# here: the group headings, the location line, and the area-photo credit.
# Palette is the three brand accents only -- cyan leads, gold marks the star
# class, red opens each group heading.
--------------------------------------------------------------*/

.stay-group + .stay-group {
  padding-top: 1rem;
}

.stay-group-title {
  font-size: 1.5rem;
  margin-bottom: 0.5rem;
  border-left: 4px solid var(--tertiary-accent);
  padding-left: 0.85rem;
}

.stay-group-intro {
  color: color-mix(in srgb, var(--default-color), transparent 30%);
  margin-bottom: 1.75rem;
  line-height: 1.6;
}

/* .travel-tours .tour-card .tour-content p carries flex:1 so the description
   absorbs the spare height and every card in a row lines up. The location
   line is a label, not body copy, so it has to opt out of that. */
.travel-tours .tour-card .tour-content p.stay-location {
  flex: 0 0 auto;
  margin-bottom: 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
  /* Ink, not the raw accent: this is 14px text on a white card, where
     #00BCD4 measures 2.3:1. */
  color: var(--cian-ink);
}

.travel-tours .tour-card .tour-content p.stay-location i {
  margin-right: 0.4rem;
}

/* Two meta chips, left-aligned rather than pushed to the edges: with only a
   star class and a type, space-between reads as two unrelated fragments. */
.travel-tours .stay-card .tour-content .tour-details {
  justify-content: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
}

.travel-tours .stay-card .tour-content .tour-details span i.bi-star-fill {
  color: var(--secondary-accent);
}

/* The photograph shows the neighbourhood, not the property. The credit is
   part of the image, so it cannot be scrolled away from the claim it
   qualifies. */
.stay-card .tour-image .stay-image-credit {
  position: absolute;
  left: 0;
  bottom: 0;
  right: 0;
  padding: 0.4rem 0.85rem;
  background-color: rgba(17, 17, 17, 0.62);
  color: #ffffff;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}

/* Partner strip. A dark band, so the wordmarks sit on one field instead of
   floating on the cream page, and so it reads as a distinct utility row rather
   than as another card. Cyan label, cream wordmarks: the three brand accents
   only, no partner brand colours. */
.stay-partners {
  background-color: var(--default-color);
  border-radius: 12px;
  padding: 1.25rem 1.5rem;
  margin-bottom: 3rem;
  /* A 4px cyan stripe ran across the top and straight off both 12px corners.
     The panel is the only dark ground on the page, so it already reads as its
     own band; the cyan moved to the label inside it. */
}

.stay-partners-inner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
}

.stay-partners-label {
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  white-space: nowrap;
}

/* The wordmarks wrap rather than scroll: a horizontal scroller hides partners
   below the fold of the row, and there are only five of them. */
.stay-partners-list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.stay-partners-list a {
  color: #ffffff;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  opacity: 0.85;
  transition: opacity 0.2s ease, color 0.2s ease;
}

.stay-partners-list a:hover,
.stay-partners-list a:focus-visible {
  opacity: 1;
  color: var(--accent-color);
}

.stay-partners-note {
  margin: 1rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 0.8125rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.62);
}

/* Primary button and affiliate link stack rather than sit side by side: at
   three columns the row is ~300px wide and 'Compare stays in Banos del Inca'
   will not share it with a button. */
.stay-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
}

/* Gold, not cyan: the monetised link should read as secondary to the cyan
   View Hotel button above it, and gold is the palette's second accent. */
.travel-tours .stay-card .stay-affiliate {
  font-size: 0.8125rem;
  font-weight: 600;
  /* 13px on a white card; raw gold measures 3.1:1. */
  color: var(--oro-ink);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--secondary-accent), transparent 65%);
  padding-bottom: 1px;
}

.travel-tours .stay-card .stay-affiliate:hover {
  color: var(--btn-hover-color);
  border-bottom-color: var(--btn-hover-color);
}

.travel-tours .stay-card .stay-affiliate i {
  font-size: 0.6875rem;
  margin-left: 0.3rem;
}

@media (max-width: 767.98px) {
  .stay-partners {
    padding: 1.1rem 1.15rem;
    margin-bottom: 2.25rem;
  }

  .stay-partners-list {
    gap: 0.4rem 1.15rem;
  }

  .stay-partners-list a {
    font-size: 0.9375rem;
  }

  .stay-group-title {
    font-size: 1.25rem;
  }

  .stay-group-intro {
    margin-bottom: 1.25rem;
  }
}


/*--------------------------------------------------------------
# Landmark name glosses
# The Spanish name is the heading; the English gloss sits under it as quiet
# italic type. It has to read as a translation, not as a second title, so it
# is deliberately smaller and lighter than the description below it.
--------------------------------------------------------------*/

.landmark-name-en {
  margin: -0.4rem 0 0.75rem;
  font-size: 0.8125rem;
  font-style: italic;
  font-weight: 500;
  line-height: 1.3;
  color: color-mix(in srgb, var(--default-color), transparent 45%);
}

/* .travel-tours .tour-card .tour-content p carries flex:1 so the description
   absorbs the spare height; the gloss is a label and has to opt out, exactly
   as .stay-location does on the Where to Stay cards. */
.travel-tours .tour-card .tour-content p.landmark-name-en,
.travel-destinations .tour-card .tour-content p.landmark-name-en {
  flex: 0 0 auto;
}

/* On the detail hero the gloss sits on the photo, so it takes a light colour
   rather than the muted body one, which would disappear against the image. */
.hero-name-en {
  margin: -0.35rem 0 0.9rem;
  font-size: 1rem;
  font-style: italic;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.78);
}

@media (max-width: 767.98px) {
  .hero-name-en {
    font-size: 0.875rem;
  }
}

/*--------------------------------------------------------------
# Language switcher (EN / ES)
--------------------------------------------------------------
   Lives as the last <li> of #navmenu so the Bootstrap mobile-nav toggle
   picks it up with the rest of the links. Text only, no flags: flags mark
   countries, not languages, and Spanish here is neutral Latin American,
   not tied to one. Inherits --nav-color / --nav-hover-color so it tracks
   the header's scrolled and mobile states without extra rules. */
.navmenu .nav-lang .nav-lang-group {
  gap: 2px;
}

.navmenu .nav-lang .nav-lang-current,
.navmenu .nav-lang .nav-lang-link {
  font-family: var(--default-font);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  padding: 6px 6px;
  text-decoration: none;
  transition: 0.3s;
}

/* The active language is not a link: there is nowhere for it to go, and an
   anchor pointing at the current page is noise for keyboard and screen
   reader users alike. */
.navmenu .nav-lang .nav-lang-current {
  color: var(--nav-hover-color);
}

.navmenu .nav-lang .nav-lang-link {
  color: var(--nav-color);
  opacity: 0.7;
}

.navmenu .nav-lang .nav-lang-link:hover,
.navmenu .nav-lang .nav-lang-link:focus-visible {
  color: var(--nav-hover-color);
  opacity: 1;
}

.navmenu .nav-lang .nav-lang-sep {
  color: var(--nav-color);
  opacity: 0.35;
  font-size: 12px;
  line-height: 1;
}

@media (min-width: 1200px) {
  /* Set off from the nav links, which sit on 15px horizontal padding. */
  .navmenu .nav-lang {
    margin-left: 10px;
    padding-left: 14px;
    border-left: 1px solid color-mix(in srgb, var(--nav-color) 25%, transparent);
  }
}

/*--------------------------------------------------------------
# Header pill: make the desktop nav fit its own bar
--------------------------------------------------------------
   The nav overflowed the black pill and spilled onto the hero behind it. It
   is not purely a translation problem: at 1200-1399px Bootstrap caps
   .container-xl at 1140px, which after 30px of pill padding either side and
   the 225px logo leaves 855px for a nav that needs 984px in English. English
   was already ~43px over before the language switcher existed; adding the
   switcher and the longer Spanish labels (1087px, ~100px wider than English)
   only made it visible.

   Measured at 1200/1250/1340/1399/1400/1440/1600/1920 in both languages, so
   the numbers below are fitted to the widest case (Spanish) rather than
   guessed. Three tiers:

   1. All desktop widths: trim the link padding 15px -> 10px a side and pull
      the switcher's divider in. That alone buys ~80px, which is what the
      >=1400px band needs, where .container-xl opens to 1320px.
   2. 1200-1399px: let the pill use the viewport instead of the 1140px cap.
      It is a floating rounded bar over a photograph, not a text column, so
      it has no reason to inherit a measure meant for paragraphs. Content
      below the header keeps the 1140px cap.
   3. 1200-1319px: step the nav type down to 14px. Below ~1320px there is no
      arrangement of a 225px logo, seven labels and a switcher that fits at
      16px, in either language.

   At 1199px and below the whole nav becomes the mobile drawer and none of
   this applies. */
@media (min-width: 1200px) {
  /* `.navmenu li a` and not `.navmenu a`: the font-size rule near the top of
     this file uses the two-class form, so a one-class override would lose on
     specificity regardless of order. */
  .navmenu li a,
  .navmenu li a:focus {
    padding-left: 9px;
    padding-right: 9px;
  }

  .navmenu .nav-lang {
    margin-left: 4px;
    padding-left: 10px;
  }
}

@media (min-width: 1200px) and (max-width: 1399.98px) {
  .header .header-container {
    max-width: none;
    width: calc(100% - 32px);
    margin-inline: auto;
  }
}

@media (min-width: 1200px) and (max-width: 1319.98px) {
  .navmenu li a,
  .navmenu li a:focus {
    font-size: 13px;
    padding-left: 6px;
    padding-right: 6px;
  }

  .header .logo { flex-basis: 138px; width: 138px; }

  .header .logo img.header-logo {
    height: 74px;
  }
}

/* In the mobile drawer the nav is a vertical stack of full-width rows, so the
   switcher reads as one more row rather than a floating pair of codes. */
@media (max-width: 1199.98px) {
  .navmenu .nav-lang {
    margin-top: 6px;
    padding-top: 12px;
    border-top: 1px solid color-mix(in srgb, var(--nav-dropdown-color, #000) 15%, transparent);
  }

  .navmenu .nav-lang .nav-lang-current,
  .navmenu .nav-lang .nav-lang-link {
    font-size: 15px;
    padding: 10px 8px;
  }
}

/*--------------------------------------------------------------
# Full-width banner between sections
--------------------------------------------------------------
   A break in the page, not a card: no container, no border-radius, no
   shadow.

   The image is NOT cropped. It carries its own headline and call to action,
   and a fixed-height container with object-fit:cover ate the top of the
   word "Travel" — cropping is only safe on a photograph, never on artwork
   with type baked into it. So the strip takes whatever height the image
   needs at the current width and the whole composition survives.

   The trade-off is on narrow screens: a 2.63:1 image at 390px is about
   148px tall, so the headline gets small. The fix for that is a second,
   squarer export for mobile, not a crop of this one. */
/* Promotional banners: a photograph with the headline, the button and the
   wordmark laid over it as real text and real elements. See PromoBanner.jsx
   for why none of that is baked into the JPEG.

   Each plate is 2.6:1 and leans to one side: the subject on one half, a
   coloured sweep in the opposite bottom corner for the wordmark, and open
   background where the copy goes. `.is-left` puts the copy on the left with
   the sweep bottom right; `.is-right` mirrors both. The accent colour of the
   sweep belongs to the artwork, so nothing here needs to know it. */
.promo-banner {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  /* The plate's own ratio, not an arbitrary band height. The artwork composes
     copy, sweep and wordmark into these proportions; a shorter band squeezes
     all three into each other, which is exactly what happened when this was a
     fixed 30vw. Clamped so it neither disappears on a phone nor swallows a
     wide monitor. */
  /* --band is the height everything else is measured against, and it is
     capped: at the plate's own ratio a 1920px window gave a 731px band, 73%
     of the screen, which is far too much for a strip between two sections.
     Past ~1470px the band stops growing and the photograph is cropped top and
     bottom instead. Because every size below is a fraction of --band rather
     than of the viewport, the composition stays in proportion when that cap
     bites — which is what vw alone could not do. */
  --band: min(calc(100vw / 2.6282), 560px);
  height: var(--band);
  min-height: 300px;
  /* The template styles every <section> with 60px of vertical padding. This
     band is a full-bleed image, not a content section: that padding was
     showing as an empty strip above the copy and below the wordmark. */
  padding: 0;
  overflow: hidden;
  background: #6d7a56;
}

/* <picture> is an inline element, and an inline box generates a line box even
   when the image inside it is absolutely positioned and takes no space. On the
   stacked phone layout that line box was adding 60px of empty strip above the
   copy, and the wordmark's own line box another 61px below it. */
.promo-banner picture,
.promo-banner-logo {
  display: block;
}

.promo-banner-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Anchored to the side the sweep is on, so the wordmark always lands on it:
     a centred crop slides the sweep off screen at some widths. */
  object-position: 100% 50%;
}

.promo-banner.is-right .promo-banner-photo {
  object-position: 0% 50%;
}

.promo-banner-inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  padding-block: 40px;
}

.promo-banner.is-right .promo-banner-inner {
  /* Static, so the copy inside can be placed against the PLATE rather than
     against this box: the band's height comes from aspect-ratio, which is not
     a definite size, so height:100% and align-self:stretch both collapse to
     the content height here (428px inside a 548px band) and the copy sank
     into the wordmark. */
  position: static;
}

.promo-banner.is-right .promo-banner-copy {
  position: absolute;
  z-index: 1;
  /* Measured off the artwork: the block starts 7% down and runs to the right
     edge, and the sweep owns everything below it. */
  top: 2.1%;
  right: 5%;
  width: 35%;
}


/* Both plates share the heading size (see the shared rule); this one only
   pulls its two lines tighter, because in the artwork they nearly touch. */
.promo-banner.is-right .promo-banner-heading {
  line-height: 0.79;
}

/* Centred across the plate and low, as in the artwork: it belongs to the
   whole banner rather than to the column of text. */
.promo-banner.is-right .promo-banner-cta {
  left: 41.6%;
  transform: translateX(-50%);
  bottom: 3.5%;
  /* The artwork's pill is 23% of the plate wide and 22% tall; scale it with
     the plate rather than leaving it at a fixed UI size, or it shrinks into
     a tag on a large screen. */
}

.promo-banner.is-right .promo-banner-cta:hover {
  transform: translateX(-50%) translateY(-2px);
}

.promo-banner-copy {
  /* Narrower than the half it sits in, on purpose: at 54% the longest heading
     ran up against the subject in the photograph. */
  max-width: 41%;
  /* The plates are bright and the copy sits over open background. A shadow
     rather than a scrim: a wash over the whole photograph would flatten it. */
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.55), 0 1px 3px rgba(0, 0, 0, 0.7);
}

.promo-banner.is-right .promo-banner-copy {
  /* Left-aligned inside the block, not right: in the artwork "Live the" and
     "CARNAVAL" share a left edge and only the second heading line is pushed
     across. The block as a whole sits on the right of the plate. */
  text-align: left;
}

/* Measured off resources/banner/carnaval-REFERENCIA-con-texto.jpg, as
   percentages of the plate:
     Live the  h 10.1  centre x 70.3
     CARNAVAL  h 12.3  centre x 76.4
     SPIRIT    h 15.5 (13 of it glyph, the rest its drop shadow)  centre 79.0
     subtitle  h  4.4  centre x 77.2
   and the gaps between them are 1.8, 0.9 and 1.6 — the four lines are one
   tight block, not four stacked paragraphs.
   SPIRIT is a little larger than CARNAVAL and sits centred beneath it. */
.promo-banner.is-right .promo-banner-heading-accent {
  font-size: 1.13em;
  text-align: center;
  /* The artwork's second line sits a touch right of dead centre. */
  transform: translateX(1.5%);
}

/* Spanish runs a third longer than English on this plate: "ESPIRITU DEL
   CARNAVAL" against "CARNAVAL SPIRIT". At the English size the lead wrapped
   onto a second line, which pushed the whole block down until the subtitle sat
   across the wordmark -- the overlap the client reported. The block gets more
   of the plate and the type is set smaller, both only where the document is in
   Spanish (LocaleContext sets html lang), so the English plate still matches
   the artwork it was measured from. */
:lang(es) .promo-banner.is-right .promo-banner-copy {
  width: 44%;
  top: 1.2%;
}

:lang(es) .promo-banner.is-right .promo-banner-heading {
  font-size: calc(var(--band) * 0.132);
}

:lang(es) .promo-banner.is-right .promo-banner-eyebrow {
  font-size: calc(var(--band) * 0.108);
}

/* Held on one line each: a wrap here is what started the pile-up, and at this
   size both lines clear the block's width with room to spare. */
:lang(es) .promo-banner.is-right .promo-banner-heading span {
  white-space: nowrap;
}

/* The words tilt very slightly, as in the artwork. Small enough to read as
   hand-set rather than as a mistake, and pivoting on the edge the block is
   anchored to. Only the type tilts: the button stays level, because a rotated
   pill reads as a rendering fault where rotated type reads as styling. */
.promo-banner-text {
  transform: rotate(-2.2deg);
  transform-origin: left center;
}

.promo-banner.is-right .promo-banner-text {
  transform-origin: right center;
}

.promo-banner-eyebrow {
  /* Pushed down toward CARNAVAL, with the same amount taken off the bottom
     so the line below does not move with it. */
  margin: calc(var(--band) * 0.011) 0 calc(var(--band) * 0.001);
  line-height: 1;
  font-family: var(--heading-font);
  /* Armonia Forte ships a real italic (see the @font-face pair in main.css),
     so this is a drawn italic, not a browser-skewed fake. */
  font-style: italic;
  font-size: calc(var(--band) * 0.135);
  font-weight: 700;
  color: #fff;
}

.promo-banner-heading {
  margin: 0;
  font-family: var(--heading-font);
  font-style: italic;
  font-size: calc(var(--band) * 0.168);
  font-weight: 700;
  line-height: 0.86;
  letter-spacing: -0.015em;
  color: #fff;
  text-transform: uppercase;
}

/* font: inherit because main.css styles every <span> as 17px Inter body text,
   which silently shrinks any span inside a heading. */
.promo-banner-heading span {
  display: block;
  font: inherit;
  letter-spacing: inherit;
}

.promo-banner-heading-accent {
  color: var(--secondary-accent);
}

/* The accent belongs to the plate: gold reads on the valley's greens, and the
   carnival plate takes the yellow of its own artwork. Red was tried and
   dropped — the costume is already red and pink, and the word sank into it. */
.promo-banner.accent-red {
  --promo-accent: #FFD400;
}

.promo-banner.accent-red .promo-banner-heading-accent {
  color: var(--promo-accent);
}

/* Only the accent word is coloured; the eyebrow stays white with the lead. */
.promo-banner.accent-red .promo-banner-eyebrow {
  color: #fff;
}

/* The first line stays white on both plates. Stated explicitly because the
   rule above used to match every span in the heading and turned CARNAVAL red
   along with SPIRIT. */
.promo-banner-heading-lead {
  color: #fff;
}

.promo-banner-subtitle {
  margin: calc(var(--band) * 0.016) 0 0;
  line-height: 1;
  font-family: var(--heading-font);
  font-style: italic;
  font-size: calc(var(--band) * 0.047);
  font-weight: 700;
  color: #fff;
}

.promo-banner-cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  /* Placed against the plate, at the position measured off the artwork. */
  position: absolute;
  left: 5%;
  bottom: 13%;
  z-index: 2;
  padding: 12px 14px 12px 26px;
  border-radius: 99px;
  background: var(--btn-color);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-shadow: none;
  /* The pill is positioned against the wordmark, so it must not reflow to two
     lines when that gap tightens. */
  white-space: nowrap;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.28);
  transition: background-color 0.2s ease, transform 0.2s ease;
}

.promo-banner-cta i {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--accent-color);
  color: var(--cian-deepest);
  font-size: 15px;
  transition: transform 0.2s ease;
}

.promo-banner-cta:hover {
  background: var(--btn-hover-color);
  color: #fff;
  transform: translateY(-2px);
}

.promo-banner-cta:hover i {
  transform: translateX(3px);
}

/* Pinned to the corner the sweep occupies rather than laid out in the flex
   row: the sweep is part of the photograph, and the corner is the one point
   that stays coloured at every width. Percentages, so it tracks the sweep as
   the plate scales.
   Note this does NOT follow `align`: both plates carry their sweep bottom
   right, and it is the sweep the wordmark has to sit on, not the copy. */
/* Only in play where the button is hidden; see the phone rules. */
.promo-banner-cover {
  display: none;
}

.promo-banner-logo {
  position: absolute;
  right: 3.1%;
  bottom: 2%;
  z-index: 2;
  /* Sized by height, like the type, and big: in the artwork the wordmark
     fills the sweep rather than sitting politely inside it. */
  /* The artwork's lockup is proportionally wider than this file (about 2.14:1
     against 1.85:1), so matching its WIDTH would make ours 7 points taller and
     push it into the subtitle. Height is matched instead: y 50.0-95.5. */
  width: calc(var(--band) * 0.79);
  height: auto;
}

@media (prefers-reduced-motion: reduce) {
  .promo-banner-cta:hover,
  .promo-banner-cta:hover i {
    transform: none;
  }
}

@media (max-width: 767.98px) {
  /* Phones only. Above this the plate keeps its own ratio and the whole
     composition simply scales, which is what makes it look like the artwork
     at any window size; here the band would have to be squarer than the
     photograph and cover would zoom straight past the subject, so the copy
     stops sharing the width and the plate darkens to carry white type. */
  .promo-banner {
    display: block;
    /* Stacked copy sets the height here, not the plate's ratio. The floor is
       low so the band ends just under the wordmark instead of leaving a dead
       strip of sweep below it. */
    height: auto;
    min-height: 300px;
  }

  /* --band is a function of width, and at phone width it collapses to about
     160px, which made every size derived from it tiny. The stacked layout is
     a different composition anyway, so it gets its own sizes in rem. */
  .promo-banner-eyebrow {
    font-size: 1.15rem;
    margin: 0 0 2px;
  }

  .promo-banner-heading {
    font-size: 2.5rem;
  }

  .promo-banner-subtitle {
    font-size: 0.95rem;
    margin-top: 10px;
  }

  .promo-banner::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to right, rgba(12, 22, 12, 0.72), rgba(12, 22, 12, 0.35));
  }

  .promo-banner.is-right::after {
    background: linear-gradient(to left, rgba(12, 22, 12, 0.72), rgba(12, 22, 12, 0.35));
  }

  .promo-banner-inner {
    z-index: 2;
    flex-direction: column;
    align-items: flex-start;
    padding-block: 26px 0;
  }

  .promo-banner.is-right .promo-banner-inner {
    align-items: flex-end;
  }

  .promo-banner-copy {
    max-width: 100%;
  }

  /* The mirrored plate places its copy absolutely against the band on
     desktop; at phone width it goes back into the flow with everything else,
     or it keeps a 35% column and the heading runs off the screen. */
  .promo-banner.is-right .promo-banner-copy {
    position: static;
    width: auto;
    text-align: left;
  }

  .promo-banner.is-right .promo-banner-heading-accent {
    text-align: left;
    transform: none;
  }

  .promo-banner.is-right .promo-banner-inner {
    position: relative;
    align-items: flex-start;
    padding-top: 26px;
  }

  /* Both plates now have a portrait crop, so neither is reframed: each is
     shown whole at its own 5:4 ratio and the layout follows its artwork.
     Measured off cajamarca-banner-region@2x-referencia-contexto-mobile.jpg:
       It's Time To y  9-18   DISCOVER y 17-26   CAJAMARCA y 26-35
       subtitle     y 35-42   wordmark x 62-99, y 74-97
     The copy sits top right here, the mirror of the carnival plate. */
  .promo-banner {
    aspect-ratio: 1500 / 1200;
    height: auto;
    min-height: 0;
  }

  .promo-banner .promo-banner-photo {
    object-position: 50% 50%;
  }

  /* The portrait crops leave their own clear space for the copy, so the
     photograph no longer has to be darkened to carry it. */
  .promo-banner::after {
    content: none;
  }

  .promo-banner.is-left .promo-banner-inner {
    position: static;
    padding: 0;
  }

  /* Measured off the reference: every line shares a left edge at about 34%
     of the plate — DISCOVER starts at 34, CAJAMARCA at 33, the subtitle at
     34 — and the block runs to the right edge from there. It is left-aligned,
     not right-aligned; anchoring it right put the lines on the wrong axis.
     Anchored to the plate, not to the container inside it. */
  .promo-banner.is-left .promo-banner-copy {
    position: absolute;
    top: 7%;
    left: 33%;
    right: 3%;
    width: auto;
    max-width: none;
    text-align: left;
  }

  /* "It's Time To" sits very slightly in from that edge in the artwork. */
  .promo-banner.is-left .promo-banner-eyebrow {
    padding-left: 2%;
  }

  .promo-banner.is-left .promo-banner-heading-accent {
    text-align: left;
    transform: none;
  }

  .promo-banner.is-left .promo-banner-eyebrow {
    font-size: 4.4vw;
    margin: 0 0 0.3vw;
  }

  .promo-banner.is-left .promo-banner-heading {
    font-size: 8.2vw;
    line-height: 0.82;
  }

  .promo-banner.is-left .promo-banner-subtitle {
    /* 2.55vw is 9.9px on a 390px screen. The vw keeps the artwork's
       proportion above that, the floor holds below it. */
    font-size: max(13px, 2.55vw);
    margin-top: 1.2vw;
  }

  .promo-banner.is-left .promo-banner-logo {
    position: absolute;
    right: 1%;
    bottom: 3%;
    width: 38%;
    margin: 0;
  }

  /* Bottom left, over the open field beside the woman. */
  .promo-banner.is-left a.promo-banner-cta {
    position: absolute;
    left: 3%;
    bottom: 3.5%;
    top: auto;
    margin: 0;
    /* 10.5px was the smallest interactive label on the site. 13px is the
       floor; the padding comes in a little so the pill still clears the
       figure in the artwork at phone width. */
    padding: 7px 8px 7px 13px;
    font-size: 13px;
    gap: 6px;
  }

  .promo-banner.is-left a.promo-banner-cta i {
    width: 19px;
    height: 19px;
    font-size: 11px;
  }

  /* The carnival plate DOES have a portrait crop (see mobileWebp in the page
     content), so it is shown whole at its own 5:4 ratio rather than cropped,
     and the layout follows the artwork: the girl fills the frame, the copy
     sits bottom left and the wordmark on the sweep bottom right.
     Measured off carnaval-REFERENCIA-con-texto-mobile.jpg:
       Live the  y 70-80   CARNAVAL y 78-87   SPIRIT y 86-95
       subtitle  y 95-98   wordmark x 55-98, y 73-100  */
  .promo-banner.is-right {
    aspect-ratio: 1500 / 1200;
    height: auto;
    min-height: 0;
  }

  .promo-banner.is-right .promo-banner-photo {
    object-position: 50% 50%;
  }

  /* No scrim: the portrait plate leaves its own clear space for the copy. */
  .promo-banner.is-right::after {
    content: none;
  }

  .promo-banner.is-right .promo-banner-inner {
    position: absolute;
    /* Where the artwork puts it: the copy runs from about 70% of the height
       to the bottom edge. Lifting it to make room for the button put the
       heading across the girl's mouth, so the button moves instead. */
    inset: auto 0 2% 0;
    padding: 0 0 0 3%;
    align-items: flex-start;
    justify-content: flex-start;
  }

  .promo-banner.is-right .promo-banner-copy {
    position: static;
    width: 56%;
    text-align: left;
  }

  .promo-banner.is-right .promo-banner-eyebrow {
    font-size: 4.4vw;
    margin: 0 0 0.3vw;
  }

  .promo-banner.is-right .promo-banner-heading {
    font-size: 8.2vw;
    line-height: 0.82;
  }

  .promo-banner.is-right .promo-banner-heading-accent {
    text-align: left;
    transform: translateX(3%);
  }

  .promo-banner.is-right .promo-banner-subtitle {
    /* Floor, as on the mirrored plate: 2.55vw is 9.9px at phone width. */
    font-size: max(13px, 2.55vw);
    margin-top: 1.2vw;
  }

  /* The wordmark sits on the sweep, as in the portrait artwork. */
  .promo-banner.is-right .promo-banner-logo {
    position: absolute;
    right: 1%;
    bottom: 3%;
    width: 38%;
    margin: 0;
  }

  /* The artwork has no button on the phone crop; keeping one would cover the
     girl. The whole band is the link instead -- see PromoBanner.jsx. */
  /* Bottom left, under the copy, clear of the wordmark on the sweep.
     a.promo-banner-cta for specificity: the shared phone rule above puts
     every button back into the flow, and it comes later in the file. */
  /* Top left: the only corner the artwork leaves free once the copy is in
     its proper place at the foot of the plate. */
  .promo-banner.is-right a.promo-banner-cta {
    position: absolute;
    left: 3%;
    top: 4%;
    bottom: auto;
    margin: 0;
    /* 10.5px was the smallest interactive label on the site. 13px is the
       floor; the padding comes in a little so the pill still clears the
       figure in the artwork at phone width. */
    padding: 7px 8px 7px 13px;
    font-size: 13px;
    gap: 6px;
  }

  .promo-banner.is-right a.promo-banner-cta i {
    width: 19px;
    height: 19px;
    font-size: 11px;
  }

  /* The copy sits over the photograph here rather than beside it, so the
     scrim has to carry more of the contrast than it does on a wide screen. */
  .promo-banner::after {
    background: linear-gradient(to bottom, rgba(10, 16, 10, 0.78) 0%, rgba(10, 16, 10, 0.55) 55%, rgba(10, 16, 10, 0.32) 100%);
  }

  .promo-banner.is-right::after {
    background: linear-gradient(to bottom, rgba(10, 16, 10, 0.78) 0%, rgba(10, 16, 10, 0.55) 55%, rgba(10, 16, 10, 0.32) 100%);
  }

  /* No tilt at phone width: the block is nearly the full column, so the
     rotation pushes the long lines into the edges. */
  .promo-banner-text {
    transform: none;
  }

  .promo-banner-cta {
    transform: none;
  }

  /* Back into the flow under the copy: at this width there is no sweep to
     sit beside. */
  .promo-banner.is-right .promo-banner-cta,
  .promo-banner-cta {
    position: relative;
    inset: auto;
    transform: none;
    display: inline-flex;
    margin: 0 0 0 12px;
  }

  .promo-banner.is-right .promo-banner-inner {
    padding-top: 40px;
  }

  .promo-banner-cta:hover {
    transform: translateY(-2px);
  }

  /* Below 992px the crop keeps only a corner of the sweep, too small to seat
     the wordmark on, so it returns to the flow under the button. relative,
     not static: the photograph is absolutely positioned, and an absolute
     sibling paints above static in-flow content whatever its z-index says. */
  .promo-banner-logo {
    position: relative;
    inset: auto;
    width: 210px;
    height: auto;
    /* 12px matches the .container gutter, so it lines up with the copy. */
    margin: 14px 0 22px 12px;
  }

  .promo-banner.is-right .promo-banner-logo {
    left: auto;
    margin-left: 0;
    margin-right: 12px;
    float: right;
  }
}

/*--------------------------------------------------------------
# Particulars (homepage reference section)
--------------------------------------------------------------
   A full-width section, not a card: title, then the map running edge to edge,
   then the four plates, then the statement beside the data. Everything
   collapses toward one column below 991px, where side-by-side blocks would be
   too narrow to read. */
.particulars {
  /* Off-white against the white intro above it and the white Why Visit band
     below, so the section reads as its own block rather than running into
     either. A hairline closes it off where the next band is the same white. */
  border-top: 1px solid color-mix(in srgb, var(--default-color) 8%, white);
  border-bottom: 1px solid color-mix(in srgb, var(--default-color) 8%, white);
}

/* The plates and the data sit on the off-white ground, so their own fill has
   to lift off it rather than match it. */
.particulars-plate {
  background: var(--surface-color);
}

.particulars .section-title {
  padding-bottom: 36px;
}

/* No pill above this heading any more -- "City Facts" over a heading reading
   "Particulars" was the same thing said twice -- so the 18px that opened the
   gap under the pill goes with it and the heading sits at the top of the
   block. .no-eyebrow says so in the markup, for any other section that drops
   its pill later. */
.particulars .section-title h2,
.particulars .section-title h3 {
  margin: 0;
  font-size: clamp(28px, 2.6vw, 36px);
}

.particulars .section-title p {
  margin: 12px auto 0;
  max-width: 62ch;
  color: color-mix(in srgb, var(--default-color) 70%, white);
}

.particulars-map-heading {
  margin: 0 0 22px;
  text-align: center;
  font-size: clamp(24px, 2.4vw, 34px);
  font-weight: 700;
  color: var(--heading-color);
  letter-spacing: -0.01em;
}

/* The map is the one element allowed out of the container. */
.particulars-map-stage {
  position: relative;
  width: 100%;
  height: clamp(340px, 46vh, 520px);
  background: var(--cian-light);
}

.particulars-map-stage iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.particulars-map-caption {
  margin: 14px 0 0;
  text-align: center;
  font-size: 13px;
  color: color-mix(in srgb, var(--default-color) 60%, white);
}

.particulars-map-caption a {
  /* 13px link on white; the raw accent measures 2.3:1 here. */
  color: var(--cian-ink);
  font-weight: 600;
  white-space: nowrap;
}

/* Plates: locator map, coat of arms, city flag, national flag ---- */
.particulars-plates {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 18px;
  margin-top: 40px;
}

.particulars-plate {
  margin: 0;
  border-radius: 18px;
  border: 1px solid color-mix(in srgb, var(--default-color) 8%, white);
  overflow: hidden;
}

.particulars-plate-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 190px;
  padding: 22px;
}

.particulars-plate-stage img {
  display: block;
  max-height: 100%;
  max-width: 100%;
  width: auto;
  object-fit: contain;
}

/* The CC BY-SA credit the locator map's licence requires. Quiet, but present
   and linked: the licence holds only while the author is named where the work
   is shown. */
/* Was 10px, the smallest type on the site. */
.particulars-plate-credit {
  display: block;
  margin-top: 6px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.5;
  /* 50% ink measured 4.1:1; --muted-color is the grey the style guide
     prescribes and clears the bar. */
  color: var(--muted-color);
}

.particulars-plate-credit a {
  color: inherit;
  text-decoration: underline;
}

.particulars-plate-credit a:hover {
  color: var(--accent-color);
}

/* The flags carry white in them and the plate is white, so without an edge a
   flag loses its border into the card. A hairline is enough; a heavier frame
   would look like a mount. */
.particulars-plate-stage img.is-flag {
  border: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
}

/* The locator is a map, not an emblem: it fills its plate edge to edge and
   takes the pin. No padding here -- the pin is positioned as a percentage of
   this box, so the image has to be the box for the coordinates to land. */
.particulars-plate-stage.is-map {
  padding: 16px;
  background: #fff;
  transition: box-shadow 0.2s ease;
}

.particulars-plate-map {
  position: relative;
  display: block;
  height: 100%;
}

.particulars-plate-map img {
  display: block;
  height: 100%;
  width: auto;
}

.particulars-plate-stage.is-map:hover {
  box-shadow: inset 0 0 0 2px var(--accent-color);
}

/* The hint under the locator plate's label. Lighter and in sentence case, so
   it reads as an invitation rather than a second caption. */
.particulars-plate-hint {
  display: block;
  margin-top: 6px;
  /* 12px was below the 13px floor and the raw accent measured 2.3:1 on the
     white plate. Both fixed; this stays the smallest step in the caption. */
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--cian-ink);
}

.particulars-plate:hover .particulars-plate-hint {
  color: var(--oro-ink);
}

.particulars-plate figcaption {
  padding: 16px 18px;
  border-top: 1px solid rgba(17, 17, 17, 0.08);
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--heading-color);
}

/* The marker is placed from coordinates in Particulars.jsx, so it stays put
   as the image scales. The ring pulses to draw the eye without animating
   anything for a reader who has asked for less motion. */
.particulars-pin {
  position: absolute;
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  background: var(--tertiary-accent);
  box-shadow: 0 0 0 2px #fff, 0 1px 4px rgba(0, 0, 0, 0.4);
}

/* Named beside the dot. The white halo is what keeps it readable over the
   country fill and the coastline both, without a box that would cover the
   map. */
.particulars-pin-label {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--heading-color);
  text-shadow:
    0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff,
    1px 1px 0 #fff, -1px 1px 0 #fff, 1px -1px 0 #fff, -1px -1px 0 #fff;
  pointer-events: none;
}

.particulars-pin::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 2px solid var(--tertiary-accent);
  opacity: 0;
  animation: particulars-pulse 2.4s ease-out infinite;
}

@keyframes particulars-pulse {
  0% { transform: scale(0.6); opacity: 0.9; }
  70% { transform: scale(1.6); opacity: 0; }
  100% { opacity: 0; }
}

/* Statement beside the data ------------------------------------- */
.particulars-bottom {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.3fr);
  gap: 24px;
  margin-top: 40px;
  align-items: stretch;
}

.particulars-statement {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 28px;
  min-height: 420px;
  border-radius: 18px;
  overflow: hidden;
  /* The teal ground, flat. There was a white radial over the top right of it,
     a simulated light source with no light in the scene to justify it. The
     video that plays inside this card is the light. */
  background: linear-gradient(160deg, var(--cian-deep) 0%, var(--cian-deepest) 100%);
  color: #fff;
}

.particulars-statement-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The card is roughly 500 CSS px wide and the file is 1920, so the browser
     is downscaling hard. Telling it to interpolate smoothly rather than
     nearest-neighbour is what stops the descent reading as blocky on a
     non-retina screen. */
  image-rendering: auto;
  backface-visibility: hidden;
  transform: translateZ(0);
  /* The clip is cropped by the card, so any aspect ratio fits: the export does
     not have to match this box. Colour and contrast are baked into the encode
     (see the ffmpeg eq filter used to build it) rather than applied here, so
     the browser is not filtering every frame. */
}

/* Keeps the type legible whatever frame is on screen, video or not. */
/* A scrim under the buttons only. Dimming the whole clip washed it out; this
   darkens just the bottom of the card, where the buttons need the contrast. */
.particulars-statement::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 45%;
  background: linear-gradient(to top, rgba(4, 22, 26, 0.75), transparent);
  pointer-events: none;
}

.particulars-statement-body {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  /* Bottom-right corner of the clip: the descent lands left of centre, so the
     button stays clear of the city rather than covering it. */
  justify-content: flex-end;
  align-items: flex-end;
  height: 100%;
}

.particulars-statement-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  /* Held back until the descent lands; see the reveal effect in
     Particulars.jsx. Hidden with opacity rather than display so the card's
     height never changes and nothing below it jumps. */
  opacity: 0;
  transform: translateY(16px);
  filter: blur(4px);
  /* Slow, and eased so it settles rather than stops: the clip has just landed
     and the button should feel like it arrives with it. */
  transition:
    opacity 900ms cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 900ms cubic-bezier(0.22, 0.61, 0.36, 1),
    filter 900ms ease;
  pointer-events: none;
}

.particulars-statement-links.is-revealed {
  opacity: 1;
  transform: none;
  filter: none;
  pointer-events: auto;
}

/* The button used to fire an expanding cyan ring on reveal -- the notification
   pulse every dashboard puts on a badge. The fade that brings the links in is
   enough to find them; a second animation on top of it was decoration asking
   to be noticed. */

@media (prefers-reduced-motion: reduce) {
  .particulars-statement-links {
    transition: none;
    filter: none;
    transform: none;
  }
}

/* Buttons rather than arrow links: over video the underline-less link read as
   a caption. Solid cyan leads, the source sits behind glass beside it. */
.particulars-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 22px;
  border-radius: 99px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-shadow: none;
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease, color 0.2s ease;
}

.particulars-btn i {
  font-size: 14px;
  transition: transform 0.2s ease;
}

.particulars-btn:hover {
  transform: translateY(-2px);
}

.particulars-btn.is-primary {
  background: var(--accent-color);
  color: var(--cian-deepest);
}

.particulars-btn.is-primary:hover {
  background: #fff;
  color: var(--cian-deepest);
}

.particulars-btn.is-primary:hover i {
  transform: translateX(4px);
}

.particulars-btn.is-ghost {
  border: 1.5px solid rgba(255, 255, 255, 0.45);
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  backdrop-filter: blur(4px);
}

.particulars-btn.is-ghost:hover {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  /* Named beside the dot. The white halo is what keeps it readable over the
   country fill and the coastline both, without a box that would cover the
   map. */
.particulars-pin-label {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--heading-color);
  text-shadow:
    0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff,
    1px 1px 0 #fff, -1px 1px 0 #fff, 1px -1px 0 #fff, -1px -1px 0 #fff;
  pointer-events: none;
}

.particulars-pin::after { animation: none; }
  .particulars-btn:hover { transform: none; }
  .particulars-btn:hover i { transform: none; }
}

.particulars-data h4 {
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--default-color) 55%, white);
}

.particulars-data dl {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px;
}

.particulars-fact {
  padding: 12px 16px;
  border-top: 1px solid color-mix(in srgb, var(--default-color) 10%, white);
  border-left: 3px solid transparent;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}

.particulars-fact:hover {
  background: var(--cian-light);
  border-left-color: var(--accent-color);
}

.particulars-fact dt {
  /* The label of every fact in the table: 12px raw gold on white measured
     3.1:1, under the floor on both counts. 13px and the ink keep it clearly
     the smaller, quieter half of the pair without making it unreadable. */
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--oro-ink);
  margin-bottom: 3px;
}

.particulars-fact dd {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--default-color);
}

@media (max-width: 991.98px) {
  .particulars-plates {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .particulars-bottom {
    grid-template-columns: minmax(0, 1fr);
  }

  .particulars-statement {
    padding: 28px 24px;
  }
}

@media (max-width: 575.98px) {
  .particulars-plates,
  .particulars-data dl {
    grid-template-columns: minmax(0, 1fr);
  }

  .particulars-plate-stage {
    height: 160px;
  }
}

/*--------------------------------------------------------------
# Why Visit teasers
# Three questions under the reasons grid, each answered on the Trivia page.
# Set as a description list with the icon outside the term/definition pair, so
# the icon stays decoration and the text keeps its structure. Three across on
# desktop, stacked below 991px where three columns of prose go too narrow. */
.why-teasers {
  margin: 44px 0 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}

.why-teaser {
  display: flex;
  gap: 14px;
  padding: 22px 20px;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--default-color) 8%, white);
  background: var(--background-color);
}

.why-teaser > i {
  flex: 0 0 auto;
  font-size: 20px;
  line-height: 1.2;
  color: var(--secondary-accent);
}

.why-teaser dt {
  margin-bottom: 6px;
  font-size: 15px;
  font-weight: 700;
  color: var(--heading-color);
}

.why-teaser dd {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: color-mix(in srgb, var(--default-color) 78%, white);
}

/* This line sits on the red section, so it takes the contrast colour rather
   than the default ink, and the link is a pill button instead of inline text:
   a cyan link on red is both hard to read and hard to hit. */
.why-teasers-cta {
  margin: 28px 0 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
  font-size: 15px;
  color: var(--contrast-color);
}

.why-teasers-cta a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 26px;
  border-radius: 99px;
  background: var(--contrast-color);
  color: var(--tertiary-accent);
  font-weight: 700;
  white-space: nowrap;
  transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.why-teasers-cta a:hover {
  background: var(--secondary-accent);
  color: var(--contrast-color);
  transform: translateY(-2px);
}

.why-teasers-cta a i {
  transition: transform 0.2s ease;
}

.why-teasers-cta a:hover i {
  transform: translateX(4px);
}

@media (prefers-reduced-motion: reduce) {
  .why-teasers-cta a:hover i,
  .why-teasers-cta a:hover { transform: none; }
}

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

/*--------------------------------------------------------------
# Where to Stay: category jump links
# Bubbles under the opening paragraph, one per section on the page. Same pill
# shape as the filter pills on the hub pages, but these are anchors, not state:
# they move the reader down the page rather than changing what is rendered. */
.stay-jump {
  /* Sticks under the site header as the reader moves down the page. The offset
     is --sticky-offset, the same variable the Things to Do filter bar uses:
     Layout.jsx slides the header away on the way down and zeroes that
     variable, so this bar rides up into the space instead of leaving a gap
     where the navbar was. The transition is what keeps the two in step. */
  position: sticky;
  top: var(--sticky-offset);
  transition: top 0.3s ease;
  z-index: 20;
  margin: 0 -12px 44px;
  padding: 12px;
  background: color-mix(in srgb, var(--background-color) 92%, transparent);
  backdrop-filter: blur(6px);
  border-radius: 12px;
}

.stay-jump-inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  max-width: 900px;
  margin: 0 auto;
}

.stay-jump-link {
  display: inline-block;
  padding: 10px 20px;
  border-radius: 99px;
  border: 1.5px solid color-mix(in srgb, var(--default-color) 12%, white);
  background: var(--surface-color);
  color: var(--heading-color);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

.stay-jump-link:hover {
  background: var(--cian-dark);
  border-color: var(--cian-dark);
  color: var(--background-color);
}

/* .section sets overflow: clip, which in some engines stops a descendant from
   sticking. The stays section has nothing to clip, so it opts out. */
#stays {
  overflow: visible;
}

@media (max-width: 575.98px) {
  /* Too many pills to stack at phone width, so the bar scrolls sideways
     instead and keeps its place under the header. */
  .stay-jump-inner {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .stay-jump-inner::-webkit-scrollbar {
    display: none;
  }

  .stay-jump-link {
    white-space: nowrap;
  }
}

/*--------------------------------------------------------------
# The photo viewer's caption panel
# GLightbox ships its own typography -- a system sans at the browser default
# size -- so the panel beside an opened photograph read as a stray browser
# dialog rather than as part of this site. It takes the page's own type here:
# the display face for the dish name, Inter for the note, and the site's ink
# rather than near-black. See docs/style.md.
#
# Not scoped to one page: the Gallery and the landmark pages open the same
# viewer, and a caption should look the same wherever it appears.
--------------------------------------------------------------*/
.glightbox-container .gslide-description {
  position: relative;
  /* Scrolls rather than clips: with the local note under it, the longest
     entries run past the foot of the panel, and a caption that cannot be
     finished is worse than no caption. */
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface-color);
  padding: 26px 30px;
}

/* The same brand marks the sections carry, at the same weight: the panel is a
   light ground, so it takes the light-ground colours. Two of them, bleeding
   off the bottom and the top edge, which leaves the middle of the panel -- the
   part the text occupies -- clear. */
.glightbox-container .gslide-description::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.1;
  background-repeat: no-repeat;
  background-image:
    url("/assets/icons/sun-terracotta.png"),
    url("/assets/icons/spiral-cyan.png");
  background-position:
    right -70px bottom -80px,
    left -80px top -90px;
  background-size: 240px auto, 200px auto;
}

/* Everything in the panel sits above the marks. */
.glightbox-container .gslide-description > * {
  position: relative;
  z-index: 1;
}

.glightbox-container .gslide-title {
  margin-bottom: 12px;
  font-family: var(--heading-font);
  font-size: 1.35rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--heading-color);
}

.glightbox-container .gslide-desc {
  font-family: var(--default-font);
  font-size: 0.95rem;
  line-height: 1.65;
  /* Left aligned, not justified. This panel is about 380px wide, and
     justification at that measure stretches the word spaces until the lines
     reach the right edge in uneven jumps -- the text ends up looking pushed
     against the right side. The site justifies its long-form prose because
     those columns are wide enough to absorb it; this one is not. */
  text-align: left;
  color: color-mix(in srgb, var(--default-color) 78%, white);
}

.glightbox-container .gslide-desc a {
  color: var(--accent-color);
  font-weight: 600;
}

/* The local note is an aside, not a second definition, and it was reading as
   a second definition: same size, same colour, same shape as the paragraph
   above it. It is a card now -- its own gold-tinted ground, a gold rule down
   the left edge, a small label, and the note itself set smaller and in italic.
   The eye can tell at a glance that it is a different kind of sentence. */
/* 4px, like every other accent stripe on the site: the callout marker is one
   idiom in three colours, not three idioms. */
.glightbox-container .dish-trivia {
  margin-top: 20px;
  padding: 14px 16px;
  border-radius: 12px;
  border-left: 4px solid var(--secondary-accent);
  background: var(--oro-light);
}

.glightbox-container .dish-trivia-label {
  margin: 0 0 6px;
  font-family: var(--default-font);
  font-size: 10px;
  font-weight: 700;
  font-style: normal;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--secondary-accent);
}

.glightbox-container .dish-trivia p:not(.dish-trivia-label) {
  margin: 0;
  font-size: 0.88rem;
  font-style: italic;
  line-height: 1.6;
  color: color-mix(in srgb, var(--default-color) 82%, white);
}

/* The arrows and the close control sit on the photograph, so they take the
   same pill treatment the rest of the site gives a control over an image. */
.glightbox-container .gnext,
.glightbox-container .gprev,
.glightbox-container .gclose {
  background-color: rgba(10, 12, 14, 0.55);
  border-radius: 99px;
  transition: background-color 0.2s ease;
}

.glightbox-container .gnext:hover,
.glightbox-container .gprev:hover,
.glightbox-container .gclose:hover {
  background-color: var(--btn-color);
}

/* Below 900px GLightbox drops the side panel under the photograph, where the
   padding above is too generous for a phone. */
@media (max-width: 900px) {
  .glightbox-container .gslide-description {
    padding: 20px 22px;
  }

  .glightbox-container .gslide-title {
    font-size: 1.2rem;
  }
}

/*--------------------------------------------------------------
# Dish cards (/food-dining)
# The photograph opens in the Gallery's viewer with the dish's own note beside
# it, so it has to look like something you can open: the cursor says zoom, and
# the picture lifts slightly under the pointer. The card clips the overflow, so
# the scale reads as the photograph moving inside its frame rather than as the
# card growing.
--------------------------------------------------------------*/
.food-card .food-lightbox {
  display: block;
  overflow: hidden;
  cursor: zoom-in;
}

.food-card .food-lightbox img {
  transition: transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.food-card .food-lightbox:hover img,
.food-card .food-lightbox:focus-visible img {
  transform: scale(1.06);
}

.food-card .food-lightbox:focus-visible {
  outline: 3px solid var(--accent-color);
  outline-offset: -3px;
}

@media (prefers-reduced-motion: reduce) {
  .food-card .food-lightbox img,
  .food-card .food-lightbox:hover img {
    transition: none;
    transform: none;
  }
}

/*--------------------------------------------------------------
# The timeline spine
# The timeline renders <div class="timeline-track"> down the middle of the
# milestones, and nothing ever styled it -- it ran with no line connecting its
# markers, which is what made it read as broken rather than as a timeline. The
# line is drawn here, behind the year markers, and stops short at each end so
# it does not run past the first and last of them.
#
# Not scoped to a page: the timeline moved from /about to /history-culture,
# where its four milestones of city history actually belong, and the class
# names are specific enough to stand on their own.
--------------------------------------------------------------*/
.journey-timeline .timeline-container {
  position: relative;
}

.journey-timeline .timeline-track {
  position: absolute;
  top: 40px;
  bottom: 40px;
  left: 50%;
  width: 2px;
  margin-left: -1px;
  border-radius: 2px;
  background: linear-gradient(
    to bottom,
    transparent,
    color-mix(in srgb, var(--accent-color) 45%, white) 8%,
    color-mix(in srgb, var(--accent-color) 45%, white) 92%,
    transparent
  );
  z-index: 0;
}

/* The spine fills from the top down to the marker being read. It is the
   same gradient as the track, at full strength, so the filled part reads as
   the line lit rather than as a second line drawn over it. */
.journey-timeline .timeline-track-fill {
  position: absolute;
  inset: 0 0 auto;
  display: block;
  width: 100%;
  border-radius: 2px;
  background: var(--accent-color);
  transition: height 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Header ------------------------------------------------------- */

.journey-timeline .timeline-header .timeline-lead {
  margin-bottom: 14px;
}

.journey-timeline .timeline-header .timeline-intro {
  max-width: 62ch;
  margin: 0 auto;
  font-size: 1.05rem;
  line-height: 1.7;
}

.journey-timeline .timeline-header .timeline-jump-label {
  margin: 26px 0 14px;
  font-size: 0.95rem;
  color: color-mix(in srgb, var(--default-color) 60%, white);
}

.journey-timeline .timeline-jump {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 12px;
}

.journey-timeline .timeline-jump-btn {
  padding: 9px 20px;
  border: 1.5px solid color-mix(in srgb, var(--accent-color) 45%, white);
  border-radius: 99px;
  background: #fff;
  color: var(--heading-color);
  font-size: 0.95rem;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.journey-timeline .timeline-jump-btn:hover {
  border-color: var(--accent-color);
  transform: translateY(-2px);
}

.journey-timeline .timeline-jump-btn.is-active {
  background: var(--accent-color);
  border-color: var(--accent-color);
  color: var(--cian-deepest);
}

/* The marker of the milestone being read. The ring is drawn with box-shadow
   rather than a border so the circle itself never changes size and the row
   below it cannot shift.

   The scale has to carry the centring translate with it: on desktop the marker
   is absolutely positioned at left/top 50% and pulled back by
   translate(-50%, -50%), so a bare `transform: scale()` here replaces that and
   throws the active circle half its own width down and to the right -- which
   is what made the active milestone jump as you scrolled past it. Below 768px
   the marker is in flow with no translate, so there the scale stands alone. */
.journey-timeline .timeline-milestone .milestone-marker {
  transition: box-shadow 0.3s ease, transform 0.3s ease;
}

.journey-timeline .timeline-milestone.is-active .milestone-marker {
  box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent-color) 22%, transparent);
  transform: translate(-50%, -50%) scale(1.06);
}

@media (max-width: 767.98px) {
  .journey-timeline .timeline-milestone.is-active .milestone-marker {
    transform: scale(1.06);
  }
}

.journey-timeline .timeline-milestone .milestone-content {
  transition: box-shadow 0.3s ease, transform 0.3s ease;
}

.journey-timeline .timeline-milestone.is-active .milestone-content {
  box-shadow: 0 14px 34px rgba(17, 17, 17, 0.12);
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .journey-timeline .timeline-track-fill,
  .journey-timeline .timeline-jump-btn,
  .journey-timeline .timeline-milestone .milestone-marker,
  .journey-timeline .timeline-milestone .milestone-content {
    transition: none;
  }

  .journey-timeline .timeline-jump-btn:hover,
  .journey-timeline .timeline-milestone.is-active .milestone-marker,
  .journey-timeline .timeline-milestone.is-active .milestone-content {
    transform: none;
  }
}

/* The markers sit on the line, not under it. */
.journey-timeline .timeline-container .timeline-milestone {
  z-index: 1;
}

/* Stacked layout below 768px: the marker leaves its absolute centring and goes
   back into the flow as `margin: 0 auto`, so it is still horizontally centred --
   the spine stays at 50% with it. It was pinned to 40px here on the assumption
   the markers moved left, which they do not: the line ran down the left margin
   while the circles sat in the middle, connecting nothing. */

/*--------------------------------------------------------------
# Language switcher: the mobile drawer
--------------------------------------------------------------
   The rules above paint the switcher in --nav-color, which is the white of
   the header pill. The mobile drawer is a white panel — the template gives
   its links --nav-dropdown-color instead — so EN / ES was rendering white
   on white: present, focusable, and invisible. Below 1200px it gets the
   drawer's own palette, plus a pill outline: it sits under a divider at the
   foot of a list of plain text links, where a bare pair of words does not
   read as something you can tap. */
@media (max-width: 1199.98px) {
  .navmenu .nav-lang {
    padding: 14px 20px 6px;
    margin-top: 6px;
    border-top: 1px solid color-mix(in srgb, var(--nav-dropdown-color) 12%, transparent);
  }

  .navmenu .nav-lang .nav-lang-group {
    gap: 0;
  }

  .navmenu .nav-lang .nav-lang-current,
  .navmenu .nav-lang .nav-lang-link {
    font-size: 15px;
    /* 44px of touch target, the iOS minimum, without a 44px-tall pill. */
    padding: 11px 18px;
    border: 1px solid color-mix(in srgb, var(--nav-dropdown-color) 20%, transparent);
  }

  .navmenu .nav-lang .nav-lang-current {
    color: var(--contrast-color);
    background-color: var(--nav-dropdown-hover-color);
    border-color: var(--nav-dropdown-hover-color);
    border-radius: 6px 0 0 6px;
  }

  .navmenu .nav-lang .nav-lang-link {
    color: var(--nav-dropdown-color);
    opacity: 1;
    border-left: 0;
    border-radius: 0 6px 6px 0;
  }

  /* The slash is the desktop separator; the pill halves meet edge to edge. */
  .navmenu .nav-lang .nav-lang-sep {
    display: none;
  }
}

/*--------------------------------------------------------------
# Contact: the form on its own, and the band under it
--------------------------------------------------------------
# The contact page lost its three info cards and its regional map embed, and
# the form was built to sit in .form-container-overlap -- a box pulled 100px up
# over the map. With nothing above it the form is the page's only element, so it
# is centred and capped instead: a 40px-padded panel stretched across a wide
# container gives lines of input far wider than anything typed into them.
#
# The band below is two tiles, each a whole link: the reader has just sent a
# message and the page would otherwise end on a dead stop. They lead with a
# photograph rather than an icon plate -- two white cards on the near-white
# page ground barely read as cards at all, and every other band on this site
# sells a destination with a picture of it. Not the photographic promo banner:
# that is one plate composed around one message, and there are two
# destinations of equal weight here. */
.contact .contact-form-solo {
  max-width: 820px;
  margin: 0 auto;
}

.contact-next-tile {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  background: var(--surface-color);
  border-radius: 18px;
  box-shadow: 0 10px 30px rgba(17, 17, 17, 0.08);
  text-decoration: none;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.contact-next-tile:hover,
.contact-next-tile:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 15px 40px rgba(17, 17, 17, 0.15);
}

/* A fixed ratio rather than a fixed height: the two tiles sit side by side and
   their photographs have to line up with each other at every width. */
.contact-next-photo {
  position: relative;
  aspect-ratio: 16 / 9;
  max-width: 100%;
  overflow: hidden;
}

.contact-next-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.contact-next-tile:hover .contact-next-photo img,
.contact-next-tile:focus-visible .contact-next-photo img {
  transform: scale(1.04);
}

.contact-next-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  padding: 24px 28px 28px;
}

.contact-next-body h3 {
  margin: 0 0 10px;
  font-size: 24px;
  color: var(--heading-color);
}

.contact-next-body p {
  margin: 0 0 18px;
  font-size: 16px;
  color: color-mix(in srgb, var(--default-color) 75%, white);
  /* Not justified: this is a CTA tile, not long-form prose. */
  text-align: left;
}

/* The arrow link is decoration inside a link, so it is a <span> styled like a
   link rather than an anchor of its own -- the tile is the link, and a nested
   anchor would be invalid and would steal the click. docs/style.md names a
   shared .particulars-cta for this look; no such rule exists in either
   stylesheet, so the tile carries its own. */
.contact-next-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  /* 13px tracked caps on white: the weakest text on the tile, so it takes the
     ink rather than the raw accent's 2.3:1. */
  color: var(--cian-ink);
}

/* The second tile takes the gold, so the pair reads as two choices rather than
   as one element repeated. */
/* The second tile's CTA is gold where the first is cyan. Same ink treatment:
   raw gold on the white tile measured 3.1:1. */
.contact-next .col-md-6:last-child .contact-next-cta {
  color: var(--oro-ink);
}

.contact-next-cta i {
  transition: transform 0.2s ease;
}

.contact-next-tile:hover .contact-next-cta i,
.contact-next-tile:focus-visible .contact-next-cta i {
  transform: translateX(5px);
}

@media (max-width: 991.98px) {
  .contact .contact-form-solo {
    padding: 28px 22px;
  }

  .contact-next-body {
    padding: 20px 22px 24px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .contact-next-tile,
  .contact-next-photo img,
  .contact-next-cta i {
    transition: none;
  }

  .contact-next-tile:hover,
  .contact-next-tile:focus-visible,
  .contact-next-tile:hover .contact-next-photo img,
  .contact-next-tile:focus-visible .contact-next-photo img,
  .contact-next-tile:hover .contact-next-cta i,
  .contact-next-tile:focus-visible .contact-next-cta i {
    transform: none;
  }
}

/* ==============================================================
# About: collage opener, photo band, mosaic closer
--------------------------------------------------------------
   Built to the structure the client sent as a reference (a green resort
   template): overlapping photographs instead of one rectangle, a full-bleed
   photographic break between the two text bands, and the four principles as
   rows rather than a 2x2 grid of boxes. Only the SHAPE was taken -- the
   colour is this site's own, every value below is a token, and the headings
   reuse the .section-title block rather than inventing a variant.

   Both photo groups are ONE grid each with deliberately overlapping areas,
   not absolutely positioned images. An overlap expressed as two grid items
   claiming the same cell survives a reflow; one expressed as `position:
   absolute; top: -40px` does not, and breaks first at exactly the widths
   nobody tests.

   Collapse is at 991px, the site's multi-column breakpoint. Below it both
   collages become a simple stack: a three-way overlap at 390px is a pile. */

/* ---- 1. Opener ---- */

/* Three columns at xl. At lg the promise column drops to a full-width row
   under the text and the collage, which keeps the collage from being squeezed
   to a third of a tablet. */
/* The three columns are NOT equal and the collage is NOT stretched.

   Stretching it to the promise panel's height was tried and reverted: the
   photographs are wide ones, and a column 430px tall crops them to narrow
   portraits -- the Cumbemayo shot lost the walker's head entirely. A
   photograph's own proportions win over a flush bottom edge.

   So the collage keeps its natural height and is centred in the row, which
   splits the leftover space above and below it and reads as deliberate rather
   than as a column that ran out. Its column is widened a little in exchange,
   which is what actually makes the pictures bigger. */
.about-opener-grid {
  display: grid;
  grid-template-columns: 0.95fr 1.12fr 0.93fr;
  gap: 40px;
  align-items: start;
}

.about-collage {
  align-self: center;
}

/* The section-title block is centred by default -- correct for a band that
   spans the page, wrong for a column of text beside a photograph. */
.about-section-title {
  text-align: left;
  padding-bottom: 0;
  margin-bottom: 18px;
}

.about-section-title h2,
.about-section-title h3 {
  margin: 12px 0 0;
  font-size: clamp(28px, 2.6vw, 38px);
}

.about-section-title p {
  margin: 14px 0 0;
  max-width: 54ch;
  color: color-mix(in srgb, var(--default-color) 70%, white);
}

/* The second half of each heading, in the brand red. Red opens headings and
   marks points across this site; gold is held for labels and the CTA, which
   this column already uses on its button.

   font: inherit is doing real work. main.css L213 resets every <span> on the
   site to 17px Inter 400 to keep the display face out of running text, and a
   span inside an h3 is caught by it -- so "Off the Circuit" set as body copy
   beside a 37px heading. .promo-banner-heading span carries the same fix for
   the same reason. */
.about-accent {
  font: inherit;
  color: var(--tertiary-accent);
}

.about-opener-text .about-lead {
  font-size: 1.08rem;
  font-weight: 500;
}

/* The collage: a 2x3 grid the three photographs overlap on. The tall shot
   holds the left column across the first two rows, the wide one crosses both
   columns at the foot, and the small one sits top right -- so the wide shot
   runs under the other two and the group reads as one composition. */
.about-collage {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.about-collage-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 18px;
  box-shadow: 0 10px 30px rgba(17, 17, 17, 0.08);
}

/* The photographs are STAGGERED, not flush. In the reference each one is
   pushed off its cell by a little, so the group reads as a handful of prints
   laid down rather than a three-up grid -- that offset is most of what makes
   it a collage. Done with a transform, not a margin: a transform does not
   change the grid's own sizing, so the rows stay exactly as computed below
   and only the paint moves. Dropped entirely under 992px, where the group
   becomes a plain stack.

   The tall shot holds the left column across both rows; the other two stack
   beside it. The two stacked images carry an explicit aspect-ratio and the
   tall one simply fills what they add up to.

   The rows are NOT left to size themselves off the images. When they were,
   two things broke at once: the right column had no second item, so row two
   opened a dead cell beside the tall photograph, and the wide shot underneath
   -- a long-exposure of the cathedral, nearly square -- resolved its row to
   its own intrinsic height and ran to roughly a thousand pixels. An
   aspect-ratio on each stacked item fixes the row heights, and height: 100%
   on the tall one makes it match them. */
.about-collage-1 {
  grid-column: 1;
  grid-row: 1 / span 2;
}

/* The stacked shots carry the ratios, which fixes every row height; the two
   tall ones then fill whatever their neighbours add up to. Without this the
   rows size to the images' intrinsic height and the cathedral long-exposure --
   nearly square -- resolved its row to about a thousand pixels. */
.about-collage-2 {
  grid-column: 2;
  grid-row: 1;
  aspect-ratio: 16 / 9;
}

.about-collage-3 {
  grid-column: 2;
  grid-row: 2;
  aspect-ratio: 3 / 2;
}

/* The second tall one, opposite the first and a row lower, so the group reads
   as two interlocking columns rather than one stack with a sidebar. It is the
   only portrait photograph in the set, which is why it takes this slot. */
.about-collage-4 {
  grid-column: 2;
  grid-row: 3 / span 2;
}

.about-collage-5 {
  grid-column: 1;
  grid-row: 3;
  aspect-ratio: 4 / 3;
}

.about-collage-6 {
  grid-column: 1;
  grid-row: 4;
  aspect-ratio: 4 / 3;
}

@media (min-width: 992px) {
  .about-collage-1 { transform: translateY(18px); }
  .about-collage-3 { transform: translateX(10px); }
  /* The lower half leans the other way, so the stagger alternates down the
     group instead of drifting one direction. */
  .about-collage-4 { transform: translate(10px, 4px); }
  .about-collage-6 { transform: translateX(-8px); }
  .about-mosaic-1 { transform: translateY(-14px); }
  .about-mosaic-3 { transform: translateX(12px); }
}

/* The offsets are decorative. A reader who has asked for less motion is not
   asking for a flat layout, so these stay -- but nothing here animates, so
   there is nothing for a reduced-motion escape to switch off. */

/* The promise column sits on the surface colour so it reads as a panel beside
   two columns that sit on the page ground. */
.about-promise {
  background: var(--surface-color);
  border: 1px solid color-mix(in srgb, var(--default-color) 10%, white);
  border-radius: 18px;
  padding: 30px 28px;
}

.about-promise-heading {
  margin: 0 0 14px;
  font-size: clamp(22px, 2vw, 27px);
}

.about-ticks {
  list-style: none;
  margin: 20px 0 0;
  padding: 0;
}

.about-ticks li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 9px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--default-color) 8%, white);
}

.about-ticks li:last-child {
  border-bottom: 0;
}

.about-ticks i {
  flex-shrink: 0;
  margin-top: 2px;
  font-size: 18px;
  color: var(--accent-color);
}

.about-footnote {
  margin: 18px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: color-mix(in srgb, var(--default-color) 60%, white);
}

/* ---- 2. The full-bleed photo band ---- */
/* Was .about-band and About-only. It is the site's one editorial break -- a
   photograph with the type laid over it and no card around it -- so it is now
   .photo-band and any page can take one. About and Things to Do both render it
   through src/components/PhotoBand.jsx. */

/* A break in the page, not a card: no container, no radius, no shadow. The
   photograph is a real <img> rather than a background-image so it carries an
   alt and the browser can lazy-load it; object-fit does the cropping that
   background-size: cover would have. */
.photo-band {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: clamp(380px, 46vw, 560px);
  padding: 60px 0;
  overflow: hidden;
  isolation: isolate;
}

/* The photograph stays with the viewport while the band travels over it, so
   the words read as moving across a still landscape rather than as a block
   sliding past. background-attachment does it with no script and no scroll
   listener: the background resolves against the viewport, the section clips
   it, and the type is the only thing that moves.

   It is a background and not an <img> for exactly that reason -- position:
   fixed inside the section resolves against the section, which scrolls, and
   the effect disappears. The alt text lives on role="img" + aria-label in
   About.jsx instead. The url() is set inline from the content file. */
/* A band rendered INSIDE a .container still has to run edge to edge. Same
   breakout the card-ring stage uses in section 24. Only for that case: a band
   that is already a top-level section needs nothing. */
.photo-band.is-breakout {
  width: 100vw;
  margin-left: calc(50% - 50vw);
}

.photo-band-img {
  position: absolute;
  inset: 0;
  z-index: -2;
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  background-attachment: fixed;
}

/* Two places where the fixed attachment has to be given up.

   Touch devices: iOS Safari and most mobile browsers either ignore
   background-attachment: fixed or size the background to a viewport that
   changes height as the address bar hides, which jumps the photograph mid
   scroll. A phone shows a plain cover crop instead, which is what it showed
   before.

   Reduced motion: the whole point of the effect is movement the reader did not
   ask for, so a reader who has asked for less of it gets none. */
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
  .photo-band-img {
    background-attachment: scroll;
  }
}

/* Darkened enough for white type to pass against it, and no further: the
   client's standing note on this site is that the photographs are the point
   and a heavy scrim throws them away. The gradient keeps the weight at the
   centre, where the words are, and lets the corners stay open. */
.photo-band-scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(ellipse at center, rgba(17, 17, 17, 0.62) 0%, rgba(17, 17, 17, 0.34) 70%, rgba(17, 17, 17, 0.22) 100%);
}

.photo-band-content {
  position: relative;
  text-align: center;
  max-width: 760px;
}

.photo-band-eyebrow {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--secondary-accent);
  /* 13px of gold over a photograph is the weakest type in the band, and the
     radial scrim is thinnest where a bright sky usually sits. The heading
     beside it is white and carries its own weight; this needs the shadow stack
     the page masthead uses or it washes out completely against cloud. */
  text-shadow:
    0 1px 2px rgba(17, 17, 17, 0.95),
    0 2px 8px rgba(17, 17, 17, 0.85),
    0 0 20px rgba(17, 17, 17, 0.7);
}

.photo-band-content h2,
.photo-band-content h3 {
  margin: 0;
  color: var(--contrast-color);
  font-size: clamp(32px, 4vw, 54px);
  /* The type carries itself over any bright frame the scrim leaves showing,
     the same way the homepage hero's does. */
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.8),
    0 3px 16px rgba(0, 0, 0, 0.7);
}

.photo-band-body {
  margin: 18px auto 26px;
  max-width: 58ch;
  color: color-mix(in srgb, var(--contrast-color) 90%, transparent);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.6);
}

/* ---- 3. Closer ---- */

.about-why-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 54px;
  align-items: center;
}

/* The mosaic: one tall photograph beside two stacked, with the small cards
   laid across the foot of the whole group. */
.about-mosaic {
  position: relative;
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 14px;
  padding-bottom: 86px;
}

.about-mosaic-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 18px;
  box-shadow: 0 10px 30px rgba(17, 17, 17, 0.08);
}

/* Same construction, same reason: the two stacked shots set the row heights
   with an aspect-ratio and the tall one fills them. */
.about-mosaic-1 {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.about-mosaic-2 { grid-column: 2; grid-row: 1; aspect-ratio: 4 / 3; }
.about-mosaic-3 { grid-column: 2; grid-row: 2; aspect-ratio: 4 / 3; }

/* ONE panel overlapping the foot of the mosaic, with the two notes side by
   side inside it -- not two separate cards. Two cards floated over a
   photograph read as debris; one panel reads as a caption block, which is what
   the reference does and what these two notes are.

   The padding-bottom on .about-mosaic is what reserves the room for it, so
   nothing below is overlapped in turn -- an absolutely positioned element that
   hangs past its parent collides with the next thing on the page at the first
   width nobody checked. */
.about-overlays {
  position: absolute;
  left: 8%;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  background: var(--surface-color);
  border: 1px solid color-mix(in srgb, var(--default-color) 10%, white);
  border-radius: 18px;
  padding: 20px 24px;
  box-shadow: 0 10px 30px rgba(17, 17, 17, 0.08);
}

.about-overlays h4 {
  margin: 0 0 6px;
  font-size: 17px;
}

.about-overlays p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: color-mix(in srgb, var(--default-color) 70%, white);
}

/* The four principles, as rows. They were .info-box squares in a 2x2 grid,
   which gave each one a headline-sized title over two lines of text and read
   as four cards competing with the photographs beside them. A row puts the
   icon, the title and the body on one reading line. */
.about-rows {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
}

.about-rows li {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  padding: 18px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--default-color) 8%, white);
}

.about-rows li:last-child {
  border-bottom: 0;
}

.about-row-icon {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 12px;
  /* Solid, with the mark reversed out of it, as in the reference -- a tinted
     plate with a tinted icon on it disappears beside the photographs.
     Near-black rather than the brand cyan: the cyan is the icon's own colour
     here, and a cyan mark on a cyan plate is nothing. */
  background: var(--default-color);
}

/* The marks are the site's own PNGs (see the content file), not a glyph font,
   so they are sized as images rather than by font-size. */
.about-row-icon img {
  width: 24px;
  height: 24px;
  object-fit: contain;
}

.about-rows h4 {
  margin: 0 0 5px;
  font-size: 18px;
}

.about-rows p {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.65;
  color: color-mix(in srgb, var(--default-color) 70%, white);
}

.about-credits {
  margin-top: 36px;
}

/* The closing call to action. The inherited template put this on a
   teal-to-black gradient that belonged to the Eliot's Adventures palette; it
   is the brand's near-black with a cyan cast now. */
/* The flat ink panel the closing CTA band on every other page already uses
   (What To Eat, Getting Here, Travel Tips, Sources). This one carried a
   three-stop 135deg gradient through an off-palette teal and out to cyan at a
   160% stop -- a different closing band on one page, for no reason the page
   gives. */
.about-cta {
  margin-top: 46px;
  border-radius: 12px;
  padding: 44px 42px;
  text-align: center;
  background: var(--default-color);
  color: var(--contrast-color);
}

.about-cta h3 {
  margin: 0 0 12px;
  color: var(--contrast-color);
}

.about-cta p {
  margin: 0 auto 24px;
  max-width: 56ch;
  color: color-mix(in srgb, var(--contrast-color) 82%, transparent);
}

.about-cta-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
}

/* The outline button sits on a dark ground here, so it takes the contrast
   colour rather than the cyan it uses on the page ground. .btn-outline gets no
   global rule on this site either, so this is the full border shorthand and
   not just a border-color, which would paint nothing. */
.about-cta .btn-outline {
  border: 1px solid color-mix(in srgb, var(--contrast-color) 55%, transparent);
  color: var(--contrast-color);
}

.about-cta .btn-outline:hover {
  background: var(--contrast-color);
  color: var(--heading-color);
}

/* ---- Collapse ---- */

@media (max-width: 1199.98px) {
  /* The promise panel drops to a full-width row under the text and the
     collage rather than being squeezed to a third of a tablet. */
  .about-opener-grid {
    grid-template-columns: 1fr 1fr;
    gap: 36px;
  }

  .about-collage {
    align-self: start;
  }

  .about-promise {
    grid-column: 1 / -1;
  }
}

@media (max-width: 991.98px) {
  .about-opener-grid,
  .about-why-grid {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  /* A three-way overlap at tablet width and below is a pile, so both groups
     become plain stacks: every photograph full width, in source order. */
  .about-collage,
  .about-mosaic {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    padding-bottom: 0;
  }

  .about-collage-img,
  .about-mosaic-img {
    grid-column: 1;
    grid-row: auto;
    aspect-ratio: 16 / 10;
    height: auto;
    max-height: 320px;
  }

  /* The collage is the exception to the stack. Six photographs one under the
     other is most of a screen's worth of scrolling before the reader reaches
     the text they are illustrating, so this group keeps two columns and
     shrinks instead -- still a group, still in source order. */
  .about-collage {
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }

  .about-collage-img {
    /* The stack rule above pins every photograph to column 1. These flow
       across both columns instead, so the pair rule actually pairs them. */
    grid-column: auto;
    max-height: 200px;
  }

  /* Out of the overlap and into the flow, below the photographs. */
  .about-overlays {
    position: static;
    left: auto;
    right: auto;
    margin-top: 4px;
  }

  .about-cta {
    padding: 34px 24px;
  }
}

@media (max-width: 575.98px) {
  .about-overlays {
    grid-template-columns: 1fr;
  }

  .photo-band {
    min-height: 340px;
  }
}

/* The buttons. .btn-primary carries NO brand styling globally on this site --
   it is branded inside the hero (main.css L1147) and then re-declared by each
   section that uses it (#featured-destinations, #news-advice,
   #getting-around). Outside those it falls through to Bootstrap's default
   blue, which is what the About page's three buttons rendered as. This is the
   same scoped re-declaration those sections use; the global fix belongs in
   main.css and is a bigger change than this page should make on its own. */
.about-opener .btn.btn-primary,
.photo-band .btn.btn-primary,
.about-cta .btn.btn-primary {
  background-color: var(--btn-color);
  border-color: var(--btn-color);
  color: var(--contrast-color);
}

.about-opener .btn.btn-primary:hover,
.photo-band .btn.btn-primary:hover,
.about-cta .btn.btn-primary:hover {
  background-color: var(--btn-hover-color);
  border-color: var(--btn-hover-color);
  color: var(--contrast-color);
}

/*--------------------------------------------------------------
# 22. Page masthead: the per-route accent rule
# src/components/PageTitle.jsx draws one short rule under the h1, in one of the
# three brand accents, chosen per route. The masthead was identical on twelve
# pages; this is the one thing allowed to differ, so a reader can tell which
# part of the guide they are in without the shape changing under them.
--------------------------------------------------------------*/
.page-title .page-title-rule {
  display: block;
  width: 88px;
  height: 6px;
  border-radius: 99px;
  /* Sits above the h1 with clear air under it. Between the heading and the
     lead it fell into the gap between two lines of type and read as nothing. */
  margin: 0 auto 20px;
  /* It is a bar of flat colour over a photograph, so it needs the same halo
     the type beside it gets, or a bright frame swallows its edges. */
  box-shadow: 0 2px 10px rgba(17, 17, 17, 0.7), 0 0 20px rgba(17, 17, 17, 0.45);
}

@media (max-width: 575.98px) {
  .page-title .page-title-rule {
    width: 64px;
    height: 5px;
    margin: 0 auto 16px;
  }
}

/*--------------------------------------------------------------
# 23. The closing CTA panel
# src/components/CtaPanel.jsx. Three pages carried this inline, identically,
# writing #111111 and #fff as raw hex -- which is exactly the drift that breaks
# a .dark-background subtree. Tokens only here.
--------------------------------------------------------------*/
.cta-panel {
  background: var(--default-color);
  border-radius: 12px;
  padding: 32px 36px;
  text-align: center;
  color: var(--contrast-color);
}

.cta-panel h3 {
  color: var(--contrast-color);
  font-weight: 700;
  margin-bottom: 8px;
}

.cta-panel p {
  color: color-mix(in srgb, var(--contrast-color) 75%, transparent);
  margin-bottom: 20px;
}

.cta-panel-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

.cta-panel-btn {
  padding: 10px 24px;
  border-radius: 8px;
  font-weight: 700;
  text-decoration: none;
  transition: background 0.18s ease;
}

.cta-panel-btn.is-primary {
  background: var(--accent-color);
  color: var(--default-color);
}

.cta-panel-btn.is-primary:hover,
.cta-panel-btn.is-primary:focus-visible {
  background: color-mix(in srgb, var(--accent-color), white 18%);
  color: var(--default-color);
}

.cta-panel-btn.is-ghost {
  background: color-mix(in srgb, var(--contrast-color) 15%, transparent);
  color: var(--contrast-color);
}

.cta-panel-btn.is-ghost:hover,
.cta-panel-btn.is-ghost:focus-visible {
  background: color-mix(in srgb, var(--contrast-color) 26%, transparent);
  color: var(--contrast-color);
}

@media (max-width: 575.98px) {
  .cta-panel {
    padding: 26px 20px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cta-panel-btn {
    transition: none;
  }
}

/*--------------------------------------------------------------
# 24. The card ring: stage, panel and CTA
# Used by History & Culture and by Trivia & Quick Facts, which render the same
# carousel over different data. Both pages carried this as an inline <style>
# block, byte for byte apart from two comments -- about 50 lines duplicated in
# two files, with nothing keeping them in step. The geometry that drives the
# ring (GEOMETRY, DRAG_THRESHOLD, ringOffset) now lives in
# src/components/cardRing.js for the same reason.
#
# The .hc- prefix is kept so neither page's markup had to change.
--------------------------------------------------------------*/

/* The stage breaks out of the 1180px container: the stack is the widest thing
   on the page and looked marooned inside it. The wrapper carries the breakout
   so the arrows can be positioned against it. */
.hc-stage-wrap {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
}

.hc-stage {
  height: 600px;
  width: 100%;
}

.hc-nav-side {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 30;
}

.hc-nav-side.is-prev { left: clamp(10px, 7vw, 120px); }
.hc-nav-side.is-next { right: clamp(10px, 7vw, 120px); }
.hc-nav-side:hover { transform: translateY(-50%) scale(1.06); }
.hc-nav-side:active { transform: translateY(-50%) scale(1); }

.hc-card {
  width: 336px;
  height: 462px;
}

.hc-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  align-items: start;
}

/* Fixed box: entries differ in length, and letting the row grow with the text
   would shove the card stack down the page. */
.hc-panel {
  height: 340px;
  overflow-y: auto;
  /* Clicking the centre photograph sends the reader up to this panel. The
     header is FIXED and 120px deep here (104px below 1200px), so without this
     the panel lands underneath it and the eyebrow the reader was sent to --
     "THE STORY OF THE VALLEY", the date -- is hidden behind the nav. Measured
     from the header rather than copied from the 90px the site gives a section,
     which is shallower than this header actually is, plus a clear gap so the
     eyebrow is not tucked right under the nav's edge -- landing flush against
     it still reads as overlapping. */
  scroll-margin-top: 175px;
}

.hc-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
}

/* The header is 104px below 1200px, so the clearance shrinks with it, keeping
   the same gap underneath. */
@media (max-width: 1199.98px) {
  .hc-panel { scroll-margin-top: 160px; }
  .blg-crumbs { padding-top: 152px; }
}

@media (max-width: 991.98px) {
  .hc-stage { height: 400px; }

  .hc-nav-side {
    width: 44px !important;
    height: 44px !important;
    font-size: 18px !important;
  }

  .hc-nav-side.is-prev { left: 8px; }
  .hc-nav-side.is-next { right: 8px; }
  .hc-card { width: 228px; height: 316px; }
  .hc-grid { grid-template-columns: 1fr; gap: 28px; }
  .hc-panel { height: auto; overflow: visible; }
  .hc-cta { flex-direction: column; text-align: center; }
}

.hc-nav:hover {
  background: var(--accent-color);
  color: var(--default-color);
  box-shadow: 0 10px 24px rgba(17, 17, 17, 0.28);
}

.hc-nav:focus-visible {
  outline: 3px solid var(--accent-color);
  outline-offset: 3px;
}

.hc-dot:hover { opacity: 1; }

/* The caption block on each card, and the hover states that tell a reader the
   photograph is a control rather than a picture.

   THE PROBLEM THIS SOLVES: the cards had no hover response at all. A thing that
   does not react to the mouse reads as decoration, so nobody tried clicking
   one. Moved out of the inline styles on both pages because :hover cannot
   reach an inline style without !important.

   Note there is no hover on a phone, which is why the affordance is not left to
   hover alone -- the intro copy on both pages says the photograph is tappable.
   This is the desktop half of that. */
.hc-card-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 46px 18px 16px;
  text-align: left;
  color: var(--background-color);
  background: linear-gradient(to top, rgba(17, 17, 17, 0.86), rgba(17, 17, 17, 0));
  transition: background 320ms ease;
}

/* A row, so the arrow can sit at the far end of it. */
.hc-card-eyebrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.82;
  margin-bottom: 4px;
}

.hc-card-title {
  display: block;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
}

/* Full opacity and large enough to register. The first version rode the end of
   the title text at 13px and 0.9 opacity, where a two-line title buried it and
   readers reported never seeing it at all. */
.hc-card-arrow {
  flex: none;
  font-size: 16px;
  opacity: 1;
  transition: transform 260ms ease;
}

.hc-card img {
  transition: filter 380ms ease, transform 620ms cubic-bezier(0.32, 0.72, 0.24, 1);
}

/* At rest the flanking cards are held back so the centre one leads. */
.hc-card:not([aria-current="true"]) img {
  filter: saturate(0.72) brightness(0.86);
}

/* Pointing at one brings it to life: full colour and a slight push in. That is
   the whole signal -- this responds, so it can be pressed.

   Driven by the `is-lit` class, NOT by :hover. The flanking cards are behind
   the stage's plane in 3D, so the browser never hit-tests them and :hover on
   one can never fire; useCardHover works out which card the pointer is over
   from the painted geometry instead. :focus-visible is kept, because keyboard
   focus does reach the card. */
.hc-card:not([aria-current="true"]) img.is-lit,
.hc-card:not([aria-current="true"]):focus-visible img {
  filter: none;
  transform: scale(1.04);
}

/* The centre card is already full colour, so it answers in the caption instead:
   the scrim deepens and the arrow lifts towards where the click will take you. */
.hc-card[aria-current="true"]:hover .hc-card-caption,
.hc-card[aria-current="true"]:focus-visible .hc-card-caption {
  background: linear-gradient(to top, rgba(17, 17, 17, 0.94), rgba(17, 17, 17, 0.1));
}

.hc-card[aria-current="true"]:hover .hc-card-arrow,
.hc-card[aria-current="true"]:focus-visible .hc-card-arrow {
  transform: translateY(-4px);
}

/* Text swap reads as a change of subject rather than a jump. */
.hc-fade { animation: hcFade 460ms ease both; }

@keyframes hcFade {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hc-fade { animation: none; }
  .hc-card { transition: none !important; }
  .hc-nav-side:hover { transform: translateY(-50%); }
  /* The colour change stays -- it is the signal. Only the movement goes. */
  .hc-card img { transition: filter 380ms ease; }
  .hc-card:not([aria-current="true"]) img.is-lit { transform: none; }
  .hc-card-arrow { transition: none; }
  .hc-card[aria-current="true"]:hover .hc-card-arrow { transform: none; }
}

/* ==============================================================
# 25. Landmark detail: the newspaper front page
# src/pages/LandmarkDetail.jsx. Opening a place from What to Do should read
# like opening a broadsheet, not like opening a product page: a standing rule,
# a kicker line of details, the name set as large as it will go, then the piece
# in two unequal columns with a hairline between them.
#
# The grid is 1.35fr / 1fr rather than halves because a newspaper's columns are
# never equal -- the wide one carries the plate and the body, the narrow one
# the deck, the opening paragraph and the standing facts. The rule between them
# is a border on the narrow column, not a pseudo-element, so it disappears by
# itself when the two stack at 991px.
#
# No date and no issue number anywhere: a guide entry is not an issue of
# anything, and dating it would only make it look stale.
============================================================== */

/* --- The piece ----------------------------------------------- */

.landmark-paper .lmn-body {
  border-top: 3px solid var(--heading-color);
  margin-top: 44px;
  padding-top: 32px;
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: 40px;
}

.landmark-paper .lmn-side {
  border-left: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
  padding-left: 40px;
}

.landmark-paper .lmn-figure {
  margin: 0 0 24px;
}

.landmark-paper .lmn-figure img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
}

/* The lead plate runs at the photograph's own ratio. Forcing it to 4:5 cropped
   a 16:9 frame down the sides, which on the dairy tasting cut the woman at the
   stall -- the subject of the picture -- out of it. A single column can carry a
   tall or a wide plate; the slider below is where one ratio had to be imposed. */
.landmark-paper .lmn-figure-lead img {
  max-width: 100%;
}

.landmark-paper .lmn-figure figcaption {
  margin-top: 8px;
  font-size: 13px;
  line-height: 1.45;
  color: color-mix(in srgb, var(--default-color) 60%, white);
  border-bottom: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
  padding-bottom: 8px;
}

.landmark-paper .lmn-subhead {
  margin: 0 0 14px;
  font-family: var(--heading-font);
  font-weight: 700;
  font-size: clamp(22px, 1.2vw + 1rem, 30px);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--heading-color);
}

.landmark-paper .lmn-prose p {
  margin-bottom: 18px;
  text-align: justify;
  hyphens: auto;
}

.landmark-paper .lmn-prose p:last-child { margin-bottom: 0; }

/* The deck: the standfirst a broadsheet sets above the opening paragraph. */
.landmark-paper .lmn-deck {
  margin: 0 0 18px;
  font-family: var(--heading-font);
  font-weight: 700;
  font-size: clamp(26px, 1.8vw + 1rem, 40px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--heading-color);
}

.landmark-paper .lmn-lead {
  margin: 0 0 20px;
  text-align: justify;
  hyphens: auto;
}

.landmark-paper .lmn-lead::first-letter {
  float: left;
  font-family: var(--heading-font);
  font-size: 3.4em;
  line-height: 0.82;
  padding: 2px 10px 0 0;
  color: var(--tertiary-accent);
}

.landmark-paper .lmn-pending {
  font-size: 14px;
  color: color-mix(in srgb, var(--default-color) 60%, white);
}

/* Standing facts: name/value pairs about one place, so a dl. */
.landmark-paper .lmn-facts {
  border-top: 3px solid var(--heading-color);
  padding-top: 16px;
}

.landmark-paper .lmn-facts dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0;
  margin: 0;
}

.landmark-paper .lmn-facts dt,
.landmark-paper .lmn-facts dd {
  padding: 9px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--default-color) 14%, white);
  margin: 0;
  font-size: 14px;
}

.landmark-paper .lmn-facts dt {
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--secondary-accent);
  padding-right: 18px;
}

.landmark-paper .lmn-facts dd { text-align: right; }

/* --- Strips below the fold ----------------------------------- */

.landmark-paper .lmn-classified,
.landmark-paper .lmn-plate {
  border-top: 3px solid var(--heading-color);
  margin-top: 44px;
  padding-top: 20px;
}

.landmark-paper .lmn-smallprint {
  font-size: 13px;
  color: color-mix(in srgb, var(--default-color) 60%, white);
  margin-bottom: 16px;
}

.landmark-paper .lmn-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.landmark-paper .lmn-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 24px;
}

.landmark-paper .lmn-tag {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 5px 12px;
  color: color-mix(in srgb, var(--default-color) 70%, white);
  border: 1px solid color-mix(in srgb, var(--default-color) 20%, white);
}

/* --- Collapse ------------------------------------------------ */

@media (max-width: 991px) {
  .landmark-paper .lmn-body { grid-template-columns: 1fr; gap: 32px; }

  .landmark-paper .lmn-side {
    border-left: 0;
    border-top: 3px solid var(--heading-color);
    padding-left: 0;
    padding-top: 24px;
  }

}

@media (max-width: 767px) {
  .landmark-paper .lmn-kicker { grid-template-columns: 1fr; }

  .landmark-paper .lmn-kicker-cell {
    border-left: 0;
    padding: 7px 0;
    border-top: 1px solid color-mix(in srgb, var(--default-color) 14%, white);
  }

  .landmark-paper .lmn-kicker-cell:first-child { border-top: 0; }

  /* Justified type in a narrow measure opens rivers; left-aligned is the
     honest setting below the tablet breakpoint. */
  .landmark-paper .lmn-prose p,
  .landmark-paper .lmn-lead { text-align: left; hyphens: manual; }
}

/* --- The plate slider ----------------------------------------
   The landmark photographs come from several sources at several aspect
   ratios. Stacked into a grid they left ragged gaps down the page, so they
   run as one scroll-snapped strip at a fixed 3:2 instead. Snap does the
   scrolling; the buttons only nudge the track, so the strip still swipes on
   touch and still reads with scripting off. */

.landmark-paper .lmn-slider { position: relative; }

.landmark-paper .lmn-slider-track {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  padding-bottom: 4px;
}

.landmark-paper .lmn-slider-track::-webkit-scrollbar { display: none; }

.landmark-paper .lmn-slide {
  flex: 0 0 calc((100% - 32px) / 3);
  scroll-snap-align: start;
  display: block;
}

.landmark-paper .lmn-slide img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
  transition: opacity 0.25s ease;
}

.landmark-paper .lmn-slide:hover img { opacity: 0.88; }

.landmark-paper .lmn-slider-nav {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 14px;
}

.landmark-paper .lmn-slider-nav button {
  width: 40px;
  height: 40px;
  border: 1px solid color-mix(in srgb, var(--default-color) 25%, white);
  background: var(--surface-color);
  color: var(--heading-color);
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease;
}

.landmark-paper .lmn-slider-nav button:hover {
  background: var(--heading-color);
  color: var(--contrast-color);
}

.landmark-paper .lmn-slider-nav button:focus-visible {
  outline: 3px solid var(--accent-color);
  outline-offset: 2px;
}

@media (max-width: 991px) {
  .landmark-paper .lmn-slide { flex-basis: calc((100% - 16px) / 2); }
}

@media (max-width: 575px) {
  .landmark-paper .lmn-slide { flex-basis: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .landmark-paper .lmn-slider-track { scroll-behavior: auto; }
  .landmark-paper .lmn-slide img { transition: none; }
}

/*--------------------------------------------------------------
# 25. .btn-outline-primary, everywhere rather than in one section
# The base sheet brands this button only under `.travel-tours` (main.css:3602).
# Things to Do and Where to Stay happen to render inside that section, so they
# came out cyan and nobody noticed the rule was scoped. The blog listing cards
# and the 404 page are not inside it, so their buttons fell through to
# Bootstrap's own .btn-outline-primary and rendered rgb(13, 110, 253) -- a blue
# that appears nowhere in the palette.
#
# Scoping a brand colour to one section is the bug: the next component to use
# this class would have inherited the same problem. The rule is unscoped here,
# which is what the base sheet should have done. Padding, radius and weight
# repeat main.css so a button looks the same wherever it is used.
--------------------------------------------------------------*/
.btn-outline-primary {
  /* "Read Guide", "View Hotel", "Read Article" -- the most-clicked control on
     the hub pages, and at 2.3:1 the least readable thing on the site. The ink
     carries both the label and the border so the control's own edge clears
     3:1 as well. */
  color: var(--cian-ink);
  border-color: var(--cian-ink);
  padding: 0.75rem 1.5rem;
  border-radius: 8px;
  font-weight: 600;
  transition: all 0.3s ease;
}

.btn-outline-primary:hover,
.btn-outline-primary:focus-visible {
  /* Filled on hover, so the ground has to carry white: the raw accent gives
     white 2.3:1, the ink gives it 5.1:1. */
  background-color: var(--cian-ink);
  border-color: var(--cian-ink);
  color: var(--contrast-color);
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .btn-outline-primary {
    transition: none;
  }

  .btn-outline-primary:hover,
  .btn-outline-primary:focus-visible {
    transform: none;
  }
}

/* ==============================================================
   26. Blog body plates.

   A blog entry is a magazine piece. The body was plain type down a
   single measure; these are the photographs set into it, under the
   `.blg-` prefix, and they follow the same plate language as the
   landmark front page in section 25: hairline border, no rounding,
   no shadow, caption in small grey type over a rule.

   The lead plate runs the full measure, like the opening picture of a
   spread. Every plate after it floats, right then left alternately,
   at a little under half the measure, so the type wraps around it and
   the page reads as columns rather than as a stack. Floats clear at
   the headings, so a plate never bleeds past the section it belongs
   to. Below 767px every plate goes full width in document order --
   a wrapped column at phone measure opens rivers, and a 44% picture
   on a 360px screen is a thumbnail.
   ============================================================== */

.blog-post-body .blg-plate {
  margin: 0 0 28px;
}

.blog-post-body .blg-plate img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
}

.blog-post-body .blg-plate figcaption {
  margin-top: 8px;
  padding-bottom: 8px;
  font-size: 13px;
  line-height: 1.45;
  color: color-mix(in srgb, var(--default-color) 60%, white);
  border-bottom: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
}

.blog-post-body .blg-plate-lead {
  margin-top: 8px;
}

.blog-post-body .blg-plate-right,
.blog-post-body .blg-plate-left {
  width: 44%;
  margin-top: 6px;
}

.blog-post-body .blg-plate-right {
  float: right;
  margin-left: 32px;
}

.blog-post-body .blg-plate-left {
  float: left;
  margin-right: 32px;
}

/* A section owns its plates: the next heading starts on a clean line. */
.blog-post-body h2,
.blog-post-body h3 {
  clear: both;
}

@media (max-width: 767px) {
  .blog-post-body .blg-plate-right,
  .blog-post-body .blg-plate-left {
    float: none;
    width: 100%;
    margin-left: 0;
    margin-right: 0;
  }
}

/* ==============================================================
   27. Blog entry: the magazine opener and the columned piece.

   An entry opens as a spread, not as a banner with a headline
   under it. On the grid: the lead plate holds the right two-thirds
   and runs tall; the masthead sits on a block of page ground that
   cuts into its left edge, the way a magazine drops type over the
   corner of a photograph; two offset plates stack down the left,
   the lower one inset so the stack steps rather than stacking
   square.

   Under it the piece runs in two columns on a wide screen, because
   that is what the opener promises and a 17px single measure after
   a spread reads as a different document. One column below 991px,
   where two would leave a measure too narrow to justify.
   ============================================================== */

/* The floating header sits over the page, so the opener starts below it:
   the masthead's kicker was landing behind the nav pill. */
/* The breadcrumb trail now opens the page, so it is the thing that has to
   clear the fixed header -- the padding moved here from .blg-opener below.
   The header box is 120px deep (104px below 1200px) and the trail needs a real
   gap under it; at 132px it sat 12px off the nav and read as stuck to it. */
.blg-crumbs {
  padding-top: 168px;
}

.blg-crumbs .breadcrumbs ol {
  margin-bottom: 16px;
}

.blg-opener {
  padding-top: 0;
}

.blg-opener-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: auto auto auto;
  align-items: start;
}

/* The lead plate: right two-thirds, spanning every row. */
.blg-opener-hero {
  grid-column: 5 / 13;
  grid-row: 1 / 4;
  margin: 0;
  align-self: stretch;
}

.blg-opener-hero img {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 420px;
  object-fit: cover;
  border: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
}

/* The masthead block, overlapping the plate by one grid column. */
.blg-opener-head {
  grid-column: 1 / 6;
  grid-row: 1;
  z-index: 2;
  background-color: var(--background-color);
  padding: 0 28px 28px 0;
}

.blg-opener-kicker {
  margin: 0 0 14px;
  font-family: var(--default-font);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--secondary-accent);
}

.blg-opener-kicker a {
  color: inherit;
  text-decoration: none;
}

.blg-opener-title {
  margin: 0;
  font-family: var(--heading-font);
  font-weight: 700;
  font-size: clamp(34px, 3.6vw + 0.5rem, 62px);
  line-height: 0.94;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  color: var(--heading-color);
}

/* The offset stack. The second plate is inset from the left so the
   two step down the page instead of forming a column. */
.blg-opener-plate {
  margin: 0;
  z-index: 2;
  /* Page ground behind the plate, the same block the masthead sits on: the
     plates overlap the lead photograph, and a caption over a photograph is
     unreadable. The gutter to the right of each plate reads as the cut. */
  background-color: var(--background-color);
}

.blg-opener-plate img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
}

.blg-opener-plate-1 {
  grid-column: 1 / 6;
  grid-row: 2;
  aspect-ratio: 4 / 3;
  padding-right: 28px;
}

.blg-opener-plate-2 {
  grid-column: 2 / 6;
  grid-row: 3;
  padding-right: 28px;
  padding-bottom: 28px;
}

.blg-opener-plate-2 img {
  aspect-ratio: 16 / 9;
}

/* The deck: the standfirst between the opener and the piece. */
.blog-post-article .blg-deck {
  margin: 18px 0 24px;
  font-size: clamp(19px, 0.5vw + 1rem, 23px);
  line-height: 1.5;
  color: color-mix(in srgb, var(--default-color) 75%, white);
}

/* A plate of a place is a way to that place's page: the picture is the link,
   and the caption carries a named one under it so the route is visible to a
   reader who does not try clicking the photograph. */
.blog-post-body .blg-plate-link,
.blg-opener-plate .blg-plate-link {
  display: block;
  text-decoration: none;
}

.blog-post-body .blg-plate-link img,
.blg-opener-plate .blg-plate-link img {
  transition: opacity 0.18s ease;
}

.blog-post-body .blg-plate-link:hover img,
.blg-opener-plate .blg-plate-link:hover img {
  opacity: 0.88;
}

.blog-post-body .blg-plate-more,
.blg-opener-plate .blg-plate-more {
  font-weight: 600;
  color: var(--accent-color);
  text-decoration: none;
}

.blog-post-body .blg-plate-more:hover,
.blg-opener-plate .blg-plate-more:hover {
  text-decoration: underline;
}

.blg-opener-plate figcaption {
  margin-top: 8px;
  padding-bottom: 8px;
  font-size: 13px;
  line-height: 1.45;
  border-bottom: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
}

/* Section headings are wrapped in their own anchor by markdown-it-anchor
   (headerLink), so they were inheriting the body link rule and setting
   themselves in cyan and underlined. A heading is a heading: ink, no rule.
   The anchor stays, so the deep link still works. */
.blog-post-body h2 a,
.blog-post-body h3 a,
.blog-post-body h4 a {
  color: var(--heading-color);
  text-decoration: none;
}

.blog-post-body h2 a:hover,
.blog-post-body h3 a:hover,
.blog-post-body h4 a:hover {
  color: var(--accent-color);
}

@media (min-width: 992px) {
  .blog-post-article {
    max-width: 1040px;
  }

  /* The piece, in columns. */
  .blog-post-body {
    columns: 2;
    column-gap: 44px;
    column-rule: 1px solid color-mix(in srgb, var(--default-color) 18%, white);
  }

  /* A heading must not be left stranded at the foot of a column. */
  .blog-post-body h2,
  .blog-post-body h3 {
    break-after: avoid;
    break-inside: avoid;
  }

  .blog-post-body h2:first-child,
  .blog-post-body h3:first-child {
    margin-top: 0;
  }

  /* Inside columns a plate fills its column: floating it at 44% of an
     already narrow measure leaves a thread of type beside it. */
  .blog-post-body .blg-plate-right,
  .blog-post-body .blg-plate-left {
    float: none;
    width: 100%;
    margin-left: 0;
    margin-right: 0;
  }

  .blog-post-body .blg-plate {
    break-inside: avoid;
  }
}

@media (max-width: 991px) {
  /* Stacked: masthead, lead plate, then the two offset plates side by
     side, which keeps the collage legible without the overlap. */
  .blg-opener-grid {
    /* minmax(0, 1fr), not 1fr: a plain fr floors at the item's min-content, so
       the longer caption was making its column the wider of the two. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto;
    gap: 16px;
  }

  .blg-opener-hero,
  .blg-opener-head {
    grid-column: 1 / 3;
    grid-row: auto;
  }

  .blg-opener-head {
    order: -1;
    padding: 24px 0 8px;
  }

  .blg-opener-hero img {
    min-height: 260px;
    aspect-ratio: 16 / 9;
    height: auto;
  }

  .blg-opener-plate-1,
  .blg-opener-plate-2 {
    grid-column: auto;
    grid-row: auto;
    margin: 0;
    padding: 0;
  }

  .blg-opener-plate-1 img,
  .blg-opener-plate-2 img {
    aspect-ratio: 4 / 3;
    height: auto;
  }
}

/*--------------------------------------------------------------
# Accessibility floor
# Added by the audit pass. Nothing here changes how the site looks at rest:
# it is hit areas, focus affordances and the one contrast fix that does not
# touch the footage.
--------------------------------------------------------------*/

/* Skip link. First focusable element on every page (Layout.jsx), off screen
   until it takes focus. Every page puts a seven-item nav before its content,
   which is seven tab stops between the address bar and the first sentence.
   Not `display: none`: a hidden element is not focusable, and the link would
   then exist for nobody. */
.skip-link {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translate(-50%, -120%);
  z-index: 1100; /* over the header (997) and its filter bar (996) */
  padding: 12px 24px;
  min-height: var(--tap-min);
  display: flex;
  align-items: center;
  border-radius: 0 0 12px 12px;
  background: var(--cian-deepest);
  color: var(--contrast-color);
  font-family: var(--default-font);
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
  box-shadow: 0 10px 30px rgba(17, 17, 17, 0.08);
  transition: transform 0.18s ease;
}

.skip-link:focus-visible {
  transform: translate(-50%, 0);
  color: var(--contrast-color);
  outline: 2px solid var(--accent-color);
  outline-offset: 3px;
}

/* <main> takes focus from the skip link, but it is not an interactive element
   and must not draw a ring when the pointer lands on it. */
.main:focus {
  outline: none;
}

/* Bootstrap ships .visually-hidden and the contact form's labels use it. It is
   declared here too so the labels survive the stylesheet being swapped. */
.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

/*--------------------------------------------------------------
# Hit areas
# The deck dots on /travel-tips/trivia and /history-culture were 8x8 CSS
# pixels: a third of the WCAG 2.5.8 minimum and, on a phone, the only way
# through a deck that has no swipe gesture. The dot still LOOKS 8px -- it is
# drawn by ::before -- while the button it lives in is 44px square.
--------------------------------------------------------------*/

.hc-dot {
  width: var(--tap-min);
  height: var(--tap-min);
  padding: 0;
  border: none;
  background: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  /* The dots sit in a row on a touch deck. Without this the browser waits
     300ms on each tap to see whether a double-tap zoom is starting. */
  touch-action: manipulation;
}

.hc-dot::before {
  content: '';
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 99px;
  background: var(--inert);
  transition: width 320ms ease, background 320ms ease;
}

.hc-dot[aria-current='true']::before {
  width: 22px;
  background: var(--default-color);
}

.hc-dot:hover::before {
  background: var(--inert-strong);
}

.hc-dot[aria-current='true']:hover::before {
  background: var(--default-color);
}

.hc-dot:focus-visible {
  outline: 2px solid var(--accent-color);
  outline-offset: -6px;
  border-radius: 99px;
}

/* The row packs the 44px buttons back to the 8px rhythm the dots had, so the
   hit areas overlap nothing and the dots still read as a tight group. */
.hc-dots {
  display: flex;
  align-items: center;
  margin: 0 -18px;
}

@media (prefers-reduced-motion: reduce) {
  .hc-dot::before { transition: none; }
}

/* The jump bar on /hotels and the editor's own small controls sat at 38-40px.
   Padding, not height, so a label that wraps still grows the control. */
.stay-jump-link {
  min-height: var(--tap-min);
  display: inline-flex;
  align-items: center;
  touch-action: manipulation;
}

/* Every control that scrolls or swipes under a finger declares its gesture, so
   the browser stops reserving the double-tap-zoom delay on it. */
.travel-tours .destination-filters,
.stay-jump-inner {
  touch-action: pan-x;
}

/* The card deck drags horizontally through pointer events and captures the
   pointer on pointerdown. With no touch-action the browser also claims the
   same horizontal movement for panning and zooming, so on a phone the deck
   and the page fought over every swipe and the deck usually lost. pan-y hands
   the horizontal axis to the deck and keeps the vertical one for the page, so
   a sideways swipe turns the cards and a downwards one scrolls past them. */
.hc-stage {
  touch-action: pan-y;
}

/*--------------------------------------------------------------
# Hero buttons: contrast
# docs/style.md and the comment at the hero scrim record a client decision --
# the footage is never dimmed. That decision stands, and the heading and lede
# still carry themselves on their shadows alone.
# The buttons are not the footage. They draw their own ground, and that ground
# was rgba(10,12,14,0.34): over a bright frame -- this clip has white stucco
# and pale plaza stone -- white on it measured about 2.6:1. At 0.58 the same
# glass fill measures 4.9:1 against the worst frame the video can show, and
# the picture around the buttons is untouched.
--------------------------------------------------------------*/

.travel-hero .hero-text .hero-buttons .btn.btn-outline {
  background-color: rgba(10, 12, 14, 0.58);
}

/*--------------------------------------------------------------
# Accent borders
# The detector flags every coloured border on one edge. Three of the five it
# found here are not the antipattern and are left alone:
#   .stay-group-title      a rule beside a bare heading, not a card
#   .dish-trivia           the site's callout idiom, one shape in three colours
#   admin blockquote       a quotation rule, which is older than the web
# The one that is the antipattern is .stay-partners: a 12px-rounded dark panel
# with a 4px cyan stripe across the top, where the stripe runs straight off
# both rounded corners. The panel already reads as its own band because it is
# the only dark ground on the page, so the stripe was doing nothing the ground
# was not. The cyan moves to the label inside it, which is where this site puts
# cyan everywhere else.
--------------------------------------------------------------*/

/* The cyan the stripe carried, moved onto the label it was introducing.
   Measured against --default-color: 8.9:1. */
.stay-partners-label {
  color: var(--accent-color);
}


/*--------------------------------------------------------------
# Hero link row on a phone
# Six `display: block; width: 100%` buttons, stacked, each with a 1rem gap:
# about 420px of button under the lede. On a 390x844 screen that is the whole
# first viewport spent on a list that repeats the nav directly above it, and
# the footage the hero exists to show was entirely behind it.
#
# They stay six equal links -- that was a deliberate call, recorded in
# Home.jsx: these are six sections of a guide and none of them is THE action,
# so promoting one would read as a mistake. Two columns, not one, is the same
# decision laid out in half the height: three rows instead of six, the
# headline and lede stay above the fold, and the valley is visible behind
# them. The labels are short enough to sit side by side, and the row goes back
# to one column below 380px where they are not.
--------------------------------------------------------------*/

@media (max-width: 991.98px) {
  .travel-hero .hero-text .hero-buttons {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
  }

  /* The template set these three per button; the grid owns layout now. */
  .travel-hero .hero-text .hero-buttons .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    margin-bottom: 0;
    min-height: var(--tap-min);
    padding-inline: 10px;
    font-size: 0.875rem;
    text-align: center;
  }
}

@media (max-width: 379.98px) {
  .travel-hero .hero-text .hero-buttons {
    grid-template-columns: 1fr;
  }
}

/* The EN/ES control. The language code is two characters at 13px with 6px of
   padding, so the link measured 34x40 -- the smallest target in the header,
   and the one a visitor reading the wrong language most needs to hit. The
   type stays 13px; the padding grows to carry a 44px target. */
.navmenu .nav-lang .nav-lang-current,
.navmenu .nav-lang .nav-lang-link {
  min-width: 34px;
  min-height: var(--tap-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 8px;
  touch-action: manipulation;
}
