/* ==============================================================
   DAVIS + MOORE  ·  SHARED STYLESHEET
   Built from the actual Relume component source, not screenshots.
   Every page links this one file, so a change here changes the
   whole site. Page-specific rules go in a <style> block on the page.

   Home   navbar10 · header5 · layout491 · layout366 · layout526
          layout16 (groups) · layout366 (how it works) · gallery5
          cta25 · footer12
   About  navbar10 · header50 · layout10 · layout373
          testimonial17 · layout503 · cta25 · footer12
   How    navbar10 · header50 · layout16 · layout210 · layout13
          layout359 · cta25 · faq08 · footer12
   Types  navbar10 · header50 · layout41 · layout194 · layout356
          layout01 · cta25 · footer12
   Dest   navbar10 · header26 · portfolio01 · cta25 · footer12
   Contact navbar10 · header50 · contact06 · contact19 · faq08
           cta25 · footer12
   Legal   navbar10 · legal header · prose · footer12
   Quiz    quiz shell · sidebar · question renderer
   Africa navbar10 · header50 · layout504 · portfolio13 · cta25 · footer12

   Owner overrides on the design system:
     1. warm paper instead of white / cool grey
     2. warm body text #2E2C28 instead of #010704
     3. primary buttons green #0F7A3F instead of navy
     4. photo scrims neutral --scrim, not navy (navy read cold on
        warm photographs)
   ============================================================== */

:root{
  --navy:#1B2A57; --navy-dark:#0A1022; --navy-darkest:#080C1A;
  --green:#128A48; --green-ui:#0F7A3F;
  --paper:#FCFBF8; --ink:#2E2C28;
  --s1:#FCFBF8; --s6:#FAF8F4; --s4:#EFE8DA;

  /* One beige, not two. The sand band (#E9DFCB) and the card tint
     (#EFE8DA) were six points apart, and where a sand section met a card
     the difference read as a mistake rather than as two deliberate tones.
     Both now resolve to the card colour, so there is a single value to
     change and no near-miss anywhere on the site. */
  --s7:var(--s4); --sand:var(--s4);
  --line:rgba(46,44,40,.16);
  --line-alt:rgba(252,251,248,.24);
  --serif:"Newsreader",Georgia,serif;
  --sans:"Archivo",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --r-btn:6px; --r-card:8px; --r-img:8px;
  --page:1280px; --pad:5%;

  /* Photo scrim. Every overlay that sits on a photograph reads this, so
     the whole site's cast changes here and nowhere else.

     Was navy 27,42,87. It made warm photographs look cold, most obviously
     on the golden-hour hero, so it is a neutral now.

     46,46,46 is not arbitrary. It is the grey with the same relative
     luminance as the navy it replaced (0.028), so every scrim keeps the
     exact contrast it was measured at and white type over it is unchanged.

     For a warmer version, 46,44,40 is the brand's own body ink and sits at
     the same luminance again. */
  --scrim: 46,46,46;
}
*,*::before,*::after{box-sizing:border-box}
body{margin:0;background:var(--s1);color:var(--ink);font-family:var(--sans);
  font-size:18px;line-height:1.6;-webkit-font-smoothing:antialiased}
img{display:block;max-width:100%}
a{color:inherit}
p{margin:0}

/* Relume type scale */
h1,h2,h3,h4,h5{font-family:var(--serif);font-weight:600;margin:0;color:var(--navy);letter-spacing:-.01em}
.t-h1{font-size:clamp(48px,6.5vw,84px);line-height:1.05}
.t-h2{font-size:clamp(44px,4.7vw,60px);line-height:1.1}
.t-h3{font-size:clamp(32px,3.7vw,48px);line-height:1.15}
.t-h4{font-size:clamp(24px,3vw,40px);line-height:1.2}
.t-h5{font-size:clamp(20px,2.4vw,32px);line-height:1.25}
.t-med{font-size:clamp(16px,1.4vw,20px);line-height:1.6}
.t-sm{font-size:clamp(12px,1.1vw,16px);line-height:1.5}

.sect{padding:64px var(--pad)}
@media(min-width:768px){.sect{padding:96px var(--pad)}}
@media(min-width:992px){.sect{padding:112px var(--pad)}}
/* Half the usual bottom. For a section whose last column is much shorter
   than the one beside it, the standard gap plus that column's own empty
   space read as a hole rather than as breathing room. */
.sect-tight-b{padding-bottom:32px}
@media(min-width:768px){.sect-tight-b{padding-bottom:48px}}
@media(min-width:992px){.sect-tight-b{padding-bottom:56px}}
.container{width:100%;max-width:var(--page);margin-inline:auto}
.head-c{max-width:512px;margin-inline:auto;text-align:center}
/* wider centred header: 896px = 70% of the 1280px container */
.head-wide{max-width:896px}
/* just enough to hold the trip-types subhead on one line */
.head-mid{max-width:640px}
.head-wrap{margin-bottom:48px}
@media(min-width:768px){.head-wrap{margin-bottom:72px}}
@media(min-width:992px){.head-wrap{margin-bottom:80px}}
.tagline{font-weight:600;margin-bottom:12px}
@media(min-width:768px){.tagline{margin-bottom:16px}}
.head-wrap h2{margin-bottom:20px}
@media(min-width:768px){.head-wrap h2{margin-bottom:24px}}

/* Three band tones only: paper, sand, navy. .sch6 used to be --s6 (#FAF8F4),
   which is one step off paper and read as a printing error rather than as a
   band. --s6 itself stays: it is the navbar, the legal page headers and the
   quiz shell, none of which are section bands. */
.sch1{background:var(--s1)} .sch6{background:var(--s4)} .sch7{background:var(--s7)}
.sch5{background:var(--navy);color:#fff}
.sch5 h1,.sch5 h2,.sch5 h3,.sch5 h4,.sch5 h5{color:#fff}

/* buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-family:var(--sans);font-size:16px;font-weight:600;line-height:1;white-space:nowrap;
  padding:12px 22px;border-radius:var(--r-btn);border:1px solid transparent;
  text-decoration:none;cursor:pointer;transition:background-color .2s,border-color .2s,color .2s}
.btn-primary{background:var(--green-ui);color:#fff}
.btn-primary:hover{background:#0c6533}
.btn-secondary{background:transparent;color:var(--navy);border-color:rgba(27,42,87,.4)}
.btn-secondary:hover{border-color:var(--navy)}
.btn-alt{background:var(--paper);color:var(--navy)}
.btn-alt:hover{background:#fff}
.btn-secondary-alt{background:transparent;color:#fff;border-color:var(--line-alt)}
.btn-secondary-alt:hover{border-color:#fff}
.btn-link{background:none;border:0;padding:0;font-weight:600;color:inherit}
.btn-link::after{content:"›";font-size:20px;line-height:1;margin-left:2px}
.btn-row{display:flex;flex-wrap:wrap;gap:16px;margin-top:24px}
@media(min-width:768px){.btn-row{margin-top:32px}}
.head-c .btn-row{justify-content:center;align-items:center}

/* image slot */
.ph{position:relative;overflow:hidden;background:var(--s4)}
.ph img{width:100%;height:100%;object-fit:cover}
.todo{display:flex;align-items:center;justify-content:center;text-align:center;
  border:1px dashed rgba(27,42,87,.4);background:var(--s4);padding:16px;min-height:180px}
.todo span{font-family:ui-monospace,Menlo,monospace;font-size:13px;
  color:rgba(27,42,87,.75);word-break:break-all}

/* ---------- navbar10 ---------- */
.nav{position:sticky;top:0;z-index:999;display:flex;align-items:center;
  min-height:64px;background:var(--s6);padding:0 var(--pad);border-bottom:1px solid var(--line)}
@media(min-width:768px){.nav{min-height:72px}}
.nav-in{margin-inline:auto;display:flex;width:100%;max-width:100%;align-items:center;justify-content:space-between}
/* real horizontal lockup: the old two-window CSS crop of the stacked PNG is gone */
.logo{display:inline-flex;align-items:center;text-decoration:none;flex:none}
.logo img{height:34px;width:auto}
@media(min-width:768px){.logo img{height:38px}}
.nav-menu{display:none}
@media(min-width:992px){
  .nav-menu{display:flex;flex:1;align-items:center;justify-content:space-between;margin-left:24px}
  .nav-links{display:flex;align-items:center}
  .nav-links a{padding:24px 16px;font-size:16px;text-decoration:none;color:var(--navy)}
  .nav-links a:hover{text-decoration:underline}
  .nav-actions{display:flex;align-items:center;gap:16px}
}
.burger{display:flex;flex-direction:column;align-items:center;justify-content:center;
  width:48px;height:48px;margin-right:-8px;background:none;border:0;cursor:pointer}
@media(min-width:992px){.burger{display:none}}
.burger span{display:block;width:24px;height:2px;margin:3px 0;background:var(--navy)}
.nav-mobile{display:none;padding:16px var(--pad) 32px;background:var(--s6);border-bottom:1px solid var(--line)}
.nav-mobile[data-open="true"]{display:block}
@media(min-width:992px){.nav-mobile{display:none!important}}
.nav-mobile a{display:block;padding:12px 0;font-size:16px;text-decoration:none;color:var(--navy)}
.nav-mobile .btn{width:100%;margin-top:16px}

/* ---------- destinations dropdown ----------
   Desktop is CSS only, on :hover and :focus-within. No JS and no aria-expanded,
   because there is no button to describe: the trigger is the Destinations link
   itself, which still goes to the destinations page.

   :focus-within is what makes it keyboard reachable. Tabbing to Destinations
   opens the panel, and only then do the six links inside become focusable.
   That is also why the panel hides with visibility rather than display: it
   still animates, and visibility:hidden keeps the links out of the tab order
   while closed. Swapping it for display:none would kill the transition;
   swapping it for opacity alone would leave six invisible tab stops. */
.nav-mobile-sub{margin:2px 0 6px;padding-left:16px;
  border-left:1px solid rgba(27,42,87,.18)}
.nav-mobile-sub a{padding:9px 0;font-size:15px;color:rgba(27,42,87,.85)}
@media(min-width:992px){
  .nav-drop{position:relative}
  .nav-drop > a{display:inline-flex;align-items:center;gap:6px}
  .nav-caret{width:10px;height:6px;flex:none;transition:transform .18s ease}
  .nav-drop:hover .nav-caret,.nav-drop:focus-within .nav-caret{transform:rotate(180deg)}
  .nav-panel{position:absolute;top:100%;left:8px;min-width:14rem;padding:8px;
    background:var(--s6);border:1px solid var(--line);border-radius:12px;
    box-shadow:0 14px 34px rgba(27,42,87,.14);
    opacity:0;visibility:hidden;transform:translateY(-6px);
    transition:opacity .18s ease,transform .18s ease,visibility .18s}
  .nav-drop:hover .nav-panel,.nav-drop:focus-within .nav-panel{
    opacity:1;visibility:visible;transform:none}
  /* display:block is load-bearing. .nav-links is a flex row, but the panel is
     an ordinary block, so its anchors fall back to inline and lay out as
     wrapped text rather than as a list. */
  .nav-links .nav-panel a{display:block;padding:10px 12px;border-radius:8px;
    white-space:nowrap}
  .nav-links .nav-panel a:hover{background:var(--s4);text-decoration:none}
  .nav-panel-all{margin-top:4px;padding-top:12px!important;
    border-top:1px solid var(--line);border-radius:0 0 8px 8px}
}
@media(prefers-reduced-motion:reduce){
  .nav-panel,.nav-caret{transition:none}
}

/* ---------- header5 ---------- */
.hero{position:relative;padding:0 var(--pad)}
.hero-in{position:relative;z-index:10;margin-inline:auto;max-width:var(--page)}
.hero-box{display:flex;align-items:center;min-height:100svh;max-height:60rem;padding:64px 0}
@media(min-width:768px){.hero-box{padding:96px 0}}
@media(min-width:992px){.hero-box{padding:112px 0}}
/* Hero copy starts hidden when the scroll-scrubbed film is going to run, set
   by the one line script in each page's head so it applies before the first
   paint. Without it the headline, subhead and buttons show for a moment and
   are then hidden by the first step(), which got very visible once the video
   moved to R2 and took a round trip longer to confirm.

   Nothing removes this on success: step() writes an inline opacity, and an
   inline style outranks this rule. site.js removes it on every failure path,
   and on a timeout, so the copy can never be stranded invisible. */
html[data-hero="hold"] .hero-copy > *{opacity:0}

.hero-copy{max-width:28rem}
.hero-copy h1{color:#fff;margin-bottom:20px}
@media(min-width:768px){.hero-copy h1{margin-bottom:24px}}
.hero-copy p{color:#fff}
.hero-bg{position:absolute;inset:0;z-index:0}
.hero-bg picture{display:block;width:100%;height:100%}
.hero-bg img{width:100%;height:100%;object-fit:cover}
.hero-bg .todo{height:100%;border:0}
.hero-bg::after{content:"";position:absolute;inset:0;background:rgba(var(--scrim),.52)}

/* ---------- hero scrubbed by scroll ----------
   The video is stepped frame by frame as you scroll and is never played.
   .hero-track is the scroll distance, .hero-stick is the screenful that
   pins inside it. 300vh of track leaves 200vh of scrolling mapped across
   the twelve seconds of footage.

   Everything here is opt-in through [data-scrub="on"], which site.js sets
   only once the video has actually loaded. Until then, and on any device
   that never gets there, this is the ordinary still hero it always was:
   the track collapses, nothing pins and the photograph shows. That is
   also what happens with no JavaScript at all. */
.hero-vid{display:none}
@media(min-width:768px) and (prefers-reduced-motion:no-preference){
  /* Pull the hero up under the navbar so the film starts at the very top
     of the page. Without this the track began 75px down, the scrub stayed
     clamped at zero until you had scrolled past the navbar, and the first
     scroll did nothing.

     --nav-h is measured and set by site.js, because the navbar's height
     comes from its content rather than its min-height, so there is no
     correct number to hardcode. If it is never set the fallback is 0 and
     the hero simply sits where it always did. */
  .hero-scrub[data-scrub="on"]{margin-top:calc(var(--nav-h, 0px) * -1)}
  .hero-scrub[data-scrub="on"] .hero-track{height:300vh}
  .hero-scrub[data-scrub="on"] .hero-stick{position:sticky;top:0;height:100svh;overflow:hidden}
  .hero-scrub[data-scrub="on"] .hero-box{min-height:100svh}
  /* the still stays in the markup as the poster and the fallback, but the
     video covers it once it is ready */
  .hero-scrub[data-scrub="on"] .hero-vid{display:block;position:absolute;inset:0;
    width:100%;height:100%;object-fit:cover;z-index:1}
  .hero-scrub[data-scrub="on"] .hero-bg::after{z-index:2}
}

/* Full bleed. The section's own 5% padding used to inset the picture from
   both edges. Moving it inward means the video and its scrim reach the
   edges of the window while the copy sits exactly where it did before:
   .hero-in now spans the full width and carries the padding, and
   .hero-box holds the old 1280px measure and stays centred. */
.hero-scrub{padding:0}
.hero-scrub .hero-in{max-width:none;padding:0 var(--pad)}
.hero-scrub .hero-box{max-width:var(--page);margin-inline:auto;width:100%}

/* The copy arrives as you scroll, one line at a time, and starts at
   nothing. site.js sets the opacity; this is just the starting value.

   INSIDE the same media query as the scrub, which matters. It used to sit
   outside it, so narrowing a desktop window left data-scrub="on" while the
   track collapsed, and the headline stayed invisible with nothing left to
   bring it back. site.js clears its inline opacity in the same case. */
@media(min-width:768px) and (prefers-reduced-motion:no-preference){
  .hero-scrub[data-scrub="on"] .hero-copy > *{opacity:0}
}

/* ---------- layout491 (tabs) ---------- */
.tabs-grid{display:grid;grid-template-columns:1fr;align-items:center;gap:0 48px}
@media(min-width:768px){.tabs-grid{grid-template-columns:1fr 1fr}}
@media(min-width:992px){.tabs-grid{gap:0 80px}}
.tabs-list{display:flex;flex-direction:column;margin-bottom:32px}
@media(min-width:768px){.tabs-list{margin-bottom:0}}
.tab-trigger{display:flex;flex-direction:column;align-items:flex-start;text-align:left;
  padding:24px 0;background:none;border:0;border-bottom:1px solid var(--line-alt);
  cursor:pointer;color:inherit;width:100%;opacity:.25;transition:opacity .3s;
  /* buttons do not inherit font-size, so the body copy was falling back to the
     browser default of ~13px. `font:inherit` picks up the 18px body size. */
  font:inherit}
.tab-trigger[aria-selected="true"]{opacity:1}
.tab-trigger h3{color:#fff}
.tab-body{overflow:hidden;max-height:0;opacity:0;transition:max-height .3s ease-in-out,opacity .3s}
.tab-trigger[aria-selected="true"] .tab-body{max-height:20rem;opacity:1;margin-top:12px}
@media(min-width:768px){.tab-trigger[aria-selected="true"] .tab-body{margin-top:16px}}
.tabs-panel{display:flex;width:100%;align-items:center;justify-content:center;overflow:hidden}
.tab-pane{display:none;width:100%}
.tab-pane[data-active="true"]{display:block;animation:fade .25s ease}
@keyframes fade{from{opacity:0}to{opacity:1}}
.tab-pane .ph{border-radius:var(--r-img);aspect-ratio:3/2}

/* ---------- layout491 driven by scroll ----------
   The tab grid pins and the three tabs advance as you scroll past, then it
   lets go and the page carries on. Nothing is hijacked: the page scrolls
   at its normal speed and scroll position simply decides which tab is
   open, so a trackpad flick or a jump to an anchor behaves the same way it
   always did.

   Only the grid pins, not the whole section. The grid is about 400px and
   the heading above it is another 300, and pinning both would need a 900px
   viewport, which rules out most laptops. So the heading scrolls away
   normally and the grid takes over from there.

   The track is 200vh: minus the grid's own height that leaves roughly half
   a viewport of scrolling per tab.

   Desktop only. On a phone the two columns stack and there is no room to
   pin anything, so they stay ordinary click tabs, which is also what
   happens for anyone who asked for reduced motion. */
@media(min-width:992px) and (min-height:760px) and (prefers-reduced-motion:no-preference){
  /* 360vh, not 200. At 200 the pinned block held for 1107px, so each tab
     got 369px and a single wheel flick went straight past all three. This
     gives each one about 850px, close to a screenful, which is long enough
     to read the tab before the next arrives. */
  .scroll-tabs{height:360vh}
  .scroll-tabs-in{position:sticky;top:95px}

  /* The headline pins with the tabs, so the block has to fit between the
     navbar and the bottom of the window. Three things buy that room:
     a tighter gap under the headline, an image sized off the viewport
     rather than a fixed 3:2, and a shorter floor on the tab column.

     The min-height on the tab column is not cosmetic. Tab bodies open and
     close as you scroll, and without a floor the pinned block changed
     height every time, which both twitched and moved the geometry the
     scroll maths depends on. */
  .scroll-tabs-in .head-wrap{margin-bottom:32px}
  .scroll-tabs-in .tabs-list{min-height:21rem;justify-content:center}
  .scroll-tabs-in .tab-pane .ph{aspect-ratio:auto;height:clamp(240px,40vh,420px)}
}

/* ---------- layout366 ---------- */
.l366{display:grid;grid-template-columns:1fr;gap:24px}
@media(min-width:768px){.l366{gap:32px}}
@media(min-width:992px){.l366{grid-template-columns:1fr 1fr}}
/* --s4 rather than --s6: on the --s1 page background the old value was only
   two shades off and the cards had almost no edge. */
.card{background:var(--s4);border-radius:var(--r-card);overflow:hidden;display:flex;flex-direction:column}
.card-pad{padding:24px}
@media(min-width:768px){.card-pad{padding:32px}}
.l366-big{order:-1}
@media(min-width:992px){
  .l366-big{order:0;grid-column:1/2;grid-row:1/3}
  .l366-big .card-pad{padding:48px;display:flex;flex:1;flex-direction:column;justify-content:center}
}
.l366-big .ph{aspect-ratio:16/10}
.l366-sm{order:1}
@media(min-width:768px){.l366-sm{display:grid;grid-template-columns:1fr 1fr}}
@media(min-width:992px){.l366-sm{order:0}}
.l366-sm .ph{min-height:220px;height:100%}
.card h3{margin-bottom:20px}
@media(min-width:768px){.card h3{margin-bottom:24px}}
.l366-sm h3{margin-bottom:8px}
.card .tagline{font-size:16px;margin-bottom:8px}

/* ---------- how it works, scrubbed ----------
   Steps left, film right, pinned together while the scroll steps the video
   and fades each step in at its moment.

   The whole block is opt-in through [data-scrub="on"], which site.js only
   sets once the video is ready. Until then, and anywhere the scrub never
   runs, this is an ordinary two-column block with all four steps plainly
   visible and a still photograph. That is also the no-JavaScript state. */
.hiw-cols{display:grid;grid-template-columns:1fr;gap:32px;align-items:center}
@media(min-width:900px){
  .hiw-cols{grid-template-columns:1fr 1fr;gap:56px}
  /* Film left, words right. Swapped with `order` rather than in the markup,
     so the steps still come first for a screen reader: they are the content,
     the film illustrates them.

     The reason for the swap is where the eye goes. With the words on the
     left they took all the attention, because they are what moves, and the
     film beside them went unread. Landing on the film first and moving
     right to the words lets both register. */
  .hiw-steps{order:2}
  .hiw-media{order:1}
}
.hiw-steps{list-style:none;margin:0;padding:0;display:grid;gap:24px}
.hiw-step{display:flex;gap:18px;align-items:flex-start}
.hiw-n{flex:none;width:34px;height:34px;border-radius:50%;
  display:grid;place-items:center;background:var(--s4);
  font-family:var(--serif);font-size:17px;color:var(--navy);margin-top:2px}
.hiw-step h3{margin-bottom:6px}
.hiw-step p{color:rgba(46,44,40,.82)}
.hiw-media .ph{position:relative;border-radius:var(--r-img);aspect-ratio:16/9}
.hiw-media img{width:100%;height:100%;object-fit:cover}
.hiw-vid{display:none}
.hiw-cta{justify-content:flex-start}

@media(min-width:900px) and (min-height:760px) and (prefers-reduced-motion:no-preference){
  .hiw-track[data-scrub="on"]{height:340vh}
  .hiw-track[data-scrub="on"] .hiw-in{position:sticky;top:95px}
  /* the heading rides with the block, so its bottom margin comes down */
  .hiw-track[data-scrub="on"] .head-wrap{margin-bottom:32px}
  .hiw-track[data-scrub="on"] .hiw-cta{margin-top:32px}
  /* the film covers the still once it can render */
  .hiw-track[data-scrub="on"] .hiw-vid{display:block;position:absolute;inset:0;
    width:100%;height:100%;object-fit:cover}
  /* steps arrive one at a time; site.js sets the opacity */
  .hiw-track[data-scrub="on"] .hiw-step{opacity:0}
}

/* ---------- layout526 ----------
   .bgcard is the words-over-a-photograph card. It used to be defined up in
   the layout522 block; that block is gone and this is now its only user,
   so it lives here. */
.bgcard{position:relative;border-radius:var(--r-card);overflow:hidden;
  display:flex;flex-direction:column;padding:24px;min-height:320px;color:#fff}
@media(min-width:768px){.bgcard{padding:32px}}
.bgcard>.bg{position:absolute;inset:0;z-index:0}
.bgcard>.bg img{width:100%;height:100%;object-fit:cover}
.bgcard>.bg .todo{height:100%;border:0}
.bgcard>.bg::after{content:"";position:absolute;inset:0;background:rgba(var(--scrim),.55)}
.bgcard .fg{position:relative;z-index:10;display:flex;flex:1;flex-direction:column;justify-content:space-between}
.bgcard h3,.bgcard h4{color:#fff}

.l526{display:grid;grid-template-columns:1fr;gap:24px}
@media(min-width:768px){.l526{gap:32px}}
@media(min-width:992px){.l526{grid-template-columns:repeat(3,1fr)}}
.l526-col{display:grid;grid-template-columns:1fr;gap:24px}
@media(min-width:768px){.l526-col{gap:32px}}
.l526 .bgcard{min-height:260px}
@media(min-width:992px){.l526 .card-big{min-height:32rem;justify-content:center}}
.l526 .card-big .fg{justify-content:center}

/* ---------- gallery5 ---------- */
.gal{display:grid;grid-template-columns:1fr 1fr;align-items:start;gap:24px}
@media(min-width:768px){.gal{gap:32px}}
@media(min-width:992px){.gal{grid-template-columns:repeat(3,1fr)}}
.gal a{text-decoration:none;display:block}
.gal .ph{border-radius:var(--r-img);aspect-ratio:1/1}
/* DEVIATION: gallery5 ships with no captions. Six unlabelled images cannot
   work as continent navigation, so a label is added beneath each. */
.gal span{display:block;margin-top:14px;font-size:16px;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--navy)}

/* ---------- cta25 ---------- */
/* 640px holds the headline on one line and drops the subhead to two */
.cta{max-width:640px;margin-inline:auto;text-align:center}
.cta h2{margin-bottom:20px}
@media(min-width:768px){.cta h2{margin-bottom:24px}}
.cta .btn-row{justify-content:center}

/* ---------- footer12 ---------- */
/* Footer runs navy, matching the band at the top of the page. All type
   reverses to warm white; rules switch to the light hairline. */
.foot{padding:48px var(--pad);background:var(--navy);color:rgba(252,251,248,.82)}
@media(min-width:768px){.foot{padding:72px var(--pad)}}
@media(min-width:992px){.foot{padding:80px var(--pad)}}
.foot h2{color:#fff}
.foot a{color:rgba(252,251,248,.82);transition:color .2s}
.foot a:hover{color:#fff}
.foot address{color:rgba(252,251,248,.82)}
.foot .socials svg{fill:rgba(252,251,248,.82)}
.foot .socials a:hover svg{fill:#fff}
.foot-top{border-bottom:1px solid var(--line-alt)}
.foot-grid{display:grid;grid-template-columns:1fr;gap:48px 8vw;margin-bottom:48px}
@media(min-width:768px){.foot-grid{margin-bottom:72px;gap:64px 8vw}}
@media(min-width:992px){.foot-grid{grid-template-columns:1fr .5fr;margin-bottom:80px}}
.foot-lead{max-width:28rem}
.foot-lead h2{margin-bottom:20px}
@media(min-width:768px){.foot-lead h2{margin-bottom:24px}}
.foot-cols{display:grid;grid-template-columns:1fr;align-items:start;gap:20px 24px}
@media(min-width:640px){.foot-cols{grid-template-columns:1fr 1fr}}
@media(min-width:768px){.foot-cols{gap:16px 32px}}
.foot-cols ul{list-style:none;margin:0;padding:0}
.foot-cols li{padding:8px 0;font-size:16px;font-weight:600}
.foot-cols a{text-decoration:none}
.foot-cols a:hover{text-decoration:underline}
.foot-mid{display:flex;flex-direction:column;align-items:flex-start;
  justify-content:space-between;padding-bottom:24px;gap:20px}
@media(min-width:640px){.foot-mid{flex-direction:row;align-items:center}}
@media(min-width:768px){.foot-mid{padding-bottom:32px}}
.foot-logo{width:150px}
.foot-mid address{font-style:normal;font-size:16px;line-height:1.7}
.foot-base{display:flex;flex-direction:column-reverse;align-items:flex-start;
  justify-content:space-between;padding-top:24px;font-size:16px;gap:20px}
@media(min-width:768px){.foot-base{flex-direction:row;align-items:center;padding-top:32px;gap:0}}
.socials{display:flex;gap:12px}
.socials a{width:24px;height:24px;display:inline-flex}
.socials svg{width:100%;height:100%;fill:var(--ink)}

/* ==============================================================
   ABOUT PAGE COMPONENTS
   ============================================================== */

/* ---------- header50 · interior-page hero ----------
   Same construction as header5 but sized by its copy rather than the
   viewport. Interior pages should not each demand a full screen. */
.hero50{position:relative;padding:64px var(--pad)}
@media(min-width:768px){.hero50{padding:96px var(--pad)}}
@media(min-width:992px){.hero50{padding:112px var(--pad)}}
/* extra room below the buttons so the foot of the photograph has somewhere
   to go, rather than the section edge landing mid-subject */
@media(min-width:992px){.hero50{padding-bottom:160px}}
.hero50-in{position:relative;z-index:10;margin-inline:auto;max-width:var(--page)}
/* 32rem holds about 6 characters of an 84px headline per line, which pushed
   the longer continent headlines to four lines. Widened on large screens
   only: the scrim gradient is keyed to the viewport, so a wider copy column
   on a narrow desktop would push white type out into the lighter half of it. */
.hero50-copy{max-width:32rem}
@media(min-width:1200px){.hero50-copy{max-width:40rem}}
.hero50 .tagline,.hero50 h1,.hero50 p{color:#fff}
.hero50 h1{margin-bottom:20px}
@media(min-width:768px){.hero50 h1{margin-bottom:24px}}
.hero50-bg{position:absolute;inset:0;z-index:0;overflow:hidden}
.hero50-bg img{width:100%;height:100%;object-fit:cover}
.hero50-bg .todo{height:100%;border:0}
/* Scrim is a gradient, not a flat wash. The copy is always left-aligned, so
   the left side needs to be dark enough to carry white type over anything,
   while the right side stays light enough to still read as a photograph.
   A flat 55% did neither job well. */
.hero50-bg::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,
    rgba(var(--scrim),.82) 0%,
    rgba(var(--scrim),.72) 34%,
    rgba(var(--scrim),.48) 66%,
    rgba(var(--scrim),.36) 100%)}
/* on a phone the copy runs full width, so a flat wash is the right one */
@media(max-width:767px){.hero50-bg::after{background:rgba(var(--scrim),.62)}}

/* Art direction: pushes the image right so a subject sitting in the copy
   column moves clear of it. Costs a slightly tighter crop. Opt in per page,
   only where a hero actually needs it.

   Done by widening the image and pinning it to the left edge, NOT by
   transform. A scale-plus-translate moved the image further right than it
   had spare width and left a strip of bare background down the left side.
   Anchored at left:0 the overflow can only ever fall off the right, so
   that cannot happen at any viewport width. */
@media(min-width:992px){
  .hero50-bg.shift-right img{position:absolute;top:0;left:0;
    width:130%;max-width:none;height:100%}
}

/* Art direction: choose where the vertical crop is taken from. cover crops
   both edges evenly, so a subject sitting low in the picture gets cut in
   half. Opt in per page and set --anchor-y.

   This, not extra section padding, is the fix for a cut-off subject: the
   crop grows with viewport width, so no fixed padding closes it on a wide
   monitor.

   --anchor-y is the share of the crop taken off the TOP. 100% keeps the
   very bottom of the photograph flush, which is usually too far: it lifts a
   low subject up into the copy. Lower values slide the picture down. The
   floor is set by the widest screen you care about, because the crop is
   largest there. On Asia the boat sits at 72%, chosen for ordinary laptop
   and desktop widths rather than for the extremes: it leaves the hull clear
   by about 90px at 1440 and 50px at 2000, and only 8px at 2560. Below 71%
   the hull is cut on a 2560px display. Deliberate, not an oversight. */
.hero50-bg.anchor-bottom img{object-position:50% var(--anchor-y, 100%)}

/* ---------- shared line icon ---------- */
.icon{display:block;width:44px;height:44px;margin-bottom:12px;color:var(--navy)}
@media(min-width:768px){.icon{margin-bottom:16px}}
.icon svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.4;
  stroke-linecap:round;stroke-linejoin:round}
.sch5 .icon{color:#fff}

/* ---------- layout10 ---------- */
.l10{display:grid;grid-template-columns:1fr;gap:48px}
@media(min-width:768px){.l10{grid-template-columns:1fr 1fr;align-items:center}}
@media(min-width:992px){.l10{gap:80px}}
.l10 h2{margin-bottom:20px}
@media(min-width:768px){.l10 h2{margin-bottom:24px}}
.l10-lead{margin-bottom:24px}
@media(min-width:768px){.l10-lead{margin-bottom:32px}}
.l10-pair{display:grid;grid-template-columns:1fr;gap:24px;padding:8px 0}
@media(min-width:640px){.l10-pair{grid-template-columns:1fr 1fr}}
.l10-pair h3{margin-bottom:12px}
@media(min-width:768px){.l10-pair h3{margin-bottom:16px}}
.l10 .ph{border-radius:var(--r-img);aspect-ratio:4/5}

/* ---------- layout373 ----------
   One wide card spanning two of four columns, then two single cards.
   Not three equal cards: the first point carries more weight. */
.l373{display:grid;grid-template-columns:1fr;gap:24px}
@media(min-width:640px){.l373{grid-template-columns:1fr 1fr}}
@media(min-width:768px){.l373{gap:32px}}
@media(min-width:992px){.l373{grid-template-columns:repeat(4,1fr)}}
.l373 .card{padding:24px;justify-content:space-between}
@media(min-width:768px){.l373 .card{padding:32px}}
@media(min-width:640px){.l373-big{grid-column:span 2}}   /* a span of 2 on the one-column base grid invents a second column and collapses its neighbour to zero width on a phone */
@media(min-width:992px){.l373-big{padding:48px;justify-content:center}}
.l373 .card h3{margin-bottom:8px}
.l373-big h3{margin-bottom:20px}
@media(min-width:768px){.l373-big h3{margin-bottom:24px}}

/* ---------- testimonial17 ----------
   Relume's construction, avatar included. Placeholder cards may carry a
   generated face; real testimonials carry a real photograph or none. */
.quotes{display:grid;grid-template-columns:1fr;gap:24px}
@media(min-width:768px){.quotes{grid-template-columns:1fr 1fr;gap:32px}}
@media(min-width:992px){.quotes{grid-template-columns:repeat(3,1fr)}}
.quote{background:var(--s4);border-radius:var(--r-card);padding:24px;
  display:flex;flex-direction:column;justify-content:space-between}
@media(min-width:768px){.quote{padding:32px}}
.stars{display:flex;gap:4px;margin-bottom:20px}
@media(min-width:768px){.stars{margin-bottom:24px}}
.stars svg{width:20px;height:20px;fill:var(--navy)}
.quote blockquote{margin:0;font-family:var(--serif);font-size:20px;
  line-height:1.5;color:var(--navy)}
.quote-by{margin-top:20px;display:flex;flex-direction:column;align-items:flex-start;
  gap:12px;font-size:16px;line-height:1.5}
@media(min-width:768px){.quote-by{margin-top:24px;flex-direction:row;align-items:center;gap:16px}}
.quote-by strong{display:block;font-weight:600;color:var(--navy)}
/* A portrait tile, not the round face-crop the component shipped with. The
   client photographs are full-length travel shots at about 2:3, so a 48px
   circle showed a fragment of somebody's midriff and none of the trip. The
   tile is 2:3 as well, which means cover crops almost nothing. */
.avatar{width:64px;height:96px;min-width:64px;border-radius:10px;overflow:hidden;
  background:var(--s7)}
@media(min-width:768px){.avatar{width:80px;height:120px;min-width:80px;border-radius:12px}}
.avatar img{width:100%;height:100%;object-fit:cover;object-position:center}
/* empty avatar slot, distinct from .todo which is sized for photo frames */
.avatar.pending{border:1px dashed rgba(27,42,87,.45);background:transparent}
/* the hero image is not square-cropped; keep the village and terraces in frame
   on a phone rather than centring on empty valley floor */
@media(max-width:767px){.hero50-bg img{object-position:72% center}}

/* placeholder marker, delete the element and this rule together */
.note{max-width:640px;margin:0 auto 40px;padding:12px 16px;
  border:1px dashed rgba(27,42,87,.45);border-radius:var(--r-btn);
  font-size:14px;line-height:1.5;text-align:center;color:rgba(27,42,87,.85)}

/* ---------- layout503 · horizontal tabs ----------
   Different tab construction from layout491 on the homepage: triggers
   run across the top under a rule, one card below. */
.t503-list{display:flex;flex-wrap:wrap;justify-content:center;gap:24px;margin-bottom:48px}
@media(min-width:768px){.t503-list{margin-bottom:64px}}
.t503-trigger{font:inherit;font-weight:600;color:var(--navy);background:none;
  border:0;border-bottom:2px solid transparent;padding:8px 0;cursor:pointer}
.t503-trigger[aria-selected="true"]{border-bottom-color:var(--navy)}
.t503-pane{display:none}
.t503-pane[data-active="true"]{display:block;animation:fade .25s ease}
.t503-card,.l359-card{background:var(--paper);border-radius:var(--r-card);overflow:hidden;
  display:grid;grid-template-columns:1fr;align-items:center}
@media(min-width:768px){.t503-card,.l359-card{grid-template-columns:1fr 1fr}}
.t503-card .card-pad,.l359-card .card-pad{padding:24px}
@media(min-width:768px){.t503-card .card-pad,.l359-card .card-pad{padding:32px}}
@media(min-width:992px){.t503-card .card-pad,.l359-card .card-pad{padding:48px}}
.t503-card .ph,.l359-card .ph{aspect-ratio:1/1;height:100%}
.t503-card h3,.l359-card h3{margin-bottom:20px}
@media(min-width:768px){.t503-card h3,.l359-card h3{margin-bottom:24px}}



/* ==============================================================
   HOW IT WORKS PAGE COMPONENTS
   ============================================================== */

/* ---------- layout16 / layout210 / layout13 ----------
   All three are the same two-column stage block. Only the side the
   image sits on and the list style inside them differ, so they share
   one rule rather than getting three near-identical ones. */
.split{display:grid;grid-template-columns:1fr;gap:48px}
@media(min-width:768px){.split{grid-template-columns:1fr 1fr;align-items:center}}
@media(min-width:992px){.split{gap:80px}}
.split h2{margin-bottom:20px}
@media(min-width:768px){.split h2{margin-bottom:24px}}
.split-lead{margin-bottom:20px}
@media(min-width:768px){.split-lead{margin-bottom:24px}}
/* Most splits carry one paragraph. Group travel carries three, and with no
   rule they ran together into one block. Scoped to .split so it cannot
   reach the card and hero copy elsewhere. */
.split .t-med + .t-med{margin-top:18px}
.split .ph{border-radius:var(--r-img);aspect-ratio:3/2}
.split-tall .ph{aspect-ratio:4/5}
/* split-fill: the picture takes the height of the copy beside it rather
   than holding a ratio. Group travel has a long copy column and a 9:16
   source shot for exactly this, and a fixed 4:5 box cropped the top and
   bottom off it. Stacked on a phone there is no copy to match, so the
   source ratio is used instead. */
.split-fill .ph{aspect-ratio:9/16}
@media(min-width:768px){
  .split-fill{align-items:stretch}
  .split-fill .split-media{display:flex}
  .split-fill .ph{aspect-ratio:auto;width:100%}
}
/* layout210 puts the image left on desktop and below the copy on a phone.
   Copy stays first in the markup either way, so it is read first. */
@media(min-width:768px){.split-flip .split-media{order:-1}}

/* layout16 checklist */
.checks{list-style:none;margin:0;padding:8px 0;display:grid;gap:16px}
.checks li{display:flex;align-items:flex-start;gap:16px}
.checks .tick{flex:none;width:24px;height:24px;margin-top:3px}
.checks .tick svg{width:100%;height:100%;fill:none;stroke:currentColor;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}

/* layout210 bullets */
.bullets{margin:16px 0;padding-left:22px}
.bullets li{margin:6px 0;padding-left:6px}

/* group travel · the two size bands.
   Numbers set in the serif because they are the fact of the section, and
   the audience is scanning for whether their group is too big or too
   small before they read anything else. */
.sizes{display:grid;gap:20px;margin:28px 0}
@media(min-width:560px){.sizes{grid-template-columns:1fr 1fr;gap:28px}}
.size{padding-left:18px;border-left:2px solid var(--green-ui)}
.size-n{font-family:var(--serif);font-size:clamp(22px,2.4vw,28px);line-height:1.2;
  margin-bottom:6px;color:var(--navy)}
.sch5 .size-n{color:#fff}
.sch5 .size{border-left-color:rgba(255,255,255,.45)}

/* layout13 ----------
   DEVIATION: Relume fills this slot with a row of partner logos. We hold
   no accreditations and must not imply any, so the slot carries what
   people actually change instead. */
.chip-label{font-size:16px;font-weight:600;color:var(--navy);margin-bottom:12px}
.chips{display:flex;flex-wrap:wrap;gap:10px;padding:2px 0 8px}
.chip{display:inline-flex;align-items:center;padding:8px 16px;border-radius:999px;
  border:1px solid var(--line);background:var(--s4);
  font-size:16px;font-weight:600;color:var(--navy)}

/* inline link inside body copy. Navy, not green: green measures 4.3:1 on
   scheme 6 and fails for text this size. */
.inline-link{color:var(--navy);text-decoration:underline;text-underline-offset:3px;font-weight:600}
.sch5 .inline-link{color:#fff}

/* ---------- faq08 ---------- */
.faq{display:grid;grid-template-columns:1fr;gap:48px}
@media(min-width:768px){.faq{grid-template-columns:1fr 1fr}}
@media(min-width:992px){.faq{grid-template-columns:.75fr 1fr;gap:80px}}
/* The heading column pins while the answers scroll past it, then leaves
   with the section. Sticky is bounded by its containing block, which is
   the .faq grid, so nothing extra is needed to make it let go at the end.

   align-self:start is the part that is easy to miss. A grid item defaults
   to stretch, which makes it as tall as the row, and an element that
   already fills its container has nowhere to stick to.

   Only from 768px. Below that the two columns stack, and a heading
   pinned above its own answers on a phone is just lost screen. */
@media(min-width:768px){
  .faq > :first-child{position:sticky;top:104px;align-self:start}
}
.faq h2{margin-bottom:20px}
@media(min-width:768px){.faq h2{margin-bottom:24px}}
.faq-list{display:grid;gap:40px}
@media(min-width:768px){.faq-list{gap:48px}}
.faq-q{font-size:clamp(16px,1.4vw,20px);font-weight:700;color:var(--navy);margin-bottom:12px}
@media(min-width:768px){.faq-q{margin-bottom:16px}}


/* ==============================================================
   TRIP TYPES PAGE COMPONENTS
   ============================================================== */

/* ---------- layout41 · two-column statement ---------- */
.l41{display:grid;grid-template-columns:1fr;gap:20px}
@media(min-width:768px){.l41{grid-template-columns:1fr 1fr;gap:24px 48px}}
@media(min-width:992px){.l41{gap:24px 80px}}

/* ---------- layout356 · sticky stack ----------
   DEVIATION: Relume pins each bar at a bigger offset than the last, so
   they pile up. That works for three panels and buries half the viewport
   at six. Here every bar pins at the same height, so each new one pushes
   the previous out and exactly one is on screen at a time, always naming
   the type you are looking at. Costs one bar of height instead of six.

   The offset matches the sticky navbar so the two never overlap. */
.stack-item{position:relative}
.stack-bar{position:sticky;top:64px;z-index:5;padding:0 var(--pad);
  background:var(--s1);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
@media(min-width:768px){.stack-bar{top:72px}}
.stack-bar-in{display:flex;align-items:center;gap:20px;height:56px;
  max-width:var(--page);margin-inline:auto}
@media(min-width:768px){.stack-bar-in{gap:24px;height:64px}}
.stack-bar .n{font-size:16px;font-weight:600;color:var(--green-ui);flex:none}
.stack-bar h2{font-family:var(--sans);font-size:16px;font-weight:600;
  letter-spacing:0;color:var(--navy);margin:0}
/* Type name is the headline, not the benefit line. Three competing labels
   per panel (pinned bar, green eyebrow, big serif promise) meant the eye
   landed on the promise and had to work out the type from it. Now the order
   is number, type, promise, detail. */
.type-n{font-family:var(--serif);font-weight:600;font-size:clamp(30px,2.8vw,42px);
  line-height:1;color:var(--green-ui);margin-bottom:6px}
.type-name{margin-bottom:14px}
.type-lead{font-size:clamp(18px,1.6vw,22px);font-weight:600;line-height:1.4;
  color:var(--navy);margin-bottom:16px}
@media(min-width:768px){.type-lead{margin-bottom:20px}}

.stack-body{padding:40px var(--pad) 56px}
@media(min-width:768px){.stack-body{padding:56px var(--pad) 72px}}
@media(min-width:992px){.stack-body{padding:64px var(--pad) 88px}}


/* ==============================================================
   DESTINATIONS PAGE COMPONENTS
   ============================================================== */

/* ---------- header26 ----------
   Centred copy with a wide image below it, rather than copy over a
   full-bleed background. Four pages already open with header50 and a
   scrim; this one should not be the fifth. */
.h26{text-align:center}
.h26-copy{max-width:640px;margin-inline:auto;margin-bottom:48px}
@media(min-width:768px){.h26-copy{margin-bottom:64px}}
@media(min-width:992px){.h26-copy{margin-bottom:72px}}
.h26 h1{margin-bottom:20px}
@media(min-width:768px){.h26 h1{margin-bottom:24px}}
.h26 .btn-row{justify-content:center}
.h26 .ph{border-radius:var(--r-img);aspect-ratio:16/9}

/* ---------- portfolio01 ----------
   DEVIATION: Relume stacks these full width, one per row. Six of those
   is about 5000px of scroll on a page whose only job is to route
   somebody to a continent. Two columns keeps the images large and the
   whole index inside two screens.

   The whole card is one link rather than Relume's three separate ones
   (image, title, and the "View" button), so there is one tab stop and
   one target per continent instead of three. */
.dest-grid{display:grid;grid-template-columns:1fr;gap:48px}
@media(min-width:768px){.dest-grid{grid-template-columns:1fr 1fr;gap:56px 32px}}
@media(min-width:992px){.dest-grid{gap:72px 48px}}
.dest-card{display:block;text-decoration:none;color:inherit}
.dest-card .ph{border-radius:var(--r-img);aspect-ratio:3/2}
.dest-card img{transition:transform .4s ease}
.dest-card:hover img{transform:scale(1.03)}
/* The link sits under the copy, not beside it. Relume puts the title and
   blurb left and the link right, which needs the full container width to
   breathe. In two columns each card is about half that, and the two halves
   end up squeezed against each other. Stacked, the card reads straight
   down: image, name, blurb, link. */
.dest-row{margin-top:20px}
@media(min-width:640px){.dest-row{margin-top:24px}}
.dest-row h3{margin-bottom:8px}
.dest-go{display:inline-block;margin-top:14px;font-weight:600;
  white-space:nowrap;color:var(--navy)}
.dest-go::after{content:"\203A";font-size:20px;line-height:1;margin-left:4px}
.dest-card:hover .dest-go{text-decoration:underline}


/* ==============================================================
   CONTINENT PAGE COMPONENTS  (Africa is the template)
   ============================================================== */

/* ---------- layout504 ----------
   Same card construction as layout503 on About, but the image sits left
   and the whole thing runs on the navy band. A paper card on navy needs
   its type switched back from the scheme's white. */
.sch5 .t503-trigger{color:#fff}
.sch5 .t503-trigger[aria-selected="true"]{border-bottom-color:#fff}
.sch5 .t503-card{color:var(--ink)}
.sch5 .t503-card h2,.sch5 .t503-card h3,
.sch5 .t503-card h4,.sch5 .t503-card h5{color:var(--navy)}

/* ---------- portfolio13 · trips, not countries ----------
   REDESIGNED. This started as one card per country, each linking to its
   own page. Twelve country pages before launch is too much, so the grid
   now groups by what people ask for and nothing in it links out. The
   full country list runs underneath as plain text.

   These are content cards, not links: no hover lift, no chevron, no
   pointer. Anything that looks clickable and is not is worse than plain
   text. */
.theme-grid{display:grid;grid-template-columns:1fr;gap:32px}
@media(min-width:768px){.theme-grid{grid-template-columns:1fr 1fr}}
@media(min-width:992px){.theme-grid{grid-template-columns:repeat(3,1fr);gap:48px 32px}}
.theme-card{background:var(--paper);border-radius:var(--r-card);overflow:hidden;
  display:flex;flex-direction:column}
.theme-card .ph{aspect-ratio:3/2}
.theme-card .card-pad{padding:20px 24px 26px}
.theme-card .tagline{margin-bottom:6px}
.theme-card h3{margin-bottom:10px}

/* the country list under the grid */
.country-list{max-width:760px;margin:56px auto 0;text-align:center}
@media(min-width:768px){.country-list{margin-top:72px}}
.country-list .chip-label{margin-bottom:16px}
.country-list .chips{justify-content:center;padding:0}
.country-list .chip{padding:6px 14px;font-size:15px}
.grid-foot{margin:28px auto 0;color:var(--ink)}


/* ==============================================================
   CONTACT PAGE COMPONENTS
   ============================================================== */

/* ---------- contact06 · details left, form right ---------- */
.c06{display:grid;grid-template-columns:1fr;gap:48px}
@media(min-width:768px){.c06{grid-template-columns:1fr 1fr}}
@media(min-width:992px){.c06{gap:80px}}
.c06 h2{margin-bottom:20px}
@media(min-width:768px){.c06 h2{margin-bottom:24px}}
.c06-intro{margin-bottom:28px}
@media(min-width:768px){.c06-intro{margin-bottom:32px}}
.c06-lines{display:grid;gap:14px}
.c06-line{display:flex;align-items:flex-start;gap:14px}
.c06-line .icon{width:24px;height:24px;margin:2px 0 0;flex:none}

/* ---------- the form ----------
   Inputs are warm paper on the navy band rather than transparent with a
   hairline. This audience is not confident with forms; a field that
   looks like a field is worth more than a field that looks elegant. */
.form{display:grid;gap:20px;max-width:32rem}
.field{display:grid;gap:8px}
.field label{font-size:16px;font-weight:600}
.field input,.field textarea{font:inherit;font-size:16px;width:100%;
  color:var(--ink);background:var(--paper);border:1px solid transparent;
  border-radius:var(--r-btn);padding:12px 14px}
.field textarea{min-height:9rem;resize:vertical}
.field input:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--green-ui);outline-offset:2px}
.field-pair{display:grid;grid-template-columns:1fr;gap:20px}
@media(min-width:640px){.field-pair{grid-template-columns:1fr 1fr}}
.optional{font-weight:400;opacity:.75}

/* SMS consent. Unchecked by default and never required to submit:
   making a service depend on marketing consent is the thing US rules
   are most pointed about. */
.consent{display:flex;align-items:flex-start;gap:12px}
.consent input{flex:none;width:18px;height:18px;margin-top:3px;accent-color:var(--green-ui)}
.consent-text{font-size:14px;line-height:1.55}
.form-note{font-size:14px;line-height:1.55;opacity:.85}
.form a{text-decoration:underline;text-underline-offset:3px}

/* ---------- contact19 · three ways to reach us ---------- */
/* Two columns, not three: the "By post" column was removed by owner
   decision. Nobody writes a letter, and the address is in the footer of
   every page already. */
.c19{display:grid;grid-template-columns:1fr;gap:48px;max-width:56rem;margin-inline:auto}
@media(min-width:768px){.c19{grid-template-columns:1fr 1fr;gap:48px}}
.c19 .icon{width:44px;height:44px;margin-bottom:20px}
.c19 h3{margin-bottom:12px}
.c19 p{margin-bottom:16px}
.c19 address{font-style:normal;font-weight:600;color:var(--navy);line-height:1.6}
.c19 a{font-weight:600;color:var(--navy);
  text-decoration:underline;text-underline-offset:3px}


/* ==============================================================
   LEGAL PAGES
   Not a design system component. Privacy and Terms are long-form
   documents, so they get a compact header and a single readable
   column rather than a photographic hero and a section rhythm.
   ============================================================== */
.legal-head{padding:56px var(--pad) 48px;background:var(--s6);
  border-bottom:1px solid var(--line)}
@media(min-width:768px){.legal-head{padding:72px var(--pad) 56px}}
.legal-head .container{max-width:40rem}
.legal-head h1{margin-bottom:12px}
.legal-updated{font-size:16px;color:var(--ink);opacity:.75}

/* 40rem at 18px is roughly 68 characters, which is the range long
   prose stays comfortable in. Wider and the eye loses the line. */
.legal{max-width:40rem;margin-inline:auto}
.legal > *:first-child{margin-top:0}
.legal h2{margin:48px 0 16px}
@media(min-width:768px){.legal h2{margin-top:56px}}
.legal h3{margin:32px 0 10px}
.legal p{margin-bottom:16px}
.legal ul{margin:0 0 16px;padding-left:22px}
.legal li{margin:10px 0;padding-left:4px}
.legal a{color:var(--navy);text-decoration:underline;text-underline-offset:3px}
.legal strong{color:var(--navy)}


/* ==============================================================
   COOKIE CONSENT BANNER
   Opt-in, not notice-only: analytics and advertising tags do not fire
   until Accept is clicked. Decline is a real button of equal weight,
   not an X, because a choice that is harder to refuse than to give is
   not much of a choice.
   ============================================================== */
/* Cookie bar turned off 2026-08-31, being redesigned. These two rules and
   the CONSENT_OFF flag in site.js are the whole of it; remove all three to
   bring it back. Belt and braces: the flag stops it opening, and these stop
   it appearing at all if the stylesheet loads before the script errors. */
.cookie{display:none!important}
.foot a[data-consent="reopen"]{display:none}

.cookie{position:fixed;inset:auto 0 0 0;z-index:1000;display:none;
  padding:20px var(--pad);background:var(--navy);color:rgba(252,251,248,.92);
  border-top:1px solid var(--line-alt);box-shadow:0 -8px 32px rgba(8,12,26,.25)}
.cookie[data-open="true"]{display:block}
.cookie-in{max-width:var(--page);margin-inline:auto;display:grid;gap:16px}
@media(min-width:900px){.cookie-in{grid-template-columns:1fr max-content;
  gap:40px;align-items:center}}
.cookie p{font-size:15px;line-height:1.55}
.cookie a{color:#fff;text-decoration:underline;text-underline-offset:3px}
.cookie-actions{display:flex;flex-wrap:wrap;gap:12px}
.cookie-actions .btn{flex:1 1 auto;justify-content:center}
@media(min-width:900px){.cookie-actions .btn{flex:0 0 auto}}


/* ==============================================================
   THE QUIZ
   ==============================================================
   Not a Relume component. A funnel page: reduced header, no nav
   links, no footer. The only way out is the logo, which is
   deliberate. Everything it renders comes from assets/quiz-data.js.
   ============================================================== */
.q-shell{min-height:100svh;display:flex;flex-direction:column;background:var(--s6)}

.q-top{position:sticky;top:0;z-index:50;background:var(--s6);
  border-bottom:1px solid var(--line);padding:14px var(--pad)}
.q-top-in{max-width:var(--page);margin-inline:auto;
  display:flex;align-items:center;justify-content:space-between;gap:24px}
.q-top .logo img{height:30px}
.q-progress{flex:1;max-width:22rem}
.q-track{height:4px;border-radius:99px;background:rgba(27,42,87,.14);overflow:hidden}
.q-fill{height:100%;width:0;background:var(--green-ui);border-radius:99px;
  transition:width .35s cubic-bezier(.4,0,.2,1)}
.q-count{margin-top:6px;font-size:13px;font-weight:600;color:rgba(46,44,40,.7)}
.q-save{font-size:14px;color:rgba(46,44,40,.65);white-space:nowrap}
@media(max-width:767px){.q-save{display:none}}

/* ---------- two panes ---------- */
.q-body{flex:1;display:grid;grid-template-columns:1fr}
@media(min-width:992px){.q-body{grid-template-columns:26rem 1fr}}
@media(min-width:1280px){.q-body{grid-template-columns:32rem 1fr}}

.q-aside{position:relative;overflow:hidden;background:var(--navy);min-height:180px}
@media(min-width:992px){.q-aside{min-height:auto}}
.q-aside img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .6s ease}
.q-aside img.on{opacity:1}
.q-aside::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(var(--scrim),.25),rgba(var(--scrim),.75))}
.q-aside-txt{position:absolute;inset:auto 0 0 0;z-index:2;padding:24px var(--pad);color:#fff}
@media(min-width:992px){.q-aside-txt{padding:40px}}
.q-aside-txt p{font-family:var(--serif);font-size:clamp(18px,2vw,26px);line-height:1.35;
  max-width:20rem}
.q-aside-txt span{display:block;margin-top:10px;font-family:var(--sans);font-size:14px;
  font-weight:600;letter-spacing:.06em;text-transform:uppercase;opacity:.8}

.q-main{padding:32px var(--pad) 48px;display:flex;align-items:flex-start}
@media(min-width:992px){.q-main{padding:56px 6% 72px}}
.q-inner{width:100%;max-width:44rem;margin-inline:auto}
@media(min-width:992px){.q-inner{margin:0}}

/* ---------- one question ----------
   This animation now runs only when the step actually changes. It used
   to run on every click, including ticking a checkbox, which read as the
   whole page resetting and dipping. Kept small: the movement should
   register as the next question arriving, not as a transition. */
.q-step{animation:qin .34s ease-out}
@keyframes qin{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* The confirm. A single answer advances on its own, so the chosen option
   has to be seen going green before the screen changes. This plays for
   360ms and PICK_HOLD in quiz.js waits 420ms, so it always finishes.
   Without it the answer landed and the question changed in the same
   frame and the click never registered at all. */
.q-tile.picked,.q-opt.picked{animation:qpick .36s cubic-bezier(.2,.8,.3,1)}
@keyframes qpick{
  0%  {transform:scale(.975)}
  40% {transform:scale(1.015)}
  100%{transform:none}
}
@media(prefers-reduced-motion:reduce){
  .q-step{animation:none}
  .q-tile.picked,.q-opt.picked{animation:none}
  .q-tile,.q-opt{transition:none}
}
.q-eyebrow{font-size:13px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--green-ui);margin-bottom:12px}
.q-step h2{margin-bottom:12px}
.q-sub{color:rgba(46,44,40,.8);margin-bottom:28px;max-width:34rem}

.q-opts{display:grid;gap:12px;margin-bottom:28px}
@media(min-width:640px){.q-opts.two{grid-template-columns:1fr 1fr}}
.q-opt{display:flex;align-items:flex-start;gap:14px;width:100%;text-align:left;
  padding:16px 18px;background:var(--s1);border:1px solid var(--line);
  border-radius:var(--r-card);cursor:pointer;font:inherit;color:inherit;
  transition:border-color .15s,background-color .15s}
.q-opt:hover{border-color:rgba(27,42,87,.45)}
.q-opt[aria-pressed="true"]{border-color:var(--green-ui);background:#fff;
  box-shadow:inset 0 0 0 1px var(--green-ui)}
.q-box{flex:none;width:22px;height:22px;margin-top:1px;border-radius:5px;
  border:1.5px solid rgba(27,42,87,.35);display:grid;place-items:center;background:#fff}
.q-opt[data-single] .q-box{border-radius:50%}
.q-opt[aria-pressed="true"] .q-box{background:var(--green-ui);border-color:var(--green-ui)}
.q-box svg{width:14px;height:14px;fill:none;stroke:#fff;stroke-width:2.5;
  stroke-linecap:round;stroke-linejoin:round;opacity:0}
.q-opt[aria-pressed="true"] .q-box svg{opacity:1}
.q-opt-t{font-weight:600;color:var(--navy)}
.q-opt-s{display:block;font-weight:400;font-size:15px;color:rgba(46,44,40,.75);margin-top:2px}

/* image tiles, router only */
.q-tiles{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:28px}
@media(min-width:640px){.q-tiles{grid-template-columns:repeat(3,1fr)}}
.q-tile{position:relative;overflow:hidden;border-radius:var(--r-card);
  border:1px solid var(--line);background:var(--s1);cursor:pointer;
  font:inherit;color:inherit;padding:0;aspect-ratio:4/3;
  display:flex;align-items:flex-end;min-height:9.5rem;
  transition:border-color .15s,transform .2s}
/* Two tiles per row on a phone is 160px of width for a label plus a line
   of description. A fixed 4:3 box cannot hold that, so below 640 the
   tile grows to fit its label instead. */
@media(max-width:639px){.q-tile{aspect-ratio:auto;min-height:10.5rem}}
.q-tile:hover{transform:translateY(-2px)}
/* The press is the feedback. It happens on the thing that was pushed,
   which is the only place the eye is looking. */
.q-tile:active{transform:scale(.985)}
.q-tile[aria-pressed="true"]{border-color:var(--green-ui);box-shadow:0 0 0 2px var(--green-ui)}
.q-tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* Bottom-weighted scrim, not a flat wash. A flat wash dulls the whole
   photograph and still leaves the label unreadable over a bright sky.
   Same gradient logic as the header50 heroes. It does not lighten when
   the tile is selected: the green ring is the selected state, and
   fading the scrim would take the label with it. */
.q-tile::after{content:"";position:absolute;inset:0;background:linear-gradient(
  to top,rgba(var(--scrim),.86) 0%,rgba(var(--scrim),.62) 34%,
  rgba(var(--scrim),.24) 66%,rgba(var(--scrim),.14) 100%)}
/* In flow, not absolute, so a long label pushes the tile taller rather
   than spilling out of the top of it. */
.q-tile span{position:relative;z-index:2;width:100%;padding:14px;
  font-weight:600;color:#fff;text-align:left;line-height:1.25;
  text-shadow:0 1px 3px rgba(9,14,30,.45)}
.q-tile.plain{aspect-ratio:auto;min-height:5.5rem;background:var(--s4)}
.q-tile.plain::after{display:none}
.q-tile.plain span{color:var(--navy);padding:18px;text-shadow:none}

/* rating rows */
.q-rate{display:grid;gap:10px;margin-bottom:28px}
.q-rate-row{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:12px 16px;background:var(--s1);border:1px solid var(--line);border-radius:var(--r-card)}
.q-rate-row>span{font-weight:600;color:var(--navy)}
.q-dots{display:flex;gap:6px;flex:none}
.q-dot{width:30px;height:30px;border-radius:50%;border:1.5px solid rgba(27,42,87,.3);
  background:#fff;cursor:pointer;font:inherit;font-size:13px;font-weight:600;
  color:rgba(46,44,40,.6);display:grid;place-items:center;padding:0}
.q-dot[aria-pressed="true"]{background:var(--green-ui);border-color:var(--green-ui);color:#fff}

/* free text */
.q-text,.q-note{width:100%;font:inherit;font-size:16px;color:var(--ink);
  background:var(--s1);border:1px solid var(--line);border-radius:var(--r-btn);
  padding:14px;resize:vertical}
.q-text{min-height:9rem;margin-bottom:28px}
.q-note{min-height:5rem;margin:-12px 0 28px}
.q-note-label{display:block;font-size:15px;font-weight:600;color:var(--navy);margin-bottom:8px}
.q-text:focus-visible,.q-note:focus-visible,.q-opt:focus-visible,.q-tile:focus-visible,
.q-dot:focus-visible{outline:2px solid var(--green-ui);outline-offset:2px}

/* nav */
.q-nav{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.q-back{background:none;border:0;padding:8px 0;font:inherit;font-weight:600;
  color:rgba(46,44,40,.7);cursor:pointer}
.q-back:hover{color:var(--navy)}
.q-skip{margin-left:auto;background:none;border:0;padding:8px 0;font:inherit;
  font-size:15px;color:rgba(46,44,40,.6);cursor:pointer;text-decoration:underline;
  text-underline-offset:3px}

/* ---------- the sample trip ----------
   Set as an editorial page rather than as form output. It has to read
   like something a person wrote, because that is what it is standing in
   for and what the next screen is asking them to pay attention to. */
.q-sample{animation:qin .3s ease-out}
.q-sample-lead{font-family:var(--serif);font-size:clamp(19px,2vw,22px);line-height:1.5;
  color:var(--navy);margin-bottom:32px}
.q-days{list-style:none;margin:0 0 28px;padding:0;
  border-left:2px solid var(--sand);padding-left:24px;display:grid;gap:26px}
.q-day{position:relative}
.q-day::before{content:"";position:absolute;left:-31px;top:7px;width:10px;height:10px;
  border-radius:50%;background:var(--green-ui);box-shadow:0 0 0 4px var(--s6)}
.q-day-n{font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--green-ui);margin-bottom:4px}
.q-day-w{font-family:var(--serif);font-size:21px;color:var(--navy);margin-bottom:6px}
.q-sample-close{padding:18px 20px;background:var(--sand);border-radius:var(--r-card);
  color:var(--navy);margin-bottom:20px}
.q-fix{margin:0 0 24px}
.q-fix label{display:block;font-size:15px;font-weight:600;color:var(--navy);margin-bottom:8px}
.q-fix textarea{width:100%;min-height:6.5rem;font:inherit;color:var(--ink);
  background:#fff;border:1px solid var(--line);border-radius:var(--r-input);
  padding:14px;resize:vertical}

/* waiting on the model. A bar that moves, so a slow answer does not
   read as a broken page. */
.q-load{padding:12px 0 32px}
.q-load-bar{height:3px;border-radius:2px;background:var(--s4);overflow:hidden;margin-bottom:14px}
.q-load-bar span{display:block;height:100%;width:35%;border-radius:2px;
  background:var(--green-ui);animation:qslide 1.5s ease-in-out infinite}
@keyframes qslide{0%{margin-left:-35%}100%{margin-left:100%}}
.q-load-txt{color:rgba(46,44,40,.7)}
@media(prefers-reduced-motion:reduce){
  .q-sample{animation:none}
  .q-load-bar span{animation:none;width:100%;opacity:.5}
}

/* capture */
.q-fields{display:grid;gap:18px;margin-bottom:24px}
@media(min-width:640px){.q-fields{grid-template-columns:1fr 1fr}}
.q-field{display:grid;gap:8px}
.q-field.wide{grid-column:1/-1}
.q-field label{font-size:15px;font-weight:600;color:var(--navy)}
.q-field input{font:inherit;font-size:16px;width:100%;color:var(--ink);background:var(--s1);
  border:1px solid var(--line);border-radius:var(--r-btn);padding:13px 14px}
.q-field input:focus-visible{outline:2px solid var(--green-ui);outline-offset:2px}
.q-consent{display:flex;align-items:flex-start;gap:12px;margin-bottom:14px}
.q-consent input{flex:none;width:18px;height:18px;margin-top:3px;accent-color:var(--green-ui)}
.q-consent label{font-size:14px;line-height:1.55}
.q-consent a{color:var(--navy);text-decoration:underline;text-underline-offset:3px}
.q-fine{font-size:14px;line-height:1.55;color:rgba(46,44,40,.75);margin-bottom:24px}

/* done */
.q-done{text-align:center;max-width:34rem;margin-inline:auto;padding:24px 0}
.q-done h2{margin-bottom:16px}
.q-done p{margin-bottom:12px}

/* ================= reveal on scroll =================
   Headlines, images and cards fade up thirty pixels as they come into
   view. One shot: nothing re-hides on the way back up.

   WHY THERE IS NO FLASH OF HIDDEN CONTENT, because it is not obvious.
   The hiding below is gated on html[data-anim], and a one-line script in
   each page's <head> sets that attribute before anything paints. With
   JavaScript off the attribute is never set, every rule here is inert,
   and the site is completely visible. That is also why the attribute is
   set inline in the head rather than from site.js, which loads at the
   end of the body and would hide content that had already painted.

   THE CONTRACT: this stylesheet hides everything in the list below, and
   assets/site.js is then responsible for revealing every single one of
   them, either on scroll or immediately. Add a selector here and you
   must add it to REVEAL in site.js. If site.js throws, it strips
   data-anim off <html> and the whole page reappears.

   Scoped to .sect throughout, which is doing real work: it excludes the
   heroes (so the headline you came for is never delayed), the navbar,
   the footer, the cookie banner, and the quiz, none of which are .sect.
   The three legal pages are excluded a different way: they never get the
   head script at all.
==================================================== */
/* :where(), not :is(). :is() takes the specificity of its most specific
   arm, which here is .sect .head-wrap, so the hiding rule outweighed the
   .rv-in rule that reveals things and nothing ever appeared. :where()
   contributes nothing, leaving this at html[data-anim] alone so .rv-in
   comfortably wins. */
html[data-anim] :where(
  .sect .head-wrap,
  .sect .ph,
  .sect .card,
  .sect .bgcard,
  .sect .theme-card,
  .sect .t503-card,
  .sect .l359-card,
  .sect .quote,
  .sect .gal a,
  .sect .split > div,
  .sect .cta,
  /* Trip types is a sticky stack with no .sect wrapper, so none of the
     rules above reached it. Scoped to .stack-body deliberately: a transform
     on .stack-item would make it a containing block and break the sticky
     bar it holds. Keep in step with REVEAL in site.js. */
  .stack-body .ph,
  .stack-body .split > div
){
  opacity: var(--rv-o, 0);
  transform: var(--rv-t, translateY(30px));
  transition: opacity var(--rv-t-dur, .85s) cubic-bezier(.22,.61,.36,1) var(--rv-d, 0ms),
              transform var(--rv-t-dur, .85s) cubic-bezier(.22,.61,.36,1) var(--rv-d, 0ms);
}
html[data-anim] .rv-in{opacity:1;transform:none}
/* things that were already on screen at load, or that sit inside something
   else that animates. No transition, so they are simply there. */
html[data-anim] .rv-now{transition:none}

/* One switch for the whole thing. The two custom properties are inherited
   from html, so the selector list above does not have to be repeated. */
@media(prefers-reduced-motion:reduce){
  /* Three variables, all inherited from html, so the selector list above
     never has to be repeated. --rv-t-dur matters as much as the other
     two: without it the properties are still transitionable, and any
     later change to them would animate for somebody who asked for no
     animation. */
  html[data-anim]{--rv-o:1; --rv-t:none; --rv-t-dur:0s}
}
