﻿/* ==========================================================================
   Traville Travel — components.css
   Buttons, cards, forms, header/nav, footer, placeholders, floats
   ========================================================================== */

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  padding: 14px 28px;
  border-radius: var(--radius-pill);
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: transform 0.2s ease, background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--white), 0 0 0 5px var(--teal); }
/* On small screens, let long button labels wrap instead of overflowing. */
@media (max-width: 600px) { .btn { white-space: normal; line-height: 1.25; } }

.btn--gold {
  background: var(--gold);
  color: #2a2208;
}
.btn--gold:hover { background: var(--gold-light); color: #2a2208; }

.btn--teal {
  background: var(--teal);
  color: var(--white);
}
.btn--teal:hover { background: var(--teal-light); color: var(--white); }

/* WhatsApp channel CTA — a muted green-teal that harmonises with the Traville
   teal palette (rather than the bright WhatsApp green), still clearly a green
   "channel" button and distinct from the gold newsletter CTA above it. */
.btn--whatsapp { background: #16856E; color: #fff; font-weight: 700; }
.btn--whatsapp:hover { background: #11705C; color: #fff; }
.btn--whatsapp svg { width: 16px; height: 16px; flex: none; margin: -1px 0; }

.btn--outline {
  background: transparent;
  color: var(--white);
  border-color: rgba(255,255,255,0.7);
}
.btn--outline:hover { background: rgba(255,255,255,0.12); color: var(--white); }

.btn--outline-teal {
  background: transparent;
  color: var(--teal);
  border-color: var(--teal);
}
.btn--outline-teal:hover { background: var(--teal); color: var(--white); }

.btn--white {
  background: var(--white);
  color: var(--teal);
}
.btn--white:hover { background: var(--sand); color: var(--teal); }

.btn--lg { padding: 16px 34px; font-size: 15px; }
.btn--block { width: 100%; }

/* Emergency / medical CTA — reads as urgent without shouting.
   Ambulance red with a white medical cross and a soft pulsing ring. */
.btn--emergency {
  background: linear-gradient(180deg, #EF2B32 0%, #D01020 100%);
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.18);
  font-weight: 700;
  letter-spacing: 0.01em;
  padding-left: 26px;
  box-shadow: 0 8px 22px rgba(208, 16, 32, 0.4);
  animation: emergencyPulse 2.6s ease-out infinite;
}
.btn--emergency:hover {
  background: linear-gradient(180deg, #FF3A40 0%, #DE1524 100%);
  color: var(--white);
  box-shadow: 0 12px 28px rgba(208, 16, 32, 0.5);
}
/* White medical-cross badge inside the button (ambulance/hospital emblem). */
.btn--emergency .btn__cross {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 21px;
  height: 21px;
  border-radius: 5px;
  background: var(--white);
  color: #D01020;
}
.btn--emergency .btn__cross svg { width: 13px; height: 13px; }
/* Gently expanding red aura that fades before repeating — calm, not flashing. */
@keyframes emergencyPulse {
  0%   { box-shadow: 0 8px 22px rgba(208, 16, 32, 0.38), 0 0 0 0 rgba(239, 43, 50, 0.5); }
  70%  { box-shadow: 0 8px 22px rgba(208, 16, 32, 0.38), 0 0 0 18px rgba(239, 43, 50, 0); }
  100% { box-shadow: 0 8px 22px rgba(208, 16, 32, 0.38), 0 0 0 0 rgba(239, 43, 50, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .btn--emergency { animation: none; }
}

/* arrow link */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  font-size: 14px;
  color: var(--teal);
}
.arrow-link:hover { gap: 10px; }

/* ---------- Top bar ---------- */
.topbar {
  background: var(--charcoal);
  color: #ccc;
  font-size: 12px;
  padding: 8px 0;
}
.topbar a { color: #ccc; }
.topbar a:hover { color: var(--gold-light); }
/* Touch targets for the standalone contact links (WCAG 2.2 AA, 2.5.8).
   These measured 15-20px tall on a phone. The rule is scoped deliberately: it
   covers tel:/mailto: links that stand ALONE as controls — the top bar, the
   footer address block and the contact list — and not the same links written
   inside a sentence ("Prefer to call? +27 …"), which 2.5.8 exempts as inline
   targets and which would gain ugly line-spacing from vertical padding.
   min-height + inline-flex grows the hit area without moving the text, so the
   bars keep their existing rhythm. Applied at the mobile breakpoint only,
   where touch is the input method. */
@media (max-width: 1023px) {
  .topbar__group a[href^="tel:"],
  .topbar__group a[href^="mailto:"],
  .footer-brand address a,
  .contact-list .row a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;   /* grown from 24px toward the 44px comfortable-tap target */
  }
}
.topbar__inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.topbar__group { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; }
.topbar__group span { display: inline-flex; align-items: center; gap: 6px; }
/* Stack the WhatsApp bubble above the label and centre it. Explicit column flex
   rather than relying on the text wrapping, which only happened when the bar
   ran out of room and left the bubble hanging off to the left. */
.topbar__group a[aria-label*="Specials Channel"] {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  line-height: 1.25;
}

/* ---------- Header / nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 200;
  background: var(--white);
}
/* The header is sticky, so a cross-page jump to #map would land the section
   underneath it. Offsetting the target keeps the map heading clear of the bar
   without any scroll scripting. The sticky bar measures 70px at every width —
   it does not shrink on mobile — so one value covers all breakpoints. */
[id="map"], [id="emergency-information"] { scroll-margin-top: 92px; }
.navbar {
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: box-shadow 0.25s ease;
}
.site-header.is-stuck .navbar { box-shadow: 0 4px 20px rgba(0,0,0,0.08); }

.brand {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 28px;
  color: var(--teal);
  letter-spacing: 0.5px;
}
.brand .dot { color: var(--gold); }

.nav-links {
  display: flex;
  align-items: center;
  gap: 22px;
}
.nav-links > li > a {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: 0.01em;
}
.nav-links > li > a:hover { color: var(--teal); }
.nav-links a.is-active { color: var(--teal); }

/* dropdown */
.has-dropdown { position: relative; }
.has-dropdown > .dropdown-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  padding: 0;
}
.has-dropdown > .dropdown-toggle:hover { color: var(--teal); }
.dropdown-toggle .caret {
  width: 8px; height: 8px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.2s ease;
  margin-top: -2px;
}
.has-dropdown.open .caret { transform: rotate(-135deg); margin-top: 2px; }

.dropdown-menu {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow-md);
  min-width: 220px;
  padding: 10px;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
}
.has-dropdown:hover .dropdown-menu,
.has-dropdown.open .dropdown-menu {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
.dropdown-menu li a {
  display: block;
  padding: 9px 14px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
}
.dropdown-menu li a:hover { background: var(--teal-pale); color: var(--teal); }
.dropdown-menu .divider {
  height: 1px;
  background: var(--border);
  margin: 6px 8px;
}
/* Other Offers destination preview: a subtle, informational lockup of the six
   offer destinations that reveals on hover/focus of the Other Offers item, so
   it never enlarges the resting dropdown. Real text, so it is keyboard- and
   screen-reader-accessible; focus-within covers keyboard users. */
.offer-preview {
  display: block;
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transform: translateY(-3px);
  padding: 0 14px;
  transition: max-height 0.32s ease, opacity 0.24s ease, transform 0.24s ease, margin 0.32s ease;
}
/* The preview starts collapsed each time the Offers dropdown opens and only
   expands once the pointer/focus reaches Other Offers. From then on it is
   latched OPEN by the .is-offers-expanded class (set in nav.js) for as long as
   the pointer stays anywhere in the Offers dropdown, so the cursor can travel
   from Other Offers across its destinations and on to Latest Specials without
   the panel collapsing or Latest Specials shifting. nav.js clears the class when
   the pointer leaves the dropdown or it closes, so the next open starts closed.
   Mobile keeps the preview inline via the ≤1023px rule, independent of this. */
.has-dropdown.is-offers-expanded .offer-preview {
  /* Roomier: the destination list is now three lines (2 per line), not one. */
  max-height: 104px;
  opacity: 1;
  transform: none;
  margin: 2px 0 6px;
}
.offer-preview__lead {
  display: block;
  font-size: 11px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: 2px;
}
.offer-preview__list {
  display: block;
  font-size: 11px; line-height: 1.5; color: var(--muted);
}
/* Each featured-offer line holds a pair (e.g. "Mauritius · Zanzibar"); stacking
   them gives the requested three rows. Inherits the parent's alignment — left on
   the desktop popover, right in the mobile drawer. */
.offer-preview__row { display: block; }
/* "Other Offers" expandable indicator: a caret matching the main-nav
   .dropdown-toggle .caret (same 8px box, 1.5px strokes, 0.2s rotate) so it
   reads as "opens further". Purely visual (aria-hidden); the link target and
   the hover/focus preview behaviour are unchanged. Rotates up while the
   preview is open (hover, keyboard focus, or the latched is-offers-expanded
   state), mirroring the main caret's open state. */
.has-offer-preview > a .caret {
  display: inline-block;
  width: 8px; height: 8px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.2s ease;
  margin-left: 7px;
  vertical-align: middle;
  position: relative; top: -1px;
}
.has-offer-preview:hover > a .caret,
.has-offer-preview:focus-within > a .caret,
.has-dropdown.is-offers-expanded .has-offer-preview > a .caret {
  transform: rotate(-135deg);
  top: 1px;
}

/* ---------- Mega menu ----------
   One component, two menus; the only difference is the data. Layers onto
   .has-dropdown so nav.js's click, outside-click and Escape handling apply
   unchanged.

   No JavaScript drives the hover. transition-delay on the open state gives
   genuine hover-intent in pure CSS: the panel does not begin to appear until
   the cursor has rested for 140ms, so it never flies open as the pointer
   crosses the label on its way elsewhere. Leaving has a shorter delay, which
   doubles as the grace period for moving diagonally into the panel. */
.has-mega { position: static; }          /* panel spans the header, not the item */

.mega-panel {
  position: absolute;
  left: 0; right: 0;
  top: 100%;
  z-index: 210;
  /* Branded backdrop, drawn entirely in CSS so it costs no request and cannot
     pixellate. Three layers, front to back: dotted flight paths at 7% opacity,
     a soft teal halo centred behind the leading tile, and the field colour.
     Everything sits well below the cards' own contrast so nothing competes.
     The field is --sand (#F5F0E8) — the exact colour behind the "Four ways to
     get pricing" tiles on the quotes page (.section--sand), reused here so the
     two surfaces read as one system. Flat rather than a wash, so the tiles meet
     the same value wherever they sit in the panel. */
  background-color: var(--sand);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1240' height='420'%3E%3Cg fill='none' stroke='%230B6E6E' stroke-width='1.1' stroke-linecap='round' stroke-dasharray='2 10' opacity='0.07'%3E%3Cpath d='M-40 316 C 210 196 430 196 690 268'/%3E%3Cpath d='M560 96 C 780 44 1000 96 1280 62'/%3E%3Cpath d='M96 74 C 286 26 432 78 566 44'/%3E%3Cpath d='M720 348 C 920 296 1080 316 1280 262'/%3E%3C/g%3E%3Cg fill='%23C49A3C' opacity='0.10'%3E%3Ccircle cx='690' cy='268' r='3'/%3E%3Ccircle cx='96' cy='74' r='2.6'/%3E%3Ccircle cx='1280' cy='62' r='2.6'/%3E%3Ccircle cx='720' cy='348' r='2.6'/%3E%3C/g%3E%3C/svg%3E"),
    radial-gradient(ellipse 640px 320px at 50% 2%, rgba(11,110,110,0.08), transparent 72%);
  background-repeat: no-repeat, no-repeat;
  background-position: center bottom, center top;
  /* Viewport-aware height so no tile is ever unreachable. 132px is the chrome
     above the panel in the worst case — the 46px topbar plus the 70px sticky
     header, plus a small breathing gap. Measured from the worst case rather
     than the scrolled one, because the topbar is only absent once the page has
     scrolled; sizing for that state would clip the panel at the top of the page.
     Scrolls only when the content actually exceeds the space. */
  max-height: calc(100vh - 132px);
  overflow-y: auto;
  overflow-x: hidden;                    /* never a horizontal scrollbar */
  overscroll-behavior: contain;          /* don't chain scroll to the page behind */
  border-top: 1px solid var(--border);
  box-shadow: 0 26px 54px rgba(11,110,110,0.13), 0 2px 8px rgba(0,0,0,0.05);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity 0.26s ease, transform 0.26s ease, visibility 0.26s;
  transition-delay: 0.08s;               /* brief grace period on close */
}
.has-mega:hover > .mega-panel,
.has-mega:focus-within > .mega-panel,
.has-mega.open > .mega-panel {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition-delay: 0.14s;               /* hover intent */
}
/* keyboard and click paths should feel immediate, not delayed */
.has-mega:focus-within > .mega-panel,
.has-mega.open > .mega-panel { transition-delay: 0s; }

/* Subtle scrollbar, shown only when the panel actually overflows. Firefox and
   Chromium take different properties, so both are declared. */
.mega-panel { scrollbar-width: thin; scrollbar-color: rgba(11,110,110,0.32) transparent; }
.mega-panel::-webkit-scrollbar { width: 8px; }
.mega-panel::-webkit-scrollbar-track { background: transparent; }
.mega-panel::-webkit-scrollbar-thumb {
  background: rgba(11,110,110,0.28);
  border-radius: 99px;
  border: 2px solid transparent;
  background-clip: content-box;
}
.mega-panel::-webkit-scrollbar-thumb:hover { background: rgba(11,110,110,0.48); background-clip: content-box; }

.mega-panel__inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 36px 24px 44px;
  /* Standard typography refinement for BOTH mega menus: grayscale smoothing
     renders every glyph edge cleanly (body already antialiases; this adds the
     macOS/Firefox grayscale path). Single place, both panels. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
.mega-panel__intro {
  margin: 0 0 22px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  /* Slightly darker than --muted: the tinted backdrop below dropped the muted
     grey to 4.37:1, under the 4.5:1 AA floor for body text. */
  color: #575757;
}

/* Fixed 190px columns rather than fractions, centred as a block: both panels
   then share one tile size and density regardless of how many cards they hold,
   so the two menus cannot drift apart as content is added. */
.mega-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(4, var(--mega-tile));
  justify-content: center;
  gap: 23px 20px;   /* 26px 22px - 10% */
}
/* The tile's query container lives on the <li>, not the <a> inside it. cqi units
   resolve against an ANCESTOR container (so the label can't query its own
   parent), and the <li> is a grid item with a definite width in every case —
   including the full-width solo tile, where an auto-width <a> would instead
   collapse to zero under inline-size containment. */
.mega-item { container-type: inline-size; }
/* Positioning only — a tile alone on its own centred row. Applied to the <li>,
   which is the grid item; on the inner <a> it would do nothing. Used by the
   quotes hero at the top and by Other Destinations at the foot. */
.mega-item--solo {
  grid-column: 1 / -1;
  width: var(--mega-tile);
  margin-inline: auto;
}
/* Centred bottom pair on the 4-column destinations panel (4 / 4 / 2): the two
   tiles take the middle two of the four columns, so the empty outer columns
   balance them either side. Reset to normal flow on the 2-column mobile grid,
   where two tiles already make a centred final row. */
.mega-item--pair-l { grid-column: 2; }
.mega-item--pair-r { grid-column: 3; }
/* Secondary "offer" cards in the Online Quotes panel sit on row 3, directly
   beneath their matching live engine: Beachcomber Offers under Beachcomber Live
   Rates (col 1) and Holiday Offers under Holiday Packages (col 4). Explicit
   placement keeps the two middle columns clear on the desktop 4-col grid; DOM
   order keeps each offer beside its engine so the mobile stack stays paired.
   (Reset to normal flow on the ≤1023px grids — see the mobile block below.) */
.mega-item--secondary { grid-row: 3; }
.mega-item--col1 { grid-column: 1; }
.mega-item--col4 { grid-column: 4; }

.mega-card { display: block; color: var(--text); }
/* Tile face rendered entirely in CSS — no image. The gradient is brand tokens
   (--teal-light -> --teal with a --teal-pale halo), the name is real text sized
   in container units, and the rules are CSS. Every tile is weightless, its copy
   is crawlable, and there is no image load so no layout shift.
   container-type lets the name scale with the tile via cqi at every breakpoint,
   exactly as the old 640px image did. --radius-card is kept so the top accent
   rule is clipped identically to the quote cards. */
.mega-card__media {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;                   /* strict square, reserves space up-front */
  border-radius: var(--radius-card);
  overflow: hidden;
  padding: 8cqi 10cqi;                   /* cqi resolves against .mega-card above */
  text-align: center;
  background:
    radial-gradient(ellipse 62% 52% at 50% 44%, rgba(230,244,244,0.12), transparent 70%),
    linear-gradient(180deg, var(--teal-light) 0%, var(--teal) 100%);
  box-shadow: 0 6px 18px rgba(0,0,0,0.07);
  transition: transform 0.32s cubic-bezier(0.22,0.61,0.36,1), box-shadow 0.32s ease;
}
/* Same teal->gold accent rule the quote cards carry, from the shared token:
   3px, left to right, 0.7 lifting to 1 on hover. z-index keeps it above the
   artwork and the placeholder letter, both of which follow it in the box. */
.mega-card__media::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 2;
  background: var(--accent-rule);
  opacity: 0.7;
  transition: opacity 0.25s ease;
}
.mega-card:hover .mega-card__media::before { opacity: 1; }
/* ---- Mega card name: ONE typography spec for every card in BOTH menus ----
   Single source of truth. Every destination AND quote card inherits these four
   tokens, so there is zero per-card size variation and every future change is
   made here alone. There is deliberately no .mega-card--wide size override any
   more: long names (Safaris & South Africa, Beachcomber Packages, ...) wrap and
   re-balance at the SAME size rather than being shrunk to fit. Vertical centring
   of the name+rule group is handled by the flex .mega-card__media, so a one-line
   name and a three-line name each sit optically centred in the square. */
:root {
  --mega-label-family:  var(--font-display);
  --mega-label-weight:  400;
  --mega-label-size:    13.5cqi;   /* the Online Quotes card size — now universal */
  --mega-label-leading: 1.08;      /* one leading for all; keeps wrapped names readable */
  /* Single lever for tile size in BOTH mega menus. Every internal dimension —
     media height (aspect-ratio 1/1), padding (8/10cqi), label (13.5cqi) and
     rules (7/26cqi) — is expressed in container units relative to the tile
     width, so changing this one token rescales the whole tile proportionally.
     171px = 190px - 10% (universal 10% reduction). */
  --mega-tile: 171px;
}
.mega-card__label {
  font-family: var(--mega-label-family);
  font-weight: var(--mega-label-weight);
  color: #fff;
  font-size: var(--mega-label-size);
  line-height: var(--mega-label-leading);
  letter-spacing: normal;
  text-wrap: balance;
  text-shadow: 0 1px 10px rgba(0,0,0,0.12);
}
/* the centred accent rule beneath the name (the shared teal->gold token) */
.mega-card__rule {
  margin-top: 7cqi;
  width: 26cqi;
  max-width: 92px;
  height: 3px;
  border-radius: 3px;
  background: var(--accent-rule);
}
/* Optional descriptor beneath the accent rule (build config: sublabel), making
   the tile a brand-over-place lockup. It inherits the SAME type spec as the
   title — same family, weight, colour and tracking — at half the size, driven
   off --mega-label-size so one token still governs both.

   height:0 is the important part. The media box centres its children, so an
   in-flow descriptor would push the title upward and break alignment with
   every other tile. Zero height keeps the descriptor out of the centring
   maths — the title + rule group measures exactly as it does on a plain tile,
   so the title sits at an identical height — and the translate then drops the
   overflowing text into place beneath the rule. */
.mega-card__sublabel {
  height: 0;
  font-family: var(--mega-label-family);
  font-weight: var(--mega-label-weight);
  font-size: calc(var(--mega-label-size) / 2);
  line-height: 1.2;
  letter-spacing: normal;
  color: #fff;
  text-shadow: 0 1px 10px rgba(0,0,0,0.12);
  transform: translateY(5cqi);
}
.mega-card__badge {
  position: absolute; top: 10px; left: 10px;
  padding: 4px 10px; border-radius: 999px;
  background: var(--gold); color: #2a2208;
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
}
/* The name is no longer repeated below the tile — the on-tile text carries it.
   The body appears only on the quote tiles, holding the descriptive sub-line
   that explains each tile's function (information, not duplication). Centred to
   sit under the centred tile above. */
.mega-card__body { display: block; margin-top: 10px; text-align: center; }
.mega-card__sub {
  display: block;
  font-size: 12.5px; line-height: 1.5; font-weight: 500; color: var(--muted);
  transition: color 0.24s ease;
}
/* External-link note under a card's description — ~half the sub-line size and
   muted, so it reads as a quiet secondary indicator, not part of the pitch. */
.mega-card__ext {
  display: block; margin-top: 3px;
  font-size: 11px; line-height: 1.3; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--muted); opacity: 0.85;
}
.mega-card:hover .mega-card__media {
  transform: translateY(-4px);
  box-shadow: 0 16px 34px rgba(11,110,110,0.2);
}
.mega-card:hover .mega-card__sub { color: var(--teal); }
.mega-card:focus-visible { outline: 3px solid var(--gold); outline-offset: 4px; border-radius: 14px; }

@media (max-width: 1100px) { .mega-grid { gap: 16px 14px; } }

/* --- Appearance modifiers, independent of position ---
   featured: the primary entry point. Reads as primary through placement and a
   restrained gold ring, not through being larger. */
.mega-item--solo.mega-item--featured { margin-bottom: 6px; }
/* featured keeps the same teal tile as every other card; it is marked only by a
   restrained gold ring, not a different colour or size. */
.mega-card--featured .mega-card__media { box-shadow: 0 8px 22px rgba(11,110,110,0.16), inset 0 0 0 1.5px rgba(196,154,60,0.6); }
/* Featured intro copy reads as an instruction, not body text: brand teal with a
   fine underline, so it is recognisable at a glance as the starting point
   without borrowing the weight of a button. Everything else about the line is
   untouched — same family, size, weight, leading and centring as every other
   card sub — so the emphasis comes only from colour and rule.
   The underline is deliberately built from the decoration properties rather
   than a border: it follows the text when the line wraps on narrow screens,
   which a border-bottom on the block would not. The offset keeps it clear of
   the descenders instead of striking through them.
   Both selectors carry the same colour so the line does NOT shift on card
   hover — the surrounding .mega-card:hover .mega-card__sub rule would
   otherwise animate it, and a colour change here would read as a link state on
   something that is already inside a link. */
.mega-card--featured .mega-card__sub,
.mega-card--featured:hover .mega-card__sub {
  color: var(--teal);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: rgba(11, 110, 110, 0.45);
}

/* ---- Flip tile: premium 3D hover that reveals a muted video (desktop only) ----
   Opt-in via .mega-card--flip + [data-flip-video]. The square footprint and the
   front CSS tile are unchanged; a 3D inner rotates around the vertical axis to
   show the clip on the reverse. The interaction is wired in js/mega-flip.js and
   gated to hover-capable pointers there, so the states below stay inert (a normal
   Mauritius tile) on touch devices until the script adds .is-flipped. */
.mega-card--flip { perspective: 1000px; }
.mega-card--flip .mega-card__flip {
  position: relative; display: block;
  aspect-ratio: 1 / 1;                    /* identical square to .mega-card__media */
  transform-style: preserve-3d;
  transition: transform 0.62s cubic-bezier(0.45, 0.05, 0.2, 1);
  will-change: transform;
}
.mega-card--flip .mega-card__face {
  position: absolute; inset: 0;
  border-radius: var(--radius-card);
  overflow: hidden;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
}
/* The front face carries the existing tile; fill the (already square) face rather
   than letting the media re-square itself inside it. */
.mega-card--flip .mega-card__face--front .mega-card__media {
  position: absolute; inset: 0; aspect-ratio: auto;
}
/* Back face: a clean brand-teal panel so the reverse is never blank while it
   rotates; the video sits on top and only fades in once the flip has completed. */
.mega-card--flip .mega-card__face--back {
  transform: rotateY(180deg);
  background: var(--teal);
}
.mega-card--flip .mega-card__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;                      /* fill the square cleanly, no distortion */
  display: block;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.mega-flip.is-playing .mega-card__video { opacity: 1; }
/* The flip is the hover affordance — suppress the card's translate lift so the
   two transforms never fight and the dimensions stay constant through the turn. */
.mega-card--flip:hover .mega-card__media {
  transform: none;
  box-shadow: 0 6px 18px rgba(0,0,0,0.07);
}
/* Rotation state, toggled by the script on hover (desktop pointers only). It
   lives on the .mega-flip wrapper (the hover region + button host), not the <a>,
   so moving onto the mute button never ends the hover. */
.mega-flip { position: relative; display: block; }
.mega-flip.is-flipped .mega-card__flip { transform: rotateY(180deg); }

/* ---- Reusable mute/unmute control (audio-enabled flip tiles) ----
   A compact, high-contrast circular button pinned to the card's bottom-right,
   over the video. Dark translucent fill + white glyph + a faint light ring read
   reliably over any footage. It appears only once the video side is shown, stays
   inside the card, and never changes the card's size or layout. */
.mega-card__mute {
  position: absolute; right: 10px; bottom: 10px; z-index: 3;
  width: 34px; height: 34px; padding: 0; margin: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%;
  background: rgba(15, 20, 20, 0.55);
  color: #fff; cursor: pointer;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.28), 0 2px 8px rgba(0,0,0,0.4);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  opacity: 0; visibility: hidden; transform: translateY(4px);
  transition: opacity 0.2s ease, transform 0.2s ease, background 0.15s ease;
}
.mega-flip.is-playing .mega-card__mute { opacity: 1; visibility: visible; transform: none; }
.mega-card__mute:hover { background: rgba(15, 20, 20, 0.72); }
.mega-card__mute:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.mega-card__mute svg { width: 18px; height: 18px; display: block; pointer-events: none; }
/* Glyph state: speaker+wave when sound is on, speaker+slash when muted. */
.mega-card__mute .mega-card__mi--off { display: none; }
.mega-card__mute.is-muted .mega-card__mi--on { display: none; }
.mega-card__mute.is-muted .mega-card__mi--off { display: block; }

/* ---- Quotes-panel logo flip (continuous) ------------------------------------
   The four quote-tool cards flip slowly and continuously between the teal tile
   (front) and the supplier's full-colour logo (back) while hovered. Independent
   of the video flip above: its own class (.mega-card--qflip) and its own state
   class (.is-qflipped), driven by js/quote-flip.js. The whole card is one <a>,
   so both faces open the same URL. Self-contained so it can't affect other tiles
   or the static quote cards on the Online Quotes page. */
.mega-card--qflip { perspective: 1000px; }
.mega-card--qflip .mega-card__flip {
  position: relative; display: block;
  aspect-ratio: 1 / 1;                         /* the square footprint, like the media */
  transform-style: preserve-3d;
  transition: transform 0.9s cubic-bezier(0.45, 0.05, 0.2, 1);
  will-change: transform;
}
.mega-card--qflip.is-qflipped .mega-card__flip { transform: rotateY(180deg); }
.mega-card--qflip .mega-card__face {
  position: absolute; inset: 0;
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
  border-radius: var(--radius-card); overflow: hidden;
}
/* Front face carries the existing CSS tile; fill the (already square) face. */
.mega-card--qflip .mega-card__face--front .mega-card__media {
  position: absolute; inset: 0; aspect-ratio: auto;
}
/* Back face: the supplier logo on a clean panel. All presentation is config-driven
   through CSS custom properties with sensible defaults, so a new quote tool needs
   no new CSS — the generator sets any of these inline from the tile's config:
     background   <- logobg   (default white)
     --qlogo-pad  <- logopad  (clear space around the logo; default 15%)
     --qlogo-h    <- logosize (logo max-height; default 60%)
     --qlogo-w    <- logow    (logo max-width;  default 100%)
   The logo is always centred and object-fit:contain, so proportions are never
   distorted whatever the aspect ratio. */
.mega-card--qflip .mega-card__face--logo {
  transform: rotateY(180deg);
  display: flex; align-items: center; justify-content: center;
  padding: var(--qlogo-pad, 15%);
  background: var(--white);
}
.mega-card__qlogo {
  max-width: var(--qlogo-w, 100%); max-height: var(--qlogo-h, 60%);
  width: auto; height: auto; object-fit: contain; display: block;
}
/* Optional stacked lockup (config: logo = emblem, logo2 = wordmark). A vertical,
   centred composition — enlarged emblem in the upper portion, wordmark beneath —
   for premium brand marks. Sizes/spacing are config-driven via CSS vars. */
.mega-card--qflip .mega-card__lockup {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--qlockup-gap, 8%);
  width: 100%; height: 100%;
}
.mega-card__qemblem {
  max-height: var(--qemblem-h, 50%); max-width: 76%;
  width: auto; height: auto; object-fit: contain; display: block;
}
.mega-card__qword {
  max-width: var(--qword-w, 86%); max-height: 26%;
  width: auto; height: auto; object-fit: contain; display: block;
}
/* Suppress the card's hover lift so it doesn't fight the flip transform. */
.mega-card--qflip:hover .mega-card__media { transform: none; box-shadow: 0 6px 18px rgba(0,0,0,0.07); }
/* Reduced motion: no continuous spin — the logo simply crossfades in on hover/focus. */
@media (prefers-reduced-motion: reduce) {
  .mega-card--qflip .mega-card__flip { transition: none; transform: none !important; }
  .mega-card--qflip .mega-card__face--logo {
    transform: none; opacity: 0;
    -webkit-backface-visibility: visible; backface-visibility: visible;
    transition: opacity 0.3s ease;
  }
  .mega-card--qflip:hover .mega-card__face--logo,
  .mega-card--qflip:focus-within .mega-card__face--logo { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .mega-panel, .mega-card__media, .mega-card__sub { transition: none; }
  .mega-card:hover .mega-card__media { transform: none; }
  /* No 3D turn under reduced motion (the script also declines to attach). */
  .mega-card--flip .mega-card__flip,
  .mega-card--flip .mega-card__video { transition: none; }
}

/* ===== Brand-logo slot — reusable logo band ==============================
   A fixed-HEIGHT band that seats a logo of ANY aspect ratio on a common
   baseline, so a row of mixed-width brand marks (a wide Flight Centre wordmark
   beside the taller Envoyage mark) reads as one even set. The height is
   reserved up-front and the band is full-width, so nothing reflows when the
   artwork loads — zero CLS.

   The band accepts any ONE of:
     • <img class="brand-logo__img" src="…" alt="…" loading="lazy" decoding="async">
     • <span class="brand-logo__wordmark">Brand<span class="dot">.</span></span>
     • <span class="brand-logo__ph">…icon + label…</span>   (dashed placeholder)
   Real logos scale to the band height via object-fit; SVG keeps them crisp at
   any DPI. */
.brand-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 52px;                        /* reserves vertical space → no CLS */
}
/* Shared optical bounding box: every logo scales to fit the SAME max-width /
   max-height, so a wide wordmark can't dominate a compact stacked mark. This
   balances perceived visual weight rather than matching literal dimensions;
   per-logo nudges below fine-tune it. Aspect ratio is always preserved. */
.brand-logo__img {
  width: auto;
  height: auto;
  max-width: 168px;
  max-height: 40px;
  object-fit: contain;
}
/* Per-logo optical nudges (±, by eye) to equalise perceived weight:
   - Flight Centre is a long single-line wordmark → let it run a touch wider.
   - FCIN is a compact two-line mark → hold it near the box height. */
.brand-logo--fc   .brand-logo__img { max-width: 164px; max-height: 30px; }
.brand-logo--fcin .brand-logo__img { max-width: 164px; max-height: 47px; }
/* Native wordmark (e.g. Traville) — real text in the brand display face, so it
   uses the page font and stays perfectly crisp; no font-in-SVG workaround. */
.brand-logo__wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 34px;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--teal);
  white-space: nowrap;
}
.brand-logo__wordmark .dot { color: var(--gold); }

/* Paired lockup (e.g. Traville + Envoyage): two marks side by side, optically
   balanced and vertically centred, reading as one unified branding element.
   In a pair the logo is height-scaled (not width-filling) so both sit level. */
.brand-logo--pair { gap: 66px; }
.brand-logo--pair .brand-logo__wordmark { font-size: 32px; }
/* Traville circular brand icon in the pair — a round mark sized to the band,
   sitting balanced beside the Envoyage chip. The webp is already circular
   (transparent corners); border-radius is a safety net. */
.brand-logo__circle {
  height: 130%;
  width: auto;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
}
/* Envoyage is a light-on-dark mark (white wordmark), so it can only be shown
   accurately on its dark ground. It sits on a navy chip that matches the brand
   reference, which also gives it visual weight to balance the Traville wordmark
   beside it. Height is a % of the band, so it scales and never overflows. */
.brand-logo__chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 44px;                        /* fixed, like the FC/FCIN caps → the */
  padding: 0 12px;                     /* optical balance holds at every breakpoint */
  background: #0B2233;
  border-radius: 8px;
  box-sizing: border-box;
}
.brand-logo__chip .brand-logo__img { width: auto; height: 38px; max-width: none; max-height: none; }

/* Dashed placeholder chrome — only rendered when no real logo is present. */
.brand-logo__ph {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  width: 100%;
  height: 100%;
  padding: 6px 14px;
  border: 1.5px dashed rgba(11, 110, 110, 0.28);
  border-radius: 10px;
  background: #F6F3EE;
  text-align: center;
  line-height: 1.2;
  box-sizing: border-box;
}
.brand-logo__icon { width: 22px; height: auto; color: rgba(11, 110, 110, 0.55); }
.brand-logo__label {
  font-family: var(--font-body);
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  color: #575757;                      /* AA on the neutral bg */
}
.brand-logo__meta {
  font-family: var(--font-body);
  font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: #6B6B6B;
}

@media (max-width: 900px) { .brand-logo { height: 48px; } .brand-logo__wordmark { font-size: 32px; } }
@media (max-width: 560px)  { .brand-logo { height: 44px; } .brand-logo__wordmark { font-size: 29px; } .brand-logo__meta { display: none; }
  .brand-logo--pair { gap: 52px; } .brand-logo--pair .brand-logo__wordmark { font-size: 25px; } }

/* ---------- "Go back" destination picker (quote pages) ----------
   Borrows the header dropdown's visual vocabulary — white panel, hairline
   border, 12px radius, teal-pale hover — but expands IN FLOW rather than as an
   absolute overlay, so it pushes the quote engine down instead of covering it.
   Generic classes: the same block can sit on any quote page. */
.dest-back { max-width: 640px; margin: 0 auto 34px; text-align: center; }
.dest-back__btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 24px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--white); color: var(--text);
  font-family: var(--font-body); font-size: 14px; font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,0.06);
  transition: color 0.24s ease, border-color 0.24s ease, box-shadow 0.24s ease, transform 0.24s ease;
}
.dest-back__btn:hover {
  color: var(--teal); border-color: rgba(11,110,110,0.45);
  box-shadow: 0 8px 22px rgba(11,110,110,0.16);
  transform: translateY(-1px);
}
.dest-back__btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
.dest-back__btn:active { transform: translateY(0); }
.dest-back__arw { font-size: 16px; line-height: 1; transition: transform 0.24s ease; }
.dest-back__btn:hover .dest-back__arw { transform: translateX(-3px); }
/* same caret construction as the header nav, so the two read as one system */
.dest-back__caret {
  width: 7px; height: 7px; margin-top: -3px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg); transition: transform 0.24s ease;
}
.dest-back.is-open .dest-back__caret { transform: rotate(-135deg); margin-top: 2px; }

/* max-height rather than grid-template-rows: universally supported, and if the
   transition is ever unsupported the panel simply appears rather than breaking. */
.dest-back__panel {
  max-height: 0; opacity: 0; visibility: hidden; overflow: hidden;
  transition: max-height 0.26s ease, opacity 0.22s ease, visibility 0.26s;
}
.dest-back.is-open .dest-back__panel { max-height: 480px; opacity: 1; visibility: visible; }
.dest-back__inner {
  margin-top: 14px; padding: 16px;
  border: 1px solid var(--border); border-radius: 14px;
  background: var(--white); box-shadow: var(--shadow-md);
}
.dest-back__hint {
  margin: 0 0 12px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted);
}
.dest-back__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
}
.dest-back__list a {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 14px; border-radius: 10px;
  font-size: 14px; font-weight: 500; color: var(--text);
  background: var(--sand);
  transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.dest-back__list a:hover { background: var(--teal-pale); color: var(--teal); transform: translateY(-1px); }
.dest-back__list a:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
/* Inline SVG, not an emoji glyph — Windows renders regional-indicator flag
   characters as bare letter pairs, so the emoji version showed "MU"/"TZ". */
.dest-back__flag { flex: none; display: block; width: 21px; height: 14px; }
.dest-back__flag svg { display: block; width: 100%; height: 100%; }

@media (max-width: 620px) {
  .dest-back { margin-bottom: 26px; }
  .dest-back__btn { width: 100%; justify-content: center; padding: 14px 20px; }
  .dest-back__list { grid-template-columns: repeat(2, 1fr); }
  .dest-back.is-open .dest-back__panel { max-height: 560px; }
}
@media (prefers-reduced-motion: reduce) {
  .dest-back__btn, .dest-back__arw, .dest-back__caret,
  .dest-back__panel, .dest-back__list a { transition: none; }
  .dest-back__btn:hover, .dest-back__list a:hover { transform: none; }
  .dest-back__btn:hover .dest-back__arw { transform: none; }
}

/* ---- Emergency Information: compact nav variant of .btn--emergency ----------
   Same ambulance-red + white-cross language as the full button on the Insurance
   page, scaled down to sit inside the bar. Deliberately NOT pulsing: the full
   button animates because it is a destination you have chosen to look at, but a
   permanent pulse in a sticky header on every page reads as noise rather than
   urgency — the red against nine neutral nav items is emphasis enough.
   Sized off the existing --header-h so it cannot change the header's height,
   which keeps it clear of any layout shift. */
   The selectors are scoped under .nav-emergency on purpose: the bar's own
   `.nav-links a` rules out-specify a bare `.btn--*` class and would repaint the
   label in the neutral nav colour (dark grey on red — about 2.8:1, an AA fail).
   The existing .nav-cta .btn--teal block above solves the same problem the same
   way. White on this red is ~4.9:1, which passes AA for this size and weight. */
.nav-emergency { margin-left: 4px; }
.nav-emergency .btn--emergency-nav {
  color: #ffffff;
  /* A touch deeper than the full button's #EF2B32 top stop. At this size the
     label is not "large text", so it needs the full 4.5:1 — #EF2B32 gives only
     4.15:1 against white. #DE1C24 -> #C50C18 measures 4.89:1 at the lightest
     point and 6.11:1 at the darkest, so every part of the sweep passes AA while
     staying the same red. */
  background: linear-gradient(180deg, #DE1C24 0%, #C50C18 100%);
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.01em;
  gap: 5px;
  animation: none;
  box-shadow: 0 3px 10px rgba(208, 16, 32, 0.26);
}
.nav-emergency .btn--emergency-nav:hover {
  color: #ffffff;
  box-shadow: 0 6px 18px rgba(208, 16, 32, 0.44);
}
/* Red-on-red would vanish, so the focus ring is white then deep red — visible
   against both the white header and the button itself. */
.nav-emergency .btn--emergency-nav:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px #ffffff, 0 0 0 5px #9B0A17;
}
.nav-emergency .btn__cross { width: 15px; height: 15px; border-radius: 4px; }
.nav-emergency .btn__cross svg { width: 10px; height: 10px; }
/* "SOS" — the prominent, compact label beside the white cross badge. */
.nav-emergency__label { letter-spacing: 0.08em; }

.nav-cta { margin-left: 4px; }
/* Primary nav CTA — bold white text + subtle depth so it reads as THE action.
   White (#fff) on --teal (#0B6E6E) ≈ 6:1 contrast → passes WCAG AA. */
.nav-cta .btn--teal {
  color: #ffffff;
  font-weight: 700;
  letter-spacing: 0.01em;
  box-shadow: 0 4px 14px rgba(11, 110, 110, 0.32);
}
.nav-cta .btn--teal:hover {
  color: #ffffff;
  box-shadow: 0 6px 18px rgba(11, 110, 110, 0.42);
}

/* hamburger */
.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 8px;
}
/* Injected into .nav-links by nav.js on every page; only shown once the drawer
   exists (mobile breakpoint below re-displays it). Hidden on desktop so it never
   appears in the horizontal nav. */
.nav-close { display: none; }
.nav-toggle span {
  width: 24px; height: 2px;
  background: var(--teal);
  border-radius: 2px;
  transition: transform 0.25s ease, opacity 0.25s ease;
}
body.nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
body.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
body.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* mobile drawer + overlay */
.nav-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.45);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s;
  z-index: 190;
}
body.nav-open .nav-overlay { opacity: 1; visibility: visible; }

/* Nav collapses to the hamburger at 1023px, not 900px. The bar carries eleven
   items and was already overflowing its container between about 900 and 950px
   before the Emergency button was added; adding a twelfth pushed that up to
   ~1023px. Rather than shrink items until they are unreadable, the menu now
   switches over exactly where the row stops fitting. Only the NAV moves — every
   other 900px breakpoint on the site is unchanged. */
@media (max-width: 1023px) {
  .nav-toggle { display: flex; }
  .nav-links {
    position: fixed;
    top: 0; right: 0;
    height: 100dvh;
    /* Compact by default: the drawer opens only wide enough for the widest
       top-level label, so a collapsed menu is a slim right-hand rail rather than
       a third of the screen. It widens (rule below) only when a dropdown or
       mega-menu is actually opened. Two fixed lengths are used, not an intrinsic
       max-content width, so the compact<->expanded change can animate smoothly.
       The vw cap guarantees it never provokes horizontal page scroll.
       184px hugs the widest top-level label ("Visa Information", ~120px) plus the
       24px side padding either side, trimming the dead space to its left without
       touching any font size, line-height or item spacing. */
    width: min(184px, 82vw);
    /* Frosted glass: the page behind shows through, softly blurred. The -webkit-
       prefix covers iOS Safari; a solid fallback lives in the @supports block at
       the end of this breakpoint so text stays readable where backdrop-filter is
       unsupported. */
    background: rgba(255, 255, 255, 0.55);
    -webkit-backdrop-filter: blur(20px) saturate(1.5);
    backdrop-filter: blur(20px) saturate(1.5);
    border-left: 1px solid rgba(255, 255, 255, 0.6);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    /* Extra top padding leaves a dedicated strip for the .nav-close pill, which
       sits below the sticky 70px header (see .nav-close). */
    padding: 128px 24px 40px;
    box-shadow: -14px 0 44px rgba(0,0,0,0.22);
    transform: translateX(100%);
    transition: transform 0.3s ease,
                width 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
    overflow-y: auto;
    z-index: 195;
  }
  body.nav-open .nav-links { transform: translateX(0); }
  /* Lighter scrim so the frosted drawer actually reveals the blurred page behind
     it (a heavy dark overlay would just read as grey through the glass). */
  .nav-overlay { background: rgba(10, 20, 20, 0.18); }
  /* Expand to fit the tile grid ONLY when a MEGA menu (Destinations / Online
     Quotes) is opened — NOT for the plain Offers accordion, which must expand its
     submenu vertically while the parent panel stays at the narrow default width.
     Driven by :has() (Safari 15.4+/all evergreens) with a JS-toggled class as a
     fallback for anything without :has() — nav.js keeps .has-open-panel in step.
     Because the drawer is position:fixed, this width change never reflows the
     page, and the vw cap keeps the widest state inside the viewport. */
  .nav-links:has(.has-mega.open),
  .nav-links.has-open-panel {
    width: min(360px, 94vw);
  }

  /* Minimise / close control — an obvious, labelled pill inside the drawer, in
     the site's teal language. The animated hamburger (top-right) still closes
     too; this is the discoverable control the brief asks for. Absolutely placed
     in the top strip, clear of the sticky header (z 200 > drawer 195) and of the
     right-aligned menu items. Injected by nav.js so every built page gets it. */
  .nav-close {
    position: absolute;
    top: 78px;
    right: 22px;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 16px 0 13px;
    background: var(--teal-pale);
    color: var(--teal);
    border: 1px solid rgba(11, 110, 110, 0.2);
    border-radius: var(--radius-pill);
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.02em;
    line-height: 1;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.2s ease, box-shadow 0.2s ease;
  }
  .nav-close:hover { background: #d9eded; }
  .nav-close:active { box-shadow: inset 0 1px 4px rgba(11, 110, 110, 0.18); }
  .nav-close:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
  .nav-close__x {
    position: relative;
    width: 15px; height: 15px;
    flex: 0 0 auto;
  }
  .nav-close__x::before,
  .nav-close__x::after {
    content: "";
    position: absolute;
    top: 50%; left: 0;
    width: 15px; height: 2px;
    background: currentColor;
    border-radius: 2px;
  }
  .nav-close__x::before { transform: translateY(-50%) rotate(45deg); }
  .nav-close__x::after  { transform: translateY(-50%) rotate(-45deg); }
  .nav-links > li { border-bottom: 1px solid var(--border); }
  /* All top-level items share one alignment: centred — plain links and the
     dropdown toggles (which are flex rows) both centre their label, so the whole
     list reads as one tidy centred column within the narrow panel. */
  .nav-links > li > a,
  .has-dropdown > .dropdown-toggle {
    display: block;
    width: 100%;
    padding: 14px 4px;
    font-size: 15px;
    text-align: center;
  }
  /* The toggle is a flex row so its label + caret stay together and sit centred,
     with the caret trailing the label (keeps the base 5px gap). */
  .has-dropdown > .dropdown-toggle {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .nav-cta { margin: 18px 0 0; }
  /* text-align:center overrides the generic right-aligned mobile-link rule so the
     full-width CTA reads centred, like a button rather than a menu link. */
  .nav-cta .btn { width: 100%; text-align: center; }
  /* Stacked menu — full width for a comfortable touch target. Shows the full
     [ cross ] SOS [ ambulance ] layout, centred. */
  .nav-emergency { margin: 18px 0 0; }
  .nav-emergency .btn--emergency-nav { width: 100%; justify-content: center; text-align: center; padding: 13px 18px; font-size: 14px; }

  /* mobile dropdown becomes accordion */
  .dropdown-menu {
    position: static;
    transform: none;
    opacity: 1;
    visibility: visible;
    box-shadow: none;
    border: 0;
    border-radius: 0;
    min-width: 0;
    padding: 0 0 8px;
    display: none;
  }
  .has-dropdown.open .dropdown-menu { display: block; }
  .has-dropdown:hover .dropdown-menu { transform: none; }
  .dropdown-menu li a { padding-left: 0; padding-right: 0; text-align: center; }
  /* Hover is unavailable on touch, so the Other Offers destination preview is
     shown inline whenever the Offers accordion is open (tap-expand), rather than
     on hover. Centred to match the rest of the mobile menu. */
  .offer-preview { max-height: none; opacity: 1; transform: none; padding: 0 4px; margin: 2px 0 8px; text-align: center; }

  /* Mega menu becomes an in-drawer accordion. Hover is meaningless on touch, so
     it opens on tap only — the :hover rule above would otherwise leave a panel
     stuck open after a tap. Cards keep their square media and hierarchy, so the
     mobile menu still reads as the same component. */
  .has-mega { position: relative; }
  .mega-panel {
    position: static;
    opacity: 1; visibility: visible; transform: none;
    transition: none; box-shadow: none; border: 0;
    display: none;
    /* The decorative layers (flight paths, teal halo) are a desktop treatment
       and would only muddy the list at this width, so they are cleared. The sand
       field stays but is made translucent + lightly blurred so it sits on the
       frosted drawer as its own soft-glass panel, framing the tiles without going
       fully opaque. (Solid-sand fallback in the @supports block below.) */
    background-image: none;
    background-color: rgba(245, 240, 232, 0.75);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border-radius: 12px;
    /* The drawer is the scroll container on mobile — a second one nested inside
       it would trap the gesture partway down the list. */
    max-height: none;
    overflow: visible;
  }
  /* Frosted-glass fallback: where backdrop-filter is unsupported, a translucent
     panel would leave text sitting on the un-blurred page — so revert the drawer
     and the mega panel to their solid surfaces. Everywhere modern, the glass wins. */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .nav-links { background: var(--white); }
    .mega-panel { background-color: var(--sand); }
  }
  .has-mega.open > .mega-panel { display: block; }
  .has-mega:hover > .mega-panel,
  .has-mega:focus-within > .mega-panel { display: none; }
  .has-mega.open:hover > .mega-panel,
  .has-mega.open:focus-within > .mega-panel { display: block; }
  /* The grid carries the horizontal inset, so the inner only adds the vertical
     breathing room; together they frame the tiles in sand on all four sides.
     The margin keeps the panel clear of the drawer's own list rule. */
  .mega-panel__inner { padding: 4px 0 4px; }
  .has-mega.open > .mega-panel { margin: 2px 0 12px; }
  .mega-panel__intro { display: none; }
  .mega-grid { grid-template-columns: repeat(2, 1fr); gap: 14px 12px; padding: 12px 14px 14px; }
  /* radius intentionally not reduced here — it must stay at --radius-card so the
     accent rule is clipped identically to the quote cards at every breakpoint */
  .mega-card__sub { font-size: 11.5px; }
  .mega-card:hover .mega-card__media { transform: none; }

  /* The fixed 190px track would overflow the drawer, so columns go fluid here.
     A solo tile spans the drawer width — width:100% (not auto) is load-bearing:
     as a query container an auto-width, column-spanning grid item collapses to
     zero under inline-size containment, which would zero its cqi-sized label. */
  .mega-item--solo { width: 100%; margin-bottom: 2px; }
  /* Two-column mobile grid: let the pair flow normally (it forms its own centred
     final row) rather than forcing desktop columns that don't exist here. */
  .mega-item--pair-l, .mega-item--pair-r { grid-column: auto; }
  /* Same for the secondary offer cards: drop the desktop row/column placement so
     each offer simply follows its engine in the stacked/2-col flow. */
  .mega-item--secondary, .mega-item--col1, .mega-item--col4 { grid-column: auto; grid-row: auto; }

  /* Mobile-ONLY staggered tile layout for the Online Quotes panel (desktop grid
     untouched). Same 2-column grid and the SAME .mega-card tiles as the
     Destinations panel — no separate sizing system — placed explicitly so the
     composition reads as an intentional stagger rather than a single column:

        row 1:   .                 |  All Online Quotes   (primary, far right)
        row 2:   Beachcomber Live  |  Beachcomber Offers
        row 3:   Live Package      |  Holiday Offers
        row 4:   Europamundo       |  .
        row 5:   Travel Insurance  |  .

     DOM order (built): 1 All / 2 BeachLive / 3 BeachOffers / 4 Europamundo /
     5 Insurance / 6 LivePackage / 7 HolidayOffers. The #id specificity here beats
     the ≤520px single-column rule below, so the stagger holds on the smallest
     phones too. All links/hrefs are untouched — this is placement only. */
  #mega-quotes .mega-grid { grid-template-columns: repeat(2, 1fr); }
  /* All Online Quotes is no longer a full-width hero on mobile: it takes the
     top-right cell as the primary tile (overrides the base solo full-width). */
  #mega-quotes .mega-item--solo { width: auto; margin: 0; }
  #mega-quotes .mega-item:nth-child(1) { grid-column: 2; grid-row: 1; } /* All → top right */
  #mega-quotes .mega-item:nth-child(2) { grid-column: 1; grid-row: 2; } /* Beachcomber Live */
  #mega-quotes .mega-item:nth-child(3) { grid-column: 2; grid-row: 2; } /* Beachcomber Offers */
  #mega-quotes .mega-item:nth-child(6) { grid-column: 1; grid-row: 3; } /* Live Package Pricing */
  #mega-quotes .mega-item:nth-child(7) { grid-column: 2; grid-row: 3; } /* Holiday Offers */
  /* Europamundo + Travel Insurance share ONE far-left-starting row (was two sparse
     single-tile rows) so the open menu is shorter — Europamundo hard left. */
  #mega-quotes .mega-item:nth-child(4) { grid-column: 1; grid-row: 4; } /* Europamundo */
  #mega-quotes .mega-item:nth-child(5) { grid-column: 2; grid-row: 4; } /* Travel Insurance */
}

/* Phones: the five quote tiles stack one per row. The destinations panel keeps
   two columns — nine cards in a single column would be a long scroll. */
@media (max-width: 520px) {
  .mega-panel--stack .mega-grid { grid-template-columns: 1fr; }
}

/* ---------- Cards (generic) ---------- */
.card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }

.card__media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}
.card:hover .card__media img { transform: scale(1.05); }
.card__body { padding: 22px; }

.pill {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
}
.pill--gold { background: var(--gold); color: #2a2208; }
.pill--teal { background: var(--teal-pale); color: var(--teal); }
.pill--ghost { background: rgba(255,255,255,0.9); color: var(--teal); }

.label-gold {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--gold);
}

.card-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 24px;
  color: var(--teal);
  margin: 8px 0;
}

.price-from {
  font-size: 13px;
  color: var(--muted);
}
.price-from strong {
  font-size: 17px;
  color: var(--gold);
}

/* ---------- Forms ---------- */
.form-card {
  background: var(--white);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg);
  padding: 30px;
}
.form-card h3 { color: var(--teal); margin-bottom: 4px; }
.form-card .form-sub { font-size: 13px; color: var(--muted); margin-bottom: 18px; }

.field { margin-bottom: 16px; }
.field label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.02em;
  margin-bottom: 6px;
}
.field .req { color: var(--gold); }

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--white);
  font-size: 16px;   /* 16px on every breakpoint: consistent, modern, and no iOS zoom */
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--teal);
  box-shadow: 0 0 0 3px rgba(11,110,110,0.12);
}
.field textarea { resize: vertical; min-height: 110px; }

.field--error input,
.field--error select,
.field--error textarea { border-color: #c0392b; }
.field .error-msg {
  display: none;
  font-size: 12px;
  color: #c0392b;
  margin-top: 5px;
}
.field--error .error-msg { display: block; }

.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

.form-note { font-size: 12px; color: var(--muted); margin-top: 12px; }

/* Segmented toggle (Flights included / Land only, Yes / No) */
.field-label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.02em;
  margin-bottom: 6px;
}
.seg-toggle {
  display: flex;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--white);
}
.seg-toggle input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}
.seg-toggle label {
  flex: 1;
  margin: 0;
  text-align: center;
  padding: 9px 12px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.seg-toggle input:checked + label { background: var(--teal); color: #fff; }
.seg-toggle input:focus-visible + label { box-shadow: 0 0 0 3px rgba(11,110,110,0.25); }

/* ---- Top-level journey switch: New Quote vs Existing Quote ---- */
.form-switch {
  display: grid;
  /* auto-fit rather than a fixed 1fr 1fr: the tab count follows the markup, so
     adding a fourth enquiry type later needs no CSS change. */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 5px;
  padding: 6px;
  background: var(--teal-pale);
  border-radius: var(--radius-pill);
  margin-bottom: 26px;
}
/* three tabs will not sit on one line on a phone — stack them into a column,
   keeping the pill shape rather than crushing the labels */
@media (max-width: 620px) {
  .form-switch { grid-template-columns: 1fr; border-radius: 18px; }
  .form-switch__btn { border-radius: 14px; }
}
.form-switch__btn {
  appearance: none;
  border: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--teal);
  background: transparent;
  padding: 15px 14px;
  border-radius: var(--radius-pill);
  transition: background 0.25s ease, color 0.25s ease, box-shadow 0.25s ease;
}
.form-switch__btn.is-active { background: var(--teal); color: #fff; box-shadow: var(--shadow-sm); }
.form-switch__btn:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(11,110,110,0.28); }

/* ---- Multi-select pills (newsletter preferences) ----
   Checkboxes styled as tappable pills. Same visual grammar as .seg-toggle, but
   they wrap and allow many selections rather than being one-of-N. */
.pill-hint { font-size: 12.5px; color: var(--muted); margin: 0 0 8px; }
.field-optional {
  font-size: 11px; font-weight: 500; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--muted); margin-left: 6px;
}
.pill-set { display: flex; flex-wrap: wrap; gap: 8px; }
.pill-set input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.pill-set label {
  margin: 0;
  cursor: pointer;
  padding: 9px 15px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--white);
  font-size: 13px; font-weight: 600; color: var(--text);
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.pill-set label:hover { border-color: rgba(11,110,110,0.45); }
.pill-set input:checked + label {
  background: var(--teal); border-color: var(--teal); color: #fff;
}
.pill-set input:focus-visible + label { box-shadow: 0 0 0 3px rgba(11,110,110,0.25); }

/* consent: a real checkbox, left-aligned with the label beside it */
.consent-field {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 14px 16px;
  background: var(--cream, #FBF8F1);
  border: 1px solid var(--border);
  border-radius: 12px;
}
.consent-field input {
  flex: 0 0 auto; width: 18px; height: 18px; margin-top: 1px;
  accent-color: var(--teal); cursor: pointer;
}
.consent-field label {
  margin: 0; cursor: pointer;
  font-size: 13.5px; line-height: 1.55; color: var(--text); font-weight: 400;
}
/* the gate disables submit until consent is ticked — say why, not just that */
.form-panel button[type="submit"]:disabled { opacity: 0.5; cursor: not-allowed; }

.form-panel[hidden] { display: none; }
.form-panel.is-active { animation: formPanelFade 0.32s ease; }
@keyframes formPanelFade {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (max-width: 400px) { .form-switch__btn { font-size: 13.5px; padding: 13px 8px; } }

/* ---- Quote pathways: each tab routes to an external Travefy form via clear
   CTAs rather than an embedded form. ONE uniform paragraph style keeps the
   three tabs typographically consistent; stacked buttons get an even gap. ---- */
.quote-pathway p { font-size: 15px; line-height: 1.7; color: var(--text); margin: 0 0 14px; }
.quote-pathway .pathway-note { font-size: 13px; line-height: 1.6; color: var(--muted); margin: 14px 0 0; }
.quote-pathway .btn--block { margin-top: 10px; }
.quote-pathway .btn--block + .btn--block { margin-top: 12px; }
/* External-link buttons carry a small, centred "opens in a new tab" caption
   directly beneath them instead of inside the label. It lives outside the <a>,
   so it never intrudes on the tap target; ~half the 14px button text, muted and
   uppercase so it reads as a quiet, secondary note. When another button follows,
   the caption's sibling rule restores a clear gap before it. */
.quote-pathway .btn-note {
  display: block; text-align: center;
  font-size: 0.5rem; line-height: 1.3; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
  margin: 6px 0 0;
}
.quote-pathway .btn-note + .btn--block { margin-top: 16px; }

/* Currency-prefixed input (budget) */
.input-prefix { position: relative; }
.input-prefix .prefix {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  font-weight: 600;
  pointer-events: none;
}
.input-prefix input { padding-left: 28px; }

/* Character counter for comment fields */
.char-count {
  display: block;
  text-align: right;
  font-size: 12px;
  color: var(--muted);
  margin-top: 5px;
}
.char-count.is-limit .char-now { color: #c0392b; font-weight: 600; }

.form-status {
  display: none;
  margin-top: 14px;
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 14px;
}
.form-status.is-success { display: block; background: var(--teal-pale); color: var(--teal); }
.form-status.is-error   { display: block; background: #fdecea; color: #c0392b; }

@media (max-width: 600px) {
  .form-row { grid-template-columns: 1fr; }
}

/* ---------- Notice / disclaimer callout ---------- */
.notice {
  background: var(--teal-pale);
  border-left: 4px solid var(--gold);
  border-radius: 12px;
  padding: 22px 24px;
}
.notice h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 16px;
  color: var(--teal);
  margin-bottom: 8px;
}
.notice p { font-size: 14px; color: var(--text); }
.notice p + p { margin-top: 10px; }

/* Destination visa block — a centred component: one prominent line of copy, then
   every button as one cohesive, centred group. The base .notice class also picks
   up an unrelated icon-notice rule in pages.css (display:flex, row); the
   two-class .notice.notice--visa selector outranks it so this block lays out as a
   clean centred column instead of a squeezed row. */
.notice.notice--visa {
  display: block;
  max-width: 760px; margin: 0 auto;
  text-align: center;
}
.notice--visa .notice__lead {
  font-size: 16.5px; line-height: 1.55; font-weight: 600;
  color: var(--teal); text-align: center;
  margin: 0 auto 22px; max-width: 60ch;
}
/* One cohesive, centred button group: buttons share a flex basis so they sit at
   equal widths in a balanced row on desktop, and wrap to a tidy 2-up on phones
   rather than an awkward run of full-width single rows. */
.notice--visa .notice__actions {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 12px;
}
.notice--visa .notice__actions .btn { flex: 1 1 190px; max-width: 280px; text-align: center; }
@media (max-width: 560px) {
  .notice--visa .notice__actions .btn { flex-basis: calc(50% - 6px); max-width: none; }
}

/* ---------- Information callout — a cohesive light teal-blue notice ----------
   One box: an uppercase label sits above the explanatory copy, which flows as a
   single well-structured block. Brand teal-pale ground with a teal accent edge,
   centred and width-limited for comfortable reading. Reusable site-wide. */
.info-callout {
  max-width: 780px;
  margin: 0 auto;
  background: var(--teal-pale);
  border: 1px solid rgba(11, 110, 110, 0.16);
  border-left: 4px solid var(--teal);
  border-radius: var(--radius-card);
  padding: 26px 30px;
  box-shadow: 0 10px 30px rgba(11, 110, 110, 0.08);
}
.info-callout__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.info-callout__icon { flex: none; width: 24px; height: 24px; color: var(--teal); }
.info-callout__icon svg { width: 100%; height: 100%; display: block; }
.info-callout__title {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--teal);
}
.info-callout__heading {
  margin: 0 0 10px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.3;
  color: var(--teal);
}
.info-callout__body p { margin: 0 0 14px; font-size: 15px; line-height: 1.75; color: var(--text); }
.info-callout__body p:last-child { margin-bottom: 0; }
.info-callout__body strong { color: var(--teal); font-weight: 700; }
/* A disclaimer pulled out of the running text and set on its own line, for the
   one statement in a callout that is a hard limitation rather than guidance.
   Built entirely from this component's existing vocabulary — the same teal, the
   same border colour as the callout's own edge, the same body face — so it
   reads as emphasis within the design rather than a new kind of box. Weight and
   the pair of hairlines carry the emphasis; the font size is deliberately left
   alone so it still sits in the same reading rhythm, and so the 620px rule
   below continues to govern it like every other line. Needs the p in the
   selector to match .info-callout__body p on specificity. */
.info-callout__body p.info-callout__flag {
  margin: 16px 0;
  padding: 14px 0;
  border-top: 1px solid rgba(11, 110, 110, 0.18);
  border-bottom: 1px solid rgba(11, 110, 110, 0.18);
  font-weight: 700;
  color: var(--teal);
}
@media (max-width: 620px) {
  .info-callout { padding: 22px 20px; border-radius: 14px; }
  .info-callout__title { font-size: 12px; letter-spacing: 0.08em; }
  .info-callout__heading {
  margin: 0 0 10px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.3;
  color: var(--teal);
}
.info-callout__body p { font-size: 14.5px; }
}

/* ---------- Comparison table ---------- */
.compare-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  -webkit-overflow-scrolling: touch;
}
.compare-table {
  width: 100%;
  border-collapse: collapse;
  min-width: 640px;
}
.compare-table th,
.compare-table td {
  text-align: left;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
  vertical-align: top;
}
.compare-table thead th {
  background: var(--teal-pale);
  color: var(--teal);
  font-weight: 600;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.compare-table tbody tr:last-child td { border-bottom: 0; }
.compare-table td:first-child,
.compare-table th:first-child { font-weight: 600; color: var(--text); }
.compare-table .muted-cell { color: var(--muted); }

/* ---------- Integration placeholders ---------- */
.placeholder-embed {
  border: 2px dashed var(--teal);
  border-radius: var(--radius-card);
  background: var(--teal-pale);
  color: var(--teal);
  text-align: center;
  padding: 48px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 180px;
}
.placeholder-embed strong { font-size: 15px; font-weight: 600; }
.placeholder-embed small { font-size: 12px; color: var(--muted); max-width: 460px; }
.placeholder-embed.dark {
  border-color: rgba(196,154,60,0.6);
  background: rgba(255,255,255,0.04);
  color: var(--gold-light);
}
.placeholder-embed.dark small { color: #9a9a9a; }

/* ---------- Embedded quote/booking engine (iframe) ---------- */
.engine-embed {
  width: 100%;
  border-radius: var(--radius-card);
  overflow: hidden;
  box-shadow: var(--shadow-md);
  background: #fff;
}
.engine-embed iframe { display: block; width: 100%; height: 900px; border: 0; }
@media (max-width: 600px) { .engine-embed iframe { height: 860px; } }

.engine-section--full { overflow-x: hidden; }

/* Flush variant — no card chrome whatsoever. The engine sits directly on the
   white section at the same content width as every other block on the page, so
   it reads as the page's own search rather than third-party content sitting in
   a box. A card outline is precisely what signals "embedded widget".

   Deliberately NOT full browser width. Measured: the engine sets no internal
   max-width, so at a 1900px viewport its own controls spread across 1885px —
   a long eye travel between fields and a form that stops reading as one unit.
   Sharing the page's 1200px grid integrates it better than stretching does,
   because it then aligns with the heading and trust panel above and below. */
.engine-embed--flush {
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: #fff;
}
/* Height: never below the known-good fixed height, but allowed to grow into a
   tall viewport so less of the engine's own content is scrolled internally.
   The plain height is the fallback for anything without dvh support. */
.engine-embed--flush iframe { height: 900px; height: max(900px, calc(100dvh - 140px)); }
@media (max-width: 900px) {
  .engine-embed--flush iframe { height: 1050px; height: max(1050px, calc(100dvh - 120px)); }
}
@media (max-width: 600px) {
  .engine-embed--flush iframe { height: 1250px; height: max(1250px, calc(100dvh - 96px)); }
}

/* The engine is the page's primary content, so its section leads in tightly
   rather than carrying a full 84px band above it. */
.engine-section--lead { padding-top: 52px; }
.engine-section--lead .section-head { margin-bottom: 26px; }

/* Branded loading state. The iframe's load event fires cross-origin, so this is
   driven by the real event rather than a guessed delay — with a failsafe in
   engine-loader.js so a blocked supplier can never leave the cover in place. */
.engine-embed { position: relative; }
.engine-loader {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  background: #fff;
  transition: opacity 0.45s ease, visibility 0.45s ease;
}
/* pointer-events is the load-bearing one. opacity and visibility are animated,
   and an interrupted transition would leave an invisible sheet sitting over the
   engine swallowing every click on the search form — a fault that looks like
   nothing at all on screen. This makes that impossible regardless of the
   transition's state. */
.engine-embed.is-loaded .engine-loader { opacity: 0; visibility: hidden; pointer-events: none; }
.engine-loader__spinner {
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 3px solid var(--teal-pale);
  border-top-color: var(--teal);
  animation: engineSpin 0.9s linear infinite;
}
@keyframes engineSpin { to { transform: rotate(360deg); } }
.engine-loader__text {
  margin: 0;
  font-size: 13.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
}
@media (prefers-reduced-motion: reduce) {
  .engine-loader__spinner { animation-duration: 2.6s; }
}

/* Auto-height embedded engine — iframe grows via the supplier's own resizer script */
.engine-frame {
  background: #fff;
  border-radius: var(--radius-card);
  overflow: hidden;
  box-shadow: var(--shadow-md);
  max-width: 1000px;
  margin: 0 auto;
}
.engine-frame iframe { display: block; width: 100%; border: 0; min-height: 420px; }

/* Full-width variant — the engine fills the whole content column instead of a boxed
   1000px card; the supplier iframe carries its own white background (Europamundo page) */
.engine-frame--wide {
  max-width: none;
  margin-inline: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}

/* ---------- Trust / reassurance panel (confidence, not disclaimer) ---------- */
.trust-panel {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  max-width: 860px;
  margin: 30px auto 0;
  padding: 24px 28px;
  background: var(--teal-pale);
  border: 1px solid rgba(11, 110, 110, 0.18);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
}
.trust-panel__icon {
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  color: var(--teal);
  box-shadow: var(--shadow-sm);
}
.trust-panel__icon svg { width: 24px; height: 24px; }
.trust-panel h3 {
  font-family: var(--font-display);
  font-size: 20px;
  margin: 2px 0 7px;
  color: var(--text);
}
.trust-panel p { margin: 0; color: var(--text); font-size: 14.5px; line-height: 1.65; }
.trust-panel p + p { margin-top: 12px; }
.trust-panel ul { list-style: none; margin: 10px 0 0; padding: 0; }
.trust-panel ul li { position: relative; padding-left: 20px; margin: 6px 0; font-size: 14px; line-height: 1.55; color: var(--text); }
.trust-panel ul li::before { content: ""; position: absolute; left: 2px; top: 8px; width: 7px; height: 7px; border-radius: 50%; background: var(--gold); }
.trust-panel ul + p { margin-top: 12px; }
.trust-panel a { color: var(--teal); font-weight: 600; white-space: nowrap; }
@media (max-width: 620px) {
  .trust-panel { flex-direction: column; gap: 14px; padding: 20px; }
}

/* ---------- WhatsApp float ---------- */
.wa-float {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 999;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: var(--green-wa);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 24px rgba(37,211,102,0.45);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.wa-float:hover { transform: scale(1.08); color: #fff; }
/* Keep the floating WhatsApp button (z-index 999) from covering the open mobile
   menu and its CTAs — fade it out while the drawer is open. */
body.nav-open .wa-float { opacity: 0; visibility: hidden; pointer-events: none; }
.wa-float svg { width: 30px; height: 30px; }
.wa-float .wa-tip {
  position: absolute;
  right: calc(100% + 14px);
  top: 50%;
  transform: translateY(-50%) translateX(8px);
  background: var(--charcoal);
  color: #fff;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  padding: 8px 13px;
  border-radius: 9px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  box-shadow: var(--shadow-md);
}
.wa-float:hover .wa-tip { opacity: 1; visibility: visible; transform: translateY(-50%) translateX(0); }
@media (max-width: 600px) {
  .wa-float { width: 54px; height: 54px; right: 16px; bottom: 16px; }
  .wa-float svg { width: 28px; height: 28px; }
  .wa-float .wa-tip { display: none; }
}

/* ---------- Cookie consent (POPIA / GDPR) ---------- */
.cookie-consent {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1000;
  background: var(--white); border-top: 1px solid var(--border);
  box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.12);
}
.cookie-consent[hidden] { display: none; }
.cookie-consent__inner {
  max-width: 1160px; margin: 0 auto; padding: 15px 20px;
  display: flex; align-items: center; gap: 12px 24px; flex-wrap: wrap;
}
.cookie-consent__text {
  margin: 0; flex: 1 1 340px;
  font-size: 13.5px; line-height: 1.55; color: var(--text);
}
.cookie-consent__text a { color: var(--teal); text-underline-offset: 2px; }
.cookie-consent__actions { display: flex; gap: 10px; flex: 0 0 auto; margin-left: auto; }
.cookie-consent__btn {
  font-family: inherit; font-size: 14px; font-weight: 600; line-height: 1;
  padding: 11px 22px; border-radius: 999px; cursor: pointer;
  border: 1.5px solid transparent;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.cookie-consent__btn--accept { background: var(--teal); color: #fff; border-color: var(--teal); }
.cookie-consent__btn--accept:hover { background: #095a5a; border-color: #095a5a; }
.cookie-consent__btn--decline { background: transparent; color: var(--text); border-color: rgba(0, 0, 0, 0.18); }
.cookie-consent__btn--decline:hover { background: var(--sand); }
.cookie-consent__btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
/* Lift the WhatsApp float clear of the banner while it is showing. */
.consent-open .wa-float { bottom: 92px; }
@media (prefers-reduced-motion: no-preference) {
  .cookie-consent:not([hidden]) { animation: consent-rise 0.38s cubic-bezier(0.2, 0.7, 0.2, 1); }
  @keyframes consent-rise { from { transform: translateY(100%); } to { transform: none; } }
}
@media (max-width: 640px) {
  .cookie-consent__inner { padding: 14px 16px; gap: 12px; }
  .cookie-consent__actions { width: 100%; margin-left: 0; }
  .cookie-consent__btn { flex: 1; padding: 12px 16px; }
  .consent-open .wa-float { bottom: 188px; }
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--charcoal);
  color: #b6b6b6;
}

/* ---- Lead capture band --------------------------------------------------
   Sits above the footer proper on a lighter charcoal, so it reads as its own
   invitation rather than another footer row. Reserved for a signup form. */
.footer-cta {
  background: #232323;
  border-bottom: 1px solid rgba(255,255,255,0.07);
  padding: var(--band-py-sm) 0;   /* #7 compact-band token (40 desktop / 34 phone) */
}
.footer-cta__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
}
.footer-cta h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 30px;
  line-height: 1.2;
  color: #fff;
  margin: 0 0 8px;
}
.footer-cta h2 em { font-style: italic; color: var(--gold-light); }
.footer-cta p { font-size: 14px; line-height: 1.6; color: #a4a4a4; margin: 0; max-width: 52ch; }
.footer-cta__form { flex: 0 0 auto; }

/* ---- Trusted partners ---------------------------------------------------
   Placeholder plates now, logo images later: give .trust-logo an <img> and the
   grid keeps its sizing. auto-fit means the row count follows the logo count,
   so adding a tenth partner needs no CSS change. */
.footer-trust { padding: var(--band-py-sm) 0 4px; }   /* #7 compact-band token top */
.footer-trust__title {
  font-family: var(--font-body);
  font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--gold-light);
  text-align: center;
  /* Sits directly above the scrolling logo bar (the intro note was removed),
     so this bottom margin is the whole heading-to-marquee gap. */
  margin: 0 0 18px;
}
.trust-grid {
  list-style: none; margin: 0; padding: 0;
  /* A centred flex wrap holds any number of partners: tiles keep a fixed width
     and a partial last row centres itself, so adding or removing a brand never
     strands a lone logo the way a fixed grid would. */
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 14px;
}
.trust-logo {
  display: flex; align-items: center; justify-content: center;
  flex: 0 1 200px; box-sizing: border-box;
  min-height: 52px;
  padding: 6px 12px;
  /* Tile ARCHITECTURE only — the equal width + row height keep the group aligned
     and responsive. The card TREATMENT (border, background, radius, shadow, heavy
     padding) is intentionally removed so the logos float cleanly on the footer.
     Hover feedback lives on the logo/wordmark itself, not the tile. */
}
.trust-logo span {
  font-size: 12px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: #8f8f8f; text-align: center;
  line-height: 1.35;
  transition: color 0.25s ease;
}
.trust-logo:hover span { color: #d8d8d8; }
/* Real brand logos arrive in every colour under the sun; on a dark footer that
   reads as clutter. Render them as one muted-white silhouette (brightness(0)
   flattens to black, invert(1) flips to white), sized by height so a square
   emblem and a wide wordmark carry equal weight. Colour returns on hover. */
.trust-logo img {
  max-height: 30px; max-width: 118px; height: auto; width: auto;
  object-fit: contain; display: block;
}
.trust-logo--img img {
  filter: brightness(0) invert(1);
  opacity: 0.60;
  transition: opacity 0.25s ease;
}
.trust-logo--img:hover img { opacity: 0.95; }

/* ---- Logo marquee -------------------------------------------------------
   One seamless, infinitely-looping row. The partner set is rendered TWICE in
   .trust-track; translating the track exactly -50% lands copy 2 where copy 1
   began, so there is no visible jump on loop. Per-item margin-right (not flex
   gap) keeps that -50% mathematically exact. Edge masks fade logos in/out;
   hover pauses; reduced-motion falls back to a static centred wrap. */
.trust-marquee {
  overflow: hidden; width: 100%; padding: 6px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}
.trust-track {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; width: max-content;
  animation: trust-marquee 44s linear infinite;
  will-change: transform;
}
/* Ink-edge spacing: each logo shrinks to its own visible width and a single
   uniform margin sets the gap, so the VISIBLE gap between adjacent logos stays
   constant (assets are tight-cropped) — no equal-width containers, no internal
   padding. The uniform margin-right also keeps the -50% loop exact. */
.trust-track .trust-logo {
  flex: 0 0 auto; box-sizing: border-box;
  min-height: 0; margin: 0 46px 0 0; padding: 0;
  justify-content: center;
}
@media (max-width: 700px) { .trust-track .trust-logo { margin-right: 34px; } }
/* Optical compensation: the sparse "in-between" marks (World Leisure Holidays'
   emblem + small stacked text, and Flight Centre's two-line lock-up) leave more
   apparent air, so the flanking transitions LOOK wider than the uniform gap even
   though they measure identically. Trim the margin on those two marks and the
   one before each, so the Holiday Factory->…->Thompsons and Santam->…->Emirates
   runs read at the same rhythm. Applied to both copies, so the loop stays exact. */
.trust-track .trust-logo--the-holiday-factory,
.trust-track .trust-logo--world-leisure-holidays,
.trust-track .trust-logo--santam,
.trust-track .trust-logo--flight-centre-travel-group { margin-right: 30px; }
@media (max-width: 700px) {
  .trust-track .trust-logo--the-holiday-factory,
  .trust-track .trust-logo--world-leisure-holidays,
  .trust-track .trust-logo--santam,
  .trust-track .trust-logo--flight-centre-travel-group { margin-right: 22px; }
}

/* Universal optical scale: a shared ~30px cap-height with a width cap so very
   wide marks don't dominate, plus a few individual tweaks (never distorting a
   logo) so compact and dense marks carry the same visual weight as the rest. */
.trust-track .trust-logo img { max-height: 30px; max-width: 112px; width: auto; height: auto; }
.trust-track .trust-logo--emirates img { max-height: 37px; }                                    /* small/narrow -> more presence */
.trust-track .trust-logo--turkish-airlines img { max-height: 36px; }                             /* roundel+wordmark -> match Emirates' optical height */
.trust-track .trust-logo--santam img { max-height: 28px; }                                      /* dense mark -> slightly smaller */
.trust-track .trust-logo--beachcomber img { max-height: 32px; }                                 /* sparse/wide -> a touch more */

/* Universal perceived brightness: every mark whitens to the same white, but
   sparse/delicate logos read fainter and dense ones stronger — so opacity is
   tuned per logo to equalise APPARENT intensity rather than one flat value. */
.trust-track .trust-logo--img img { opacity: 0.66; }
.trust-track .trust-logo--beachcomber img { opacity: 0.88; }
.trust-track .trust-logo--emirates img { opacity: 0.72; }
.trust-track .trust-logo--turkish-airlines img { opacity: 0.72; }                               /* match Emirates' ink weight */
.trust-track .trust-logo--santam img { opacity: 0.56; }
.trust-track .trust-logo--img:hover img { opacity: 0.96; }

/* Wordmark placeholders sized/toned to read as peers among the graphic logos. */
.trust-track .trust-logo span { white-space: nowrap; font-size: 11.5px; font-weight: 500; letter-spacing: 0.06em; color: #9a9a9a; }
/* The two long wordmarks read wider than the graphic marks; a slightly smaller
   size brings their footprint into line (ink-edge spacing then self-corrects). */
.trust-track .trust-logo--the-holiday-factory span,
.trust-track .trust-logo--thompsons-holidays span { font-size: 10px; letter-spacing: 0.03em; }
/* Flight Centre Travel Group — typeset as a compact stacked wordmark: "Flight
   Centre" over an indented "Travel Group" (the second line begins under the
   "Centre" of the first, T roughly under C). Stacking lets the type be larger
   while the two-line block still holds a footprint in line with its neighbours.
   A hair brighter than the single-line wordmarks for legibility, still subtle. */
.trust-track .trust-logo--flight-centre-travel-group span.is-stacked {
  display: inline-flex; flex-direction: column; align-items: flex-start;
}
.trust-track .trust-logo--flight-centre-travel-group span.is-stacked > span {
  font-size: 10.5px; letter-spacing: 0.02em; line-height: 1.18;
  color: #b0b0b0; white-space: nowrap;
}
.trust-track .trust-logo--flight-centre-travel-group span.is-stacked > span:last-child {
  padding-left: 3.95em;   /* start "Travel" (T) beneath the "C" of Centre */
}
/* Track "Travel" out a hair so its last letter (L) lines up under the last
   letter of "Centre" (E) — Travel then spans exactly the width of Centre. */
.trust-track .trust-logo--flight-centre-travel-group span.is-stacked .fctg-tv { letter-spacing: 0.03em; }
@keyframes trust-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.trust-marquee:hover .trust-track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .trust-marquee { -webkit-mask-image: none; mask-image: none; }
  .trust-track { animation: none; flex-wrap: wrap; justify-content: center; width: auto; row-gap: 20px; }
  .trust-track .trust-logo { margin: 0 28px; }
  .trust-track .trust-logo[aria-hidden="true"] { display: none; }
}

/* Lower footer zone — the sitemap, Explore links and Traville info sit on the
   same soft grey as the "Travel ideas" band, giving a clean colour transition
   that separates them from the brand/logo marquee above. Full-width; content
   stays centred in the container. Understated break, not a heavy divider. */
.footer-lower {
  background: #232323;
  border-top: 1px solid rgba(255,255,255,0.06);
  margin-top: 30px;
  padding-top: var(--band-py-sm);   /* #7 compact-band token */
}
.footer-grid {
  display: grid;
  /* Two columns, not four: the three sitemap columns collapsed into one list of
     the nine primary destinations, so the brand block gets the room instead. */
  grid-template-columns: 1.7fr 1fr;
  gap: 56px;
  padding: 54px 0 48px;
}
.footer-grid h3 {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--gold-light);
  margin-bottom: 18px;
}
.footer-brand .brand { color: #fff; font-size: 26px; }
.footer-brand p { font-size: 14px; color: #9a9a9a; margin-top: 12px; max-width: 280px; }
.footer-brand address { font-style: normal; font-size: 14px; line-height: 1.85; color: #9a9a9a; margin-top: 16px; }
.footer-brand address strong { color: #d8d8d8; font-weight: 600; }
.footer-brand address a { color: #b6b6b6; }
.footer-brand address a:hover { color: var(--gold-light); }
/* the nine primary links in two columns, so the block stays short */
.footer-nav ul { columns: 2; column-gap: 26px; }
.footer-nav ul li { break-inside: avoid; }

.footer-grid ul li { margin-bottom: 10px; }
.footer-grid ul li a { font-size: 14px; color: #b6b6b6; }
.footer-grid ul li a:hover { color: var(--gold-light); }

.footer-social { display: flex; gap: 12px; margin-top: 18px; }
.footer-social a {
  width: 38px; height: 38px;
  border-radius: 50%;
  background: rgba(255,255,255,0.08);
  display: flex; align-items: center; justify-content: center;
  color: #ddd;
}
.footer-social a:hover { background: var(--teal); color: #fff; }
.footer-social svg { width: 18px; height: 18px; }

/* ===== Social media icons — official brand app-icons, consistent everywhere ===== */
.social-ico { display: block; width: 100%; height: 100%; }
/* Topbar: brand icons in place of the old "Instagram" / "Facebook" text */
/* 24x24 hit area around an 18px glyph. WCAG 2.2 AA (2.5.8 Target Size) sets a
   24x24 minimum and these were exactly 18x18. The icon is sized on the child
   .social-ico rather than the link, so the target grows without the artwork
   changing; centring keeps the row's optical alignment identical. */
.topbar__group .social-link { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 5px; transition: transform 0.18s ease; }
.topbar__group .social-link .social-ico { width: 18px; height: 18px; }
.topbar__group .social-link:hover { transform: translateY(-1px); }
.topbar__group .social-link:focus-visible { outline: 2px solid var(--gold-light); outline-offset: 2px; }
/* Footer & contact: consistent 34px brand squares (no circular badge) */
.footer-social a { width: 34px; height: 34px; background: none; border-radius: 8px; padding: 0; transition: transform 0.2s ease; }
.footer-social a:hover { background: none; transform: translateY(-2px); }
.footer-social a:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--gold); border-radius: 9px; }
.footer-social .social-ico { width: 34px; height: 34px; border-radius: 8px; }
/* WhatsApp Specials Channel — exact muted green from the newsletter button */
.footer-social .is-channel { background: #16856E; }
.footer-social .is-channel:hover { background: #11705C; }
.footer-social .is-channel svg { color: #fff; width: 20px; height: 20px; }
.topbar__group a[aria-label*="Specials Channel"] svg { color: #16856E; }

.footer-bottom {
  position: relative;           /* anchors the centred easter-egg trigger */
  border-top: 1px solid rgba(255,255,255,0.1);
  padding: 22px 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 13px;
  color: #8a8a8a;
}
/* Hidden easter-egg trigger. Absolutely positioned so it sits dead-centre of the
   bar regardless of how wide the copyright and legal links are, and so it stays
   out of the flex flow entirely. Desktop only — the bar wraps below 900px and an
   absolute element would land on top of it. */
.egg-trigger {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: #8a8a8a;
  opacity: 0.4;
  transition: opacity 0.3s ease;
}
.egg-trigger:hover { opacity: 0.85; color: #8a8a8a; }
@media (max-width: 900px) { .egg-trigger { display: none; } }
.footer-bottom nav { display: flex; gap: 18px; flex-wrap: wrap; }
.footer-bottom a { color: #8a8a8a; }
.footer-bottom a:hover { color: var(--gold-light); }

@media (max-width: 900px) {
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px; }
  /* stack the pitch above the button rather than squeezing them side by side */
  .footer-cta__inner { flex-direction: column; align-items: flex-start; gap: 20px; }
  .footer-cta h2 { font-size: 26px; }
  .trust-logo { flex-basis: 138px; }
}
@media (max-width: 600px) {
  .topbar__inner { justify-content: center; }
  .footer-grid { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; text-align: center; }
  /* .footer-cta phone padding now comes from --band-py-sm (34px at ≤600). */
  .footer-cta__form,
  .footer-cta__form .btn { width: 100%; text-align: center; }
  /* two per row beats a 140px minimum forcing a single tall column */
  .trust-grid { gap: 10px; }
  .trust-logo { flex-basis: 42%; min-height: 54px; }
}

/* ============================================================================
   MOBILE QUICK-WINS (audit implementation) — global, reusable rules.
   Grouped here for easy review; nothing here touches desktop (>=1024px).
   ============================================================================ */
@media (max-width: 1023px) {
  /* #3 Tap targets — grow icon + inline-link hit areas toward 44px without
     changing the visible glyph size. */
  .topbar__group .social-link { width: 40px; height: 40px; }
  .arrow-link { min-height: 40px; }
  /* #10 Footer/menu link rows become comfortable tap rows. */
  .footer-nav a,
  .footer-bottom nav a { display: inline-flex; align-items: center; min-height: 40px; }
}
@media (max-width: 600px) {
  /* #2 Condense the top contact bar to ONE compact row: keep the phone number
     and the social icons, drop the email text and the "Specials Channel" label
     (the WhatsApp icon still links out). Kills the 86px two-row wrap. The
     .topbar__group span selector out-specifies a bare class, so these hides are
     qualified to win the cascade. */
  .topbar__group span.topbar__email { display: none; }
  .topbar__group .topbar__wa-label { display: none; }
  .topbar__inner { flex-wrap: nowrap; gap: 10px; }
  .topbar__group { flex-wrap: nowrap; gap: 12px; }
  .topbar__group a[aria-label*="Specials Channel"] { flex-direction: row; }

  /* #6 Tighten the footer (was ~1.7x the viewport): shrink the brands marquee
     (its biggest single block) with smaller plates, tighter gaps and less lead-in
     padding. Existing footer-cta/lower paddings are left as-is so nothing grows. */
  .footer-trust { padding: 26px 0 0; }
  .trust-grid { gap: 8px; }
  /* Shorter brand plates + less lead-in padding tightens the marquee (the
     footer's biggest single block). Full footer compaction is deeper work — see
     audit — so this is the safe quick-win slice. */
  .trust-logo { min-height: 44px; }
  /* #7 CTA-strip standardisation lives in pages.css (.cta-banner is defined
     there, after this file, so the override must sit there to win the cascade). */
}
