/* Journeys with JB — shared site behaviour (added v212).
   Loaded on every page after tokens.css and the shared sheets, before each
   page's own inline styles. Holds the rules that must be identical everywhere. */

/* ─── SCROLL-REVEAL HEADER ───────────────────────────────────────────────
   The header slides out of the way while you read down the page and comes
   back the moment you scroll up, so photography is never sitting behind a
   permanent bar. Driven by js/nav-reveal.js, which adds .nav-hidden. */

header[role="banner"] {
  transition: transform var(--dur-base) var(--ease-out);
}

header[role="banner"].nav-hidden {
  transform: translateY(-100%);
}

/* An open mobile menu lives inside the header, so the script never hides the
   header while it is open. This is the belt-and-braces CSS half of that. */
header[role="banner"].nav-menu-open {
  transform: none;
}

/* Anchor links (the guide tables of contents) must not drop a heading
   underneath the header. 64px nav plus a little breathing room. */
html {
  scroll-padding-top: 78px;
}

@media (prefers-reduced-motion: reduce) {
  header[role="banner"] { transition: none; }
}


/* ─── SCROLL REVEAL ──────────────────────────────────────────────────────
   Moved here from shared-home.css in v218. It used to live in the homepage
   stylesheet, so the nine guide and itinerary pages had no entry motion at
   all: the homepage breathed and then a guide felt like an older site.
   site.css is loaded by all sixteen pages, so this is now the one definition.

   Two things changed at the same time. The travel was 28px over 0.7s, which
   is far enough and slow enough that the eye follows the block instead of
   reading it. It is now 14px over 400ms on the site's ease-out.

   Nothing here is applied until JavaScript adds the class, so a page whose
   script fails still shows all of its content. */

.reveal {
  opacity: 0;
  transform: translateY(var(--reveal-shift));
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
}

.reveal.reveal-left  { transform: translateX(calc(var(--reveal-shift) * -1)); }
.reveal.reveal-right { transform: translateX(var(--reveal-shift)); }

.reveal.visible {
  opacity: 1;
  transform: translate(0, 0);
}

/* Stagger stays small on purpose. A long staggered list makes a page feel
   slow to load even when it is not, so this tops out at two steps and the
   steps are short. */
.reveal-delay-1 { transition-delay: 60ms; }
.reveal-delay-2 { transition-delay: 120ms; }
.reveal-delay-3 { transition-delay: 120ms; }

/* v218: this fallback did not exist. Someone who has asked their computer for
   less motion was still getting a fade and a slide on every section of the
   homepage and the About page. The content must still appear, so this cannot
   be `animation: none` on its own: .reveal starts at opacity 0, and without
   the visible state being forced here it would stay invisible. */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal.reveal-left,
  .reveal.reveal-right {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .reveal-delay-1,
  .reveal-delay-2,
  .reveal-delay-3 { transition-delay: 0s; }
}


/* ─── HEADING WEIGHTS ────────────────────────────────────────────────────
   The floor for every heading on the site. Headings that no page rule
   touches used to fall through to the browser's own bold, which is why a
   handful of section titles and every footer heading rendered at 700 while
   their neighbours sat at 400. The per-page rules that do set a weight now
   all carry these same four values, so this is a floor and not a fight. */
/* v265: tracking joins weight as a floor, for the same reason. All 20 page
   titles render at an identical 64px / 500 / Cormorant, but they are built
   through six different wrappers (.hero h1, .guide-title, .itin-title,
   .page-title, .policy-hero h1, and a bare h1), so there was nowhere for a
   single value to live and they had drifted into three. `body h1` is that
   place. Specificity is (0,0,2), so any page rule that genuinely needs to
   opt out still can, without !important and without editing this line. */
body h1 { font-weight: var(--h1-weight); letter-spacing: var(--display-tracking); }
body h2 { font-weight: var(--h2-weight); }
body h3 { font-weight: var(--h3-weight); }
body h4 { font-weight: var(--h4-weight); }

/* The five headings below are set in Marcellus, which is published in one
   weight only. The footer column headings were asking it for 700 and the
   itinerary sub-headings for 600, which is asking for something that does not
   exist. Measured, Marcellus draws at exactly the same width from 300 through
   800, so the browser is quietly ignoring those numbers rather than smearing
   the one cut it has. Nothing was rendering wrongly.

   The rule stays anyway, for two reasons. It states what is actually drawn
   instead of leaving a number in the file that reads like a design decision
   and is not one. And if Marcellus ever fails to load, these headings fall
   through to Georgia, which does ship a real bold, so 700 would suddenly
   become genuinely bold on exactly the five places that never wanted it. */
body .footer-col h3,
body .day-question,
body .narrative-section h3,
body .also-label,
body .related-content-label {
  font-weight: 400;
}


/* ─── TEXT SITTING ON PHOTOGRAPHY ────────────────────────────────────────
   The eyebrows, subtitles and badges in the heroes were all set in white at
   65 to 86 percent opacity. On a dark background that reads as a soft, elegant
   grey. On a photograph it reads as whatever is behind it, and behind these
   ones is a mid-tone landscape, so the words were sinking into the scenery.

   Solid white plus the deeper scrim in tokens.css fixes it without a text
   shadow, which would have smudged the letterforms. The badges also carried a
   translucent white pill, which was brightening the very patch of picture the
   white text needed to stand out from, so those go dark instead.

   v215: this rule was written for heroes that sit on a photograph, but the
   #hero selector matched every page that uses that id, and on Services, the
   Budget Translator and the Points Calculator that id sits on flat cream
   (background: var(--bone)). Those three were painting white on cream at about
   1.2:1, which is invisible. Each of those pages already sets the correct dark
   colour itself; this rule was simply outranking it. Scoping to .hero-photo,
   which only the homepage hero carries, leaves the homepage exactly as it was
   and hands the other three back to their own styling. */
/* v264: two selectors left this group when the hero eyebrows were thinned from
   eighteen pages to six. `.guide-eyebrow` had exactly four users — Caribbean,
   Honeymoon Hotels, Iceland and Sports Travel — and all four dropped it, so the
   class no longer exists anywhere in the build. `#hero.hero-photo .hero-eyebrow`
   was scoped to the homepage, which is the only `.hero-photo` on the site (the
   comment above explains why it is scoped that way), and the homepage dropped
   its eyebrow too. `.itin-eyebrow` STAYS: the four itineraries keep theirs,
   because "Sample Itinerary" is load-bearing. `.hero-eyebrow` unscoped also
   survives on the Budget Translator and the Points Calculator, but neither is a
   `.hero-photo` page, so it was never this rule that coloured them. */
body .itin-header .itin-eyebrow,
body .itin-header .itin-subtitle,
body .guide-hero .guide-subtitle,
body #hero.hero-photo .trust-link,
body .itin-header .badge,
body .guide-hero .badge {
  color: #fff;
}

body .itin-header .badge,
body .guide-hero .badge {
  background: rgba(30, 24, 18, 0.42);
  border-color: rgba(255, 255, 255, 0.5);
}


/* ─── LINE LENGTH ON CAPTIONS AND FINE PRINT ─────────────────────────────
   Added v215. The smallest text on the site was carrying the longest lines,
   which is backwards: small type needs short measures, not long ones.
   Measured at 1440 before this rule, a photo caption on the Atacama page ran
   158 characters, the partner note ran 138 on six pages, and the calculator
   disclaimer ran 283 across the full width of the window.

   None of these blocks are in the v213 full-measure list, so this does not
   touch the decision made then. v213 deliberately removed the caps from
   running prose on the guide pages so it lines up with the photograph above
   it. Captions and fine print were never part of that; they simply never had
   a cap in the first place, or in the case of .partner-note had one written
   in pixels that did not do much. That note already carried max-width: 680px
   and it was not being ignored: EB Garamond at 13px averages 4.93px a
   character, so 680px genuinely holds 138 of them. A cap in pixels says
   nothing about how many words land on the line, which is the whole reason
   the v207 work chose em.

   Reusing that same calibration rather than inventing a new number. v207
   measured JB's own copy at eight widths: 42em gave 107 characters, 36em
   gave 91, 32em gave 81, 28em gave 71. Running prose stayed at 28em. Fine
   print and captions can run a little longer than body copy without
   becoming hard to track, so 36em, about 91 characters.

   .budget-hint is deliberately absent. It is already in the v207 28em list
   on every page, and naming it here would have widened it to 36em, which is
   the opposite of the point. */
body .partner-note,
body .guide-caption,
body .calc-disclaimer,
body .estimates-disclaimer,
body .virtuoso-explainer,
body .photo-caption,
body .intro-img-caption {
  max-width: 36em;
}

/* The centred ones need the auto margins back, since a max-width alone would
   pin them to the left of a block that is trying to centre its text. */
body .partner-note,
body .calc-disclaimer,
body .estimates-disclaimer,
body .virtuoso-explainer {
  margin-left: auto;
  margin-right: auto;
}


/* ─── INQUIRY BUTTONS ON NARROW SCREENS ──────────────────────────────────
   These carry an uppercase label with wide letter-spacing inside generous
   side padding. On a phone that combination leaves so little room for the
   text that the label stacked three and four lines deep, and on the About
   page it pushed straight out of the button. Trimming the padding and the
   letter-spacing below 700px gives the words room without changing how the
   buttons look on a laptop.

   Each page carries its own style block after this file, so these rules are
   scoped to `body` to win on specificity rather than on order. */
@media (max-width: 700px) {
  body .inquire-btn,
  body .cta-btn,
  body .cta-button,
  body .btn-gold,
  body .hero-btn,
  body .btn-spotlight,
  body .svc-card-cta,
  body .pkg-cta,
  body .guides-callout-btn,
  body .form-submit,
  body .btn-cta-primary {
    padding-left: 18px;
    padding-right: 18px;
    letter-spacing: 0.07em;
    white-space: normal;
    text-wrap: balance;
    overflow-wrap: break-word;
  }

  /* v265: the four itinerary pages wrap "Start Planning Your Journey" onto two
     lines at 390px. The button is not the problem. The identical button with
     the identical label sits on one line inside .guide-cta on the guide pages,
     because that box is 24px wider. .cta-bar keeps its full 32px desktop side
     padding on a phone, which leaves the button 262px to render a label that
     needs 265. Trimming the sides to 20px below 700px gives it 286px, so the
     label fits with room to spare rather than by a hair. Vertical padding and
     every other screen size are untouched. */
  body .cta-bar {
    padding-left: 20px;
    padding-right: 20px;
  }
}

/* On the narrowest phones the box fix above is not enough on its own. "Start
   Planning Your Journey" is the longest label on the site and needs 265px; a
   375px iPhone SE leaves 263px inside .guide-cta, so it wrapped there too.
   Tightening the tracking and the side padding a little further on this one
   button buys about 22px and carries a single line down to 360px, which covers
   every Android and iPhone still in common use. At 320px the label genuinely
   will not fit and wrapping to two balanced lines is the right outcome. Only
   .inquire-btn is touched, because no other button carries a label this long. */
@media (max-width: 420px) {
  body .inquire-btn {
    padding-left: 12px;
    padding-right: 12px;
    letter-spacing: 0.04em;
  }
}


/* ─── KEYBOARD FOCUS ─────────────────────────────────────────────────────
   Someone navigating by keyboard needs to see where they are. This rule
   already existed, word for word, but only on six of the sixteen pages, so
   the other ten fell back to whatever ring the browser happened to draw, or
   to none at all on the print buttons and the quiz controls.

   :focus-visible rather than :focus, so the ring appears for keyboard and
   assistive-technology users and not for anyone clicking with a mouse. */
body a:focus-visible,
body button:focus-visible,
body input:focus-visible,
body select:focus-visible,
body textarea:focus-visible,
body [tabindex]:focus-visible {
  outline: 2px solid var(--sage, #5E6E4A);
  outline-offset: 2px;
  border-radius: 2px;
}


/* ─── TAP TARGET SIZE ────────────────────────────────────────────────────
   Measured on a 390px iPhone viewport, these controls were all shorter than
   the 44px a fingertip needs. Every one of them was short in height only,
   never in width, so a minimum height is enough and nothing has to get wider.

   The labels are unchanged. inline-flex with centred items means the extra
   height goes above and below the words rather than pushing them off centre.

   Two things are deliberately left alone:
     - the 44 pins on the About page world map, which are 34px. Making them
       44px would overlap neighbouring countries, and the accessibility rules
       exempt a target whose position is fixed by the map it sits on.
     - links inside sentences, which are exempt for the same reason: you
       cannot move a word out of its paragraph to give it more room. */
body .footer-email,
body .back-print-row a,
body .print-btn,
body .sort-select,
body .services-preview-cta,
body .partner-trust-badge,
body .spotlight-itinerary-link,
body .reviews-cta-link {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

/* The logo cannot use the rule above. Its markup is
   `Journeys <span>with JB</span>`, and a flex container turns the bare words
   and the span into two separate flex items, which throws away the single
   space that sits between them. The logo rendered as "Journeyswith JB" in the
   top left corner of all 16 pages. Measured, the word was 129.41px wide before
   and 124.55px after, and that 4.86px is the missing space.

   A line box 44px tall gives the same finger-sized target without making the
   logo a flex container, so the space survives. Measured back to 129.41px. */
body .nav-logo {
  min-height: 44px;
  display: inline-block;
  line-height: 44px;
}


/* ─── ABOUT PAGE GALLERY ARROWS ──────────────────────────────────────────
   History, because it explains why this rule looks thin now.

   The two carousel arrows used to be the text characters back-arrow and
   forward-arrow rather than pictures. None of the site's three fonts contains
   an arrow glyph, so the browser substituted silently and the shape a visitor
   saw depended on their machine. The fix at the time was to name a font stack
   known to carry the glyph, which is how Arial ended up here: the only
   non-house font anywhere on the site, and the thing every design audit since
   has flagged. v217 then added 18px and --muted-text because the buttons were
   otherwise falling through to the browser default of 13.33px in pure black.

   v259: the arrows are inline SVG paths now, so there is no glyph to
   substitute and no font stack to name. Arial is gone. font-size and
   line-height went with it, since neither reaches a drawn path.

   What stays is the colour. shared-home.css has a `.gallery-nav-btn svg` rule
   that strokes in var(--muted); about.html overrides that to currentColor so
   the arrows inherit the value below instead, which is the one measured
   against .gallery-counter sitting between the two buttons (5.50:1 on
   warmwhite). Keep them in step if either ever moves. */
body .gallery-nav-btn {
  color: var(--muted-text);
}

/* ═══════════════════════════════════════════════════════════════════
   v222 · FULL-BLEED PHOTOGRAPH BAND
   ═══════════════════════════════════════════════════════════════════

   The audit finding this answers: every photograph on the about page was
   the same shape (2:3) in the same rounded box inside the same 1200px
   container, and every photograph on the guides page was the same shape
   (roughly square) in the same card. Twelve identical frames and eleven
   identical frames. A page where every image is the same size in the same
   box reads as a template that had pictures poured into it, which is
   precisely the thing JB could feel but could not name.

   One photograph per page now runs edge to edge at a wide crop. It is the
   only element on either page that touches both sides of the screen, so it
   works as a breath between two blocks of content and it breaks the "every
   image lives in a box" pattern by existing.

   On the technique: this is width:100% on a body-level section, NOT the
   usual 100vw plus negative margin trick. 100vw includes the scrollbar
   gutter on Windows and desktop Linux, so that method reliably produces a
   few pixels of horizontal scroll on exactly the machines nobody tests on.
   Placing the band outside .container instead gets the same result with no
   arithmetic and no overflow, at the cost of the band having to be a
   sibling of the sections rather than a child. That is a fair trade.

   Height is a clamp rather than an aspect-ratio so the band stays a band on
   a phone. At a fixed ratio a 2.4:1 crop becomes 162px tall at 390px wide,
   which is a stripe, not a photograph. The clamp floor of 240px keeps it
   readable as an image on a phone and lets object-fit do the cropping. */

/* On the background: this needs stating explicitly, and the first version of
   this rule got it wrong. Because the band deliberately sits OUTSIDE any
   <section>, it has no section ground beneath it, and a transparent figure
   falls all the way through to <body>. On about.html <body> is --oat, so the
   caption rendered on a tan strip cutting across a warmwhite run. Both bands
   currently land inside a warmwhite stretch, so warmwhite is the default. A
   band placed in a cream or bone run must override this per page.

   On the padding: the band is a breath, and a breath needs air above it.
   .about-page-body ends on 20px and the guides grid on 56px, neither of which
   is enough for a photograph to arrive on. --section-pad-tight adds the site's
   own smallest rhythm stop and shrinks with it at 900px and 680px. It is
   top-only: the caption already closes the band, and the section below opens
   on 96px of its own. */
.photo-bleed {
  display: block;
  width: 100%;
  margin: 0;
  padding: var(--section-pad-tight) 0 0;
  background: var(--warmwhite);
  overflow: hidden;
  line-height: 0;
}

/* --oat here is only a holding colour behind the image while it loads, so a
   lazy band never flashes as a white gap. It is not the caption's ground. */
.photo-bleed img {
  display: block;
  background: var(--oat);
  width: 100%;
  height: clamp(240px, 34vw, 460px);
  object-fit: cover;
  margin: 0;
  border-radius: 0;
  box-shadow: none;
}

/* The caption sits under the photograph on the page ground, not over the
   image. Text laid over a photograph needs a scrim, a scrim needs tuning
   per image, and the site already does that once in the index hero. Doing
   it twice more for a decorative band is how a scrim ends up at three
   different opacities. Marcellus at the label size, on the middle tracking
   stop, matching .photo-credit on the index. */
.photo-bleed figcaption {
  font-family: var(--font-subtitle);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-text);
  line-height: 1.5;
  text-align: center;
  padding: 14px 24px 0;
}

@media (max-width: 680px) {
  .photo-bleed figcaption { padding-top: 11px; }
}

/* ── HEADING LINE BREAKS (v246) ──────────────────────────────────────────────
   Six headings on the site carry a hardcoded <br>. Three of them broke badly
   once the browser ALSO had to wrap the text: the index hero stranded "same."
   on an 86px line at 390px, the About h1 stranded "JB." on 49px, and the
   services h2 stranded "thinking…" on 191px — that last one on DESKTOP as
   well as on a phone.

   Measured, not guessed. Both properties were run against every h1/h2/h3 on
   all 20 pages at 1440 / 390 / 360 and the line-box widths compared:

     heading                    baseline @390    balance        pretty
     index h1.hero-title        282 / 86 / 187   152/216/187 ✓  227/140/187 ✓
     about.html h1              260 / 318 / 49   unchanged  ✗   260/243/124 ✓
     services h2.section-title  310 / 117 / 342  208/219/342 ✓  unchanged  ✗

   Neither property fixes all three, hence the split below. `balance` equalises
   every line and handles a bad break in the FIRST segment of a heading; it is
   what the services h2 needs. `pretty` only reflows the last line of the block,
   which is exactly the About h1's problem and is the one case balance will not
   touch. Both degrade silently to normal wrapping in a browser that lacks them.

   The full sweep recorded 9 changed headings sitewide and ZERO regressions —
   no heading gained an orphan and none started overflowing its box.

   ⚠️ DO NOT "simplify" this by hiding the <br> in CSS. `h1 br { display: none }`
   renders "Meet Jea, the onebehind Journeys with JB." — there is no whitespace
   either side of the tag in the source, so the <br> is doing the word break.
   That was tried in a browser during v246 and produced exactly that string. */
h1.hero-title,
h2.section-title { text-wrap: balance; }

.about-hero-inner h1 { text-wrap: pretty; }

/* Card CTAs wrap badly in the narrowest column they ever occupy. Measured on
   index.html at 1440, where four tiers share the row and each button is 219px:
   "Plan This Trip With Me" broke to 182px + 25px, leaving "Me" alone on the
   second line, and "Start Planning Your Journey" broke 195/77 at 1100. The
   same buttons already get `text-wrap: balance` below 700px for the same
   reason (see INQUIRY BUTTONS ON NARROW SCREENS above) — the squeeze just
   isn't only a phone problem, so the rule is lifted out of that breakpoint.
   Single-line labels are unaffected; balance does nothing until text wraps. */
.svc-card-cta,
.pkg-cta { text-wrap: balance; }

/* ── TOOLS DROPDOWN IN THE MAIN NAV (v246) ──────────────────────────────────
   The Budget Translator and the Points Calculator were footer-only. They are
   two of the strongest things on the site and most visitors never saw them.
   They now sit behind a "Tools" item in the top nav on all 20 pages.

   ⚠️ WHY NEW CLASS NAMES INSTEAD OF THE EXISTING `.nav-dropdown`.
   A complete dropdown component — `.nav-dropdown`, `.nav-dropdown-toggle`,
   `.nav-dropdown-menu`, caret, hover state, `.open` state — already exists on
   this site, left behind by a removed "Resources" menu. It is dead code: zero
   pages carry the markup. It was NOT reused because its copies are scattered
   and unequal. The CSS lives inline on 16 pages and in `shared-home.css` for
   the other 3, iceland-guide carries a partial copy, and the matching JS is
   inline on 19 pages but ABSENT on iceland-guide and different on services.
   Reusing the name would mean the shared definition below losing to whichever
   inline copy a page happens to hold, and the JS binding twice on 19 pages —
   two clicks, so the menu would open and instantly shut. Fresh names sidestep
   all of it: one definition here, one handler in `js/nav-reveal.js`, identical
   behaviour on every page. Visual spec is copied from the old component so it
   still looks native. If the dead `.nav-dropdown` code is ever swept up, this
   is unaffected. */
.nav-tools { position: relative; }

.nav-tools-toggle {
  font-family: var(--font-subtitle);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-text);
  cursor: pointer;
  background: none;
  border: none;
  outline: none;
  line-height: 1;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 0;
  transition: color var(--dur-base) var(--ease-out);
}

.nav-tools-toggle:focus-visible {
  outline: 2px solid var(--sage);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Drawn with borders rather than set as a character. None of the three brand
   typefaces carries an arrow glyph — the same reason the About gallery arrows
   fall back to Arial — so a text caret would render differently per machine. */
.nav-tools-toggle::after {
  content: '';
  display: inline-block;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid currentColor;
  transition: transform var(--dur-base) var(--ease-out);
}

/* v247: matches any aria-current value, not just "page". The toggle is a
   <button> with no href, so it can never BE the current page; it only contains
   it. Its correct value is "true", and pinning this selector to "page" would
   have silently dropped the sage highlight on the Tools item the moment that
   was corrected. */
.nav-tools:hover .nav-tools-toggle,
.nav-tools.open .nav-tools-toggle,
.nav-tools-toggle[aria-current] { color: var(--sage-dk); }

.nav-tools.open .nav-tools-toggle::after { transform: rotate(180deg); }

.nav-tools-menu {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  background: #fff;
  border: 1px solid var(--sand);
  border-radius: 8px;
  box-shadow: var(--shadow-card, 0 8px 24px rgba(68,57,45,0.10));
  min-width: 210px;
  list-style: none;
  margin: 0;
  padding: 0;
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(-6px);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
  z-index: 200;
}

.nav-tools.open .nav-tools-menu {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

/* Hover-to-open is fenced off to real pointers. Without the guard a phone
   applies :hover on tap and keeps it applied until you tap somewhere else, so
   a second tap on "Tools" would close the menu in JavaScript while the stuck
   :hover reopened it — the menu would refuse to shut. */
@media (hover: hover) and (pointer: fine) {
  .nav-tools:hover .nav-tools-menu {
    opacity: 1;
    pointer-events: auto;
    transform: translateX(-50%) translateY(0);
  }
}

/* Bridges the 14px gap between the toggle and the panel so a diagonal mouse
   travel does not drop out of :hover halfway and shut the menu. */
.nav-tools-menu::before {
  content: '';
  position: absolute;
  top: -15px;
  left: 0;
  right: 0;
  height: 15px;
}

.nav-links .nav-tools-menu a {
  display: block;
  padding: 11px 18px;
  font-family: var(--font-subtitle);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-text);
  border-bottom: 1px solid var(--sand);
  white-space: nowrap;
  transition: color var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out);
}

.nav-links .nav-tools-menu li:last-child a { border-bottom: none; }

.nav-links .nav-tools-menu a:hover,
.nav-links .nav-tools-menu a:focus-visible { color: var(--deep); background: var(--cream); }

.nav-links .nav-tools-menu a[aria-current="page"] { color: var(--sage-dk); }

@media (prefers-reduced-motion: reduce) {
  .nav-tools-toggle::after,
  .nav-tools-menu { transition: none; }
}

/* The mobile sheet is a flat list, so the two tools are plain links there with
   a quiet group label above them rather than a second nested menu to tap open. */
.nav-mobile-label {
  font-family: var(--font-subtitle);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--stone, #C8BBA6);
  padding-top: 4px;
}


/* ─── FOOTER INQUIRY LINK (v248) ─────────────────────────────────────────
   Until v248 the footer was the one part of the site that never asked for
   the business. It offered an email address, the Fora and Virtuoso profile
   links, five navigation links and the social icons, and on all 20 pages it
   offered no way at all to reach the inquiry form. The footer is where every
   scroll ends, so that was the weakest possible last word.

   Four pages had no closing CTA anywhere above the footer either, which made
   the gap a real dead end rather than a missed reinforcement: privacy-policy,
   points-calculator, budget-translator (its only CTA sits inside the results
   panel, so it does not exist until the tool is finished) and services.

   ⚠️ Deliberately a compact outlined link, NOT a full-width CTA band. Two
   reasons, both on the record. Sixteen of the twenty pages already close with
   a CTA immediately above the footer, and stacking a second loud one directly
   beneath it would read as nagging. And services.html's bottom "Ready to
   Start?" band was removed at JB's request in v189 — standards §14 says do
   not re-add it without her asking, and a quiet footer link is not that band.

   The label is "Start Planning Your Journey", the approved general-close
   phrase. Not a third phrase — see §14, both approved phrases are in use and
   there is no spare. */
body .footer-cta-wrap {
  margin: 14px 0 4px;
}

body .footer-cta {
  display: inline-flex;
  align-items: center;
  /* v262: was 44px at 10px/24px padding, in --font-display. Two things were
     wrong and one thing was right.

     Wrong: the height. The homepage carried six button heights (35, 44, 48,
     52, 58, 72) and this was the 44. It is now 52px, the DESIGN.md Marquee
     height that every other "start planning" button on the site uses.

     Wrong: the family. DESIGN.md says buttons are Marcellus, and the site's
     other sage buttons all use --font-subtitle. This one asked for
     --font-display, which resolves to Cormorant Garamond — the body serif. It
     was the only button on the site not in the label face, which is why it
     read as a caption with a box around it rather than as a button.

     Right, and kept: the outline. DESIGN.md defines a secondary button as
     "outlined 1px in sage on the paper ground, with sage-deep text", and this
     is the quiet repeat at the bottom of all 20 pages, not a second primary
     ask. The four service CTAs went solid in v262 because they are genuine
     conversion points. This one is not, and making it solid would put the
     loudest object on the page beside a copyright line.

     Blast radius: all 20 pages, so site.css bumps. */
  min-height: 52px;
  /* 14px vertical, not 15px: the 1px border top and bottom makes up the
     difference, so this lands on 52 like every other button. */
  padding: 14px 28px;
  border: 1px solid var(--sage, #5E6E4A);
  border-radius: 2px;
  font-family: var(--font-subtitle, 'Marcellus', Georgia, serif);
  /* v258: was 12px / 0.14em, and it was the only text on the whole site at
     either value. Two DESIGN.md rules, both broken by one declaration:
     the Thirteen Floor Rule ("13px is the smallest type on the site at every
     screen width. There is no 12px") and the Three Stops Rule (tracking is
     0.08em, 0.12em or 0.16em, and no others). --text-xs IS 13px, so this is
     now on the ladder instead of beside it. This button sits in the footer of
     all 20 pages, which is why site.css goes to ?v=258 everywhere. */
  font-size: var(--text-xs, 13px);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sage-dk, #4A5A3A);
  text-decoration: none;
  background: transparent;
  transition: background-color 200ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
              color 200ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}

body .footer-cta:hover,
body .footer-cta:focus-visible {
  background: var(--sage, #5E6E4A);
  color: var(--bone, #FBF8F3);
}


/* ─── TAP TARGETS, SECOND PASS (v248) ────────────────────────────────────
   Three controls were still under the 24px WCAG 2.5.8 AA floor after the
   pass above. Two of them sit on all 20 pages, so they were the most
   repeated accessibility fault on the site.

   Measured at 1440 on the live v247 build:
     .trust-link   "Powered by Fora Travel"  125 x 15
     .trust-link   "Virtuoso Affiliate"       91 x 15
     footer-bottom "Privacy Policy"          127 x 15

   These three could not join the min-height list above. All three sit inside
   a running line of text — the footer-meta line reads "Journeys with JB ·
   Powered by Fora Travel · Virtuoso Affiliate" — and giving an inline element
   a 44px min-height grows the line box and pushes the footer layout around.

   So the hit area is grown with an absolutely positioned overlay instead,
   which is the one technique that adds finger room while changing nothing
   about how the page looks. Nothing moves by a single pixel; only the
   clickable rectangle gets taller. The links sit side by side with a middot
   between them and only grow vertically, so no two overlays can overlap. */
body .footer-meta .trust-link,
body .footer-bottom a {
  position: relative;
}

/* v265: the overlay above was sized in percentages of the link's own line box,
   which worked out to a 33px tap area. That clears the 24px AA floor it was
   written for, but not the 44px a thumb actually wants, and the percentages
   would drift with any font-size change. Replaced with a rectangle that is
   simply 44px tall and centred on the link, which is deterministic.

   Measured before committing to 44: the nearest interactive neighbour below
   "Powered by Fora Travel" is the TikTok icon, 27px away. A 44px box on a 17px
   link reaches 13.5px past it, so 13.5px of clear space remains and no overlay
   can steal a tap from the social row. Above, the nearest is 50px away. */
body .footer-meta .trust-link::after,
body .footer-bottom a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 44px;
  transform: translateY(-50%);
}


/* ─── TAP TARGETS, THIRD PASS (v262) ─────────────────────────────────────
   The five footer navigation links are the last controls on the site under
   the 44px comfortable-touch size. Measured on a 390px viewport, v261:

     About              40 x 38
     Guides             42 x 38
     Services           46 x 38
     Points Calculator 103 x 38
     Budget Translator 106 x 38

   38px clears the 24px WCAG 2.5.8 AA floor, which is why the v248 pass left
   them alone, but it misses the 44px figure Apple and Google both publish and
   these five are the only links in the footer that miss it. Everything around
   them already lands on 44 or better: the email link is 44, the three social
   icons are 44 x 44, and the footer CTA is now 52.

   14.4px type on a 1.8 line box is 26px of content, so 9px top and bottom
   gives exactly 44. The links are display: inline-block already, so padding
   applies; nothing about their width or wrapping changes. The li keeps its
   10px margin, so there is still real space between one target and the next
   and the whole column grows by 30px on a page around 12,000px tall.

   ⚠️ This supersedes two identical rules that both read `padding: 6px 0`:
   css/shared-home.css line ~1490 and css/shared-guide.css line ~254, both
   inside a `@media (max-width: 600px)` block labelled "v158 mobile tap
   targets". They are left in place on purpose. Editing them would have bumped
   two more stylesheets across all 20 pages for a six-pixel change, and
   site.css was bumping anyway for the footer button. A future pass that is
   already touching those two files should delete both rules and this note.

   The breakpoint is 600px to match the rules it overrides, and `body` on the
   front of the selector is how the rest of this file wins that specificity. */
@media (max-width: 600px) {
  body .footer-col ul li a {
    display: inline-block;
    padding: 9px 0;
  }
}
