/* ─────────────────────────────────────────────────────────────────────────
   Journeys with JB — design tokens (extracted v208)

   Every colour, font and type size the site uses lives here, once.

   Before this file existed, 13 pages each carried their own private copy of
   this list, plus a 14th copy inside css/shared-home.css. They had already
   started to disagree: iceland-guide was missing --error, --max-w and
   --section-pad; northern-lights-guide carried 13 extra values; privacy-policy
   used a different --max-w. Changing one colour meant 14 edits, and missing
   one meant a page quietly drifted.

   Every page loads this file first, before its own styles, so anything a page
   sets after this still wins. Two pages deliberately do that:
     - privacy-policy.html overrides --max-w to 760px for a narrower text column
     - northern-lights-guide.html adds its own aurora palette on top

   Values below are unchanged from what the site already rendered. This file
   was assembled by taking the values that were already identical across all
   14 copies, so nothing visible changes.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  /* ── Natural Light — sage system (2026-07-12) ── */
  --oat:           #E0D6C5;
  --linen:         #EAE1D2;
  --warmwhite:     #FBF7EF;
  --bone:          #F6F1E7;
  --stone:         #C8BBA6;
  --cocoa:         #645648;
  --walnut:        #44392D;
  --sage:          #5E6E4A;
  --sage-dk:       #4E5A3E;
  --sage-on-dark:  #C2CEA4;

  /* ── Older names for the same colours, kept because pages still use them ── */
  --cream:         #EAE1D2;
  --warm-white:    #FBF7EF;
  --sand:          #C8BBA6;
  --deep:          #44392D;
  --charcoal:      #645648;
  --muted:         #857A68;
  --muted-text:    #6E6353;
  --error:         #b0473e;

  /* v228: three tokens removed after a sitewide reference count returned zero
     uses for each. --clay and --taupe were two names for #A2957F, which the
     site never referenced once. --accent-dark was left over from the retired
     bronze system and had been quietly reassigned to #EAE1D2, so a variable
     named "accent dark" was holding a pale cream. If clay is wanted back it
     is one line: --clay: #A2957F. */

  /* ── Type ── */
  --font-display:  'Cormorant Garamond', Georgia, serif;
  --font-body:     'EB Garamond', Georgia, serif;
  --font-elegant:  'EB Garamond', Georgia, serif;
  --font-subtitle: 'Marcellus', Georgia, serif;

  /* v215: --text-xs was 0.75rem (12px) on desktop but 0.8125rem (13px) on a
     phone, so the desktop reader got the smaller of the two. 13px is now the
     floor at every width and the phone override below no longer needs it. */
  --text-xs:   0.8125rem;
  --text-sm:   0.9rem;
  --text-base: 1.05rem;
  --text-md:   1.15rem;
  --text-lg:   1.4rem;

  /* v215: running prose on the long-form pages. The guides, itineraries and
     the blog post were setting body copy in --text-sm (14.4px), a size meant
     for labels and captions, while the About page reads at 20px. That also
     drove the line lengths past 139 characters. Raising the size inside the
     same column width pulls those lines back to roughly 111 to 114 characters,
     which is inside the 101 to 119 range approved in v213, so the full-width
     look chosen then is preserved rather than undone.

     This is deliberately a separate token from --text-sm. Labels, names, nav,
     hero subtitles and card chrome should stay at 14.4px; only text a visitor
     actually sits and reads moves to this one. */
  --text-read: 1.125rem;

  /* ── v222 card prose ──
     A third reading size, and the reason it exists is worth writing down
     because it looks at first glance like a violation of the Reading Size Rule
     in DESIGN.md.

     That rule says card chrome stays at --text-sm and does not get raised to
     reading size. It is right, and --text-sm is unchanged at 14.4px. But
     "chrome" means a tag, a price, a route, a night count: fragments you scan.
     Measured in the browser, 28 elements at 14.4px were not fragments. They
     were full sentences over 90 characters, and they were carrying the actual
     selling:

       "Safari by day, Indian Ocean by night. Elephant herds in Tara..."
       "For travelers who want more than a typical vacation: journeys built
        around dramatic landscapes, outdoor exploration, and places few
        people ever reach."

     That is prose, set at the size used for the word "Complimentary". It is
     the best writing on the site displayed at the smallest size on the card.

     16px is deliberately below --text-read (18px). A card description is still
     scanned in a grid alongside eleven others, so it should not compete with
     the running prose on a guide page. It only has to stop looking like a
     label.

     What did NOT move: photo captions on the blog post, .card-tag, .card-route,
     .card-length, .card-region, .svc-card-price, .pkg-num. Those are chrome and
     the rule holds for them. */
  --text-card: 1rem;

  /* ── Layout ── */
  --max-w: 1100px;
}

/* v188 phone type scale: --text-xs at 12px was carrying labels, captions,
   list copy and footer text. 13px reads far better on a handset.
   v215: --text-xs is now 13px at every width, so it is no longer set here.
   --text-sm still steps up on a phone. */
@media (max-width: 600px) {
  :root { --text-sm: 0.95rem; }
}

/* ─────────────────────────────────────────────────────────────────────────
   v208 breakpoint scale

   The site used to switch layout at 20 different widths: 1188, 1187, 1160,
   1040, 900, 800, 780, 768, 740, 720, 700, 681, 680, 640, 620, 600, 560, 540,
   480 and 360. Most of those numbers were arbitrary. Nothing in the layout
   needed the difference between 700 and 720, and the same nav collapsed at 900
   on fourteen pages but at 768 on the points calculator.

   There are now five:

     1100px  wide desktop  ->  laptop
      900px  laptop        ->  tablet          (the nav collapses here)
      780px  tablet        ->  large phone
      680px  large phone   ->  phone
      600px  phone

   Three exceptions remain on purpose, because those numbers come from the
   content rather than from taste:
     1188px  index.html services row: the grid is capped at 1100px and the page
             has 44px of padding each side, so 1188 is exactly where four
             columns start to be squeezed
      480px  the day-by-day itinerary rows and the island detail strip
      360px  hides the print button on the very smallest handsets

   Note that CSS cannot put a media query width in a variable, so these numbers
   still have to be typed out in each stylesheet. The point of the scale is
   that there are five numbers to recognise instead of twenty.

   Every breakpoint that moved, moved UP: 700 became 780, 560 became 600, and
   so on. A larger max-width means the simpler stacked layout starts slightly
   sooner as the window narrows, which can never squeeze a column past its
   content. Moving one down would have risked exactly that.
   ───────────────────────────────────────────────────────────────────────── */

/* v199 heading scale. One page title size and one section title size for the
   whole site, so an H3 can never end up competing with body copy again.
   The clamp scales them down smoothly on narrow screens. */
:root {
  --h1-size: clamp(2.25rem, 1.3rem + 4.2vw, 4rem);      /* 36px -> 64px */
  --h2-size: clamp(1.625rem, 1.15rem + 2.2vw, 2.75rem); /* 26px -> 44px */

  /* v212 heading weights. Before this the site rendered h1, h2 and h3 at four
     different weights each depending on the page, which read as four different
     levels of importance for what are the same level of heading.

     Cormorant Garamond has very fine hairlines. At 64px and 44px the size alone
     carries the authority, so 500 stays elegant. At 30px and 22px those
     hairlines start to disappear against the cream backgrounds, so the smaller
     two need 600 to still read as headings rather than as large body copy. */
  --h1-weight: 500;
  --h2-weight: 500;
  --h3-weight: 600;
  --h4-weight: 600;

  /* v265 display tracking. This is the counterpart to the Three Stops Rule:
     that rule governs WIDE tracking on capitalised labels, and DESIGN.md is
     explicit that tightened tracking on the large Cormorant headings is a
     separate matter. Separate, but it still needs exactly one value, and
     before v265 it had three. Measured: all 20 pages render their page title
     at an identical 64px / weight 500 / Cormorant Garamond -- one component
     built six different ways -- and 15 of them sat at zero while four used
     -0.5px and one used -0.01em.

     Two things make -0.01em the right number rather than zero. Cormorant is
     drawn with generous spacing for reading sizes, which reads loose by the
     time it reaches 64px, so a light tightening is what the face wants. And
     it must be written in em, not px: the four pages that used -0.5px were
     sitting on a clamp()ed font-size, so the ratio slid from -0.0139em on a
     phone to -0.0078em on a desktop -- tracking hardest where the type was
     smallest, which is backwards.

     Anything that needs to opt out should say so in its own rule and say why.
     Do not add a second value here. */
  --display-tracking: -0.01em;

  /* v212 photo scrims. Every hero already laid a soft brown wash over its
     photograph, but each one faded to a different, much weaker value at its far
     end (0.30, 0.40, 0.45, 0.50), and that pale end is exactly where the eyebrow
     and subtitle sit. Measured against the real pixels, white text on those
     pale ends came out between 2.2 and 4.4 to one, under the 4.5 needed to read
     comfortably. These two numbers set both ends of every scrim in one place,
     so the wash still fades across the picture rather than sitting on it as a
     flat sheet, and the fade now ends somewhere the words survive.

     The two values are the lightest pair that clears 4.5 to one everywhere.
     They were not picked by eye: the scrim was turned off, the real photographs
     were sampled behind every piece of hero text, and the wash was then walked
     down until something failed. The wash costs the photography a great deal,
     so it was worth spending the time to find the true floor rather than
     settling for the first value that passed:

       0.70 / 0.66   0 failures
       0.68 / 0.64   0 failures   <- in use
       0.66 / 0.62   3 failures
       0.64 / 0.60   5 failures

     Going any lighter loses the Atacama salt flat eyebrow and the Caribbean
     subtitle first, because those sit on the brightest patches on the site.

     Each hero repeats these two numbers as a fallback, as in
     rgba(68,57,45,var(--scrim-deep, 0.68)). If a returning visitor's browser
     ever served a cached copy of this file that predates the tokens, the
     variable would resolve to nothing, the whole gradient would be thrown out
     as invalid, and the hero would lose its wash entirely. The fallback means
     the worst case is the correct scrim rather than none at all. */
  --scrim-deep: 0.68;
  --scrim-fade: 0.64;

  /* ── v212 section rhythm ──
     Every band on the site sat at 58px of padding top and bottom at every screen
     size, from a 1440px desktop down to a phone. 58px is a sensible figure on a
     handset and a cramped one on a desktop, where the bands ran into each other
     and the page read as one long scroll rather than a series of chapters.

     The three values below give a section room to breathe on a large screen and
     tighten it as the screen narrows, so the phone keeps exactly the spacing it
     has now. The breakpoints are two of the five already in the scale. */
  --section-pad-y: 96px;
  --section-pad: var(--section-pad-y) 24px;

  /* ── v222 rhythm break ──
     96px was doing every job. Measured in the browser, index.html ran six
     consecutive bands at exactly 96 top and 96 bottom, and services.html ran
     five of five. The value itself is right; using only that value is the
     problem. Even spacing all the way down a page is the thing that reads as
     assembled rather than composed, and it was the second-largest reason the
     site felt generated.

     These two sit either side of the base so a page can open a gap where a
     new chapter starts and close one where two sections belong together.
     They are not free to sprinkle: WIDE marks the start of a movement, TIGHT
     binds an adjacent pair. Everything else stays on the base 96.

     They step down on the same two breakpoints as --section-pad-y, and keep
     roughly the same ratio to it (1.5x and 0.67x), so the phone never ends up
     with a 144px hole in it. */
  --section-pad-wide:  144px;
  --section-pad-tight:  64px;

  /* ── v212 corner radius, settled in v263 ──
     v212 cut 16 corner sizes down to five, but five was still four too many
     for two jobs. Measured across all thirteen guides in v263: 2px on 64
     buttons, 4px on 26 panels, 8px on 287 surfaces, 12px on 43, plus the
     pills and the social circles. .guide-cta was rendering at 12px on three
     pages and 8px on a fourth, which is what settling this is for.

     Two sizes now, and they mean different things:
       --radius-sm   the button corner, and only buttons and inputs
       --radius-lg   every surface: card, panel, box, table, photograph, nav
     --radius-pill stays because a pill is a shape, not a corner. Social
     icons are 50% inline for the same reason.

     --radius-md and --radius-card are gone. Verified zero references across
     every html, css and js file in the build before removing them. */
  --radius-sm: 2px;
  --radius-lg: 8px;
  --radius-pill: 100px;

  /* ── v212 shadows ──
     25 different shadows were in use, and most of the difference between them
     was not a design decision. There were two shadows that differ only in the
     third decimal place of their opacity, three that differ only in blur, and
     two written in pure black on a site whose every other shadow is the same
     warm brown as the body text, which is why those two read as grey smudges
     next to their neighbours.

     Three shadows do all the work: a tight one that gives an edge to the nav
     bar and the floating button, a soft wide one for a card at rest, and a
     slightly stronger one for a card under the pointer. A handful of sage-green
     glows and two deliberately heavy pressed states are left as they are,
     because those are doing something these three cannot. */
  --shadow-edge: 0 2px 8px rgba(68,57,45,0.22);
  --shadow-card: 0 8px 24px rgba(68,57,45,0.10);
  --shadow-lift: 0 6px 18px rgba(68,57,45,0.22);

  /* ── v222 shadow follow-up ──
     v212 set the three above but four off-scale walnut shadows had crept back
     since: 0 2px 14px /0.06 on .investment-callout across eight guide pages,
     0 12px 36px /0.09 on the guides card hovers, 0 4px 20px /0.07 on the
     featured package card, and 0 18px 44px /0.16 under the about portrait.
     All twelve declarations are now --shadow-card. Worth noting that
     --shadow-card had drifted out of real use almost entirely; the site was
     running on --shadow-edge plus a scatter of one-offs.

     The ONE remaining walnut exemption is .hero-btn: 0 4px 14px /0.28 at rest
     and 0 8px 22px /0.34 on hover, in index.html and shared-home.css. That
     button sits on top of a photograph, and --shadow-card at 0.10 opacity
     disappears against a busy image. It needs the extra weight to hold an
     edge. This is deliberate, not drift — do not "fix" it. */

  /* ── v218 motion ──
     The last part of the site that was never standardised. Thirteen different
     transition durations were in use (0.1s through 0.7s), and of 297
     transitions, 294 ran on the browser's default curve. That curve eases in
     as well as out, which is why a hover could feel like it hesitated before
     it started moving.

     Three durations cover everything. Fast is for a colour or a border
     changing under the pointer, where anything longer reads as lag. Base is
     for a button or a card that also moves. Slow is for content arriving on
     screen, which is the only motion here allowed to take its time.

     One curve, and it is an ease-out: movement starts at full speed and
     settles. Linear stays on the two reading-progress bars, because a progress
     bar that eases is lying about the rate. */
  --dur-fast: 160ms;
  --dur-base: 200ms;
  --dur-slow: 400ms;
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* How far a block travels as it fades in. It was 28px, far enough that the
     eye follows the movement instead of reading the words. */
  --reveal-shift: 14px;

  /* Two hover lifts, because there were four (1px, 2px, 3px and 4px, varying
     by page rather than by intent). Small is for anything carrying text that
     has to stay readable while it moves. Card is for a photograph. */
  --lift-sm: -2px;
  --lift-card: -3px;

  /* The house transition for anything that reacts to a pointer. Twenty-one
     rules used `transition: all`, which tells the browser to animate whatever
     happens to change, including the properties that force it to work out the
     whole layout again. On the points calculator, `all` was smoothly resizing
     the TEXT inside an option card on hover.

     Naming the properties fixes that by omission. Every one of these six is a
     paint or compositor change. Nothing here can move the page. */
  --transition-ui:
    color var(--dur-fast) var(--ease-out),
    background var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out),
    opacity var(--dur-fast) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

@media (max-width: 900px) {
  :root {
    --section-pad-y:     72px;
    --section-pad-wide: 108px;
    --section-pad-tight: 48px;
  }
}

@media (max-width: 680px) {
  :root {
    --section-pad-y:     58px;
    --section-pad-wide:  88px;
    --section-pad-tight: 40px;
  }
}

/* ─── REDUCED MOTION (v248) ─────────────────────────────────────────────────
   Before this, honouring the setting was piecemeal: sixteen of the twenty
   pages carried exactly one small `prefers-reduced-motion` rule, usually for
   the floating pill's close button, and the two shared stylesheets that
   define most of the site's motion (this file and shared-guide.css) carried
   none at all. So a visitor who has asked their operating system to reduce
   motion still got every hover slide, every card lift and every entry fade.

   Two mechanisms, on purpose, because neither covers everything alone.

   1. The duration TOKENS collapse. Almost all motion on the site is written
      as `var(--dur-base) var(--ease-out)`, so zeroing the three durations
      reaches it without touching a single component rule. This also gets
      past the handful of rules that carry `!important` on their transition
      (`.nav-cta` in shared-guide.css, for one), which a `*` rule could not
      outrank.

   2. A universal net for hard-coded values. A few durations were written as
      literals rather than tokens (`transition: transform 0.1s linear` on the
      reading-progress bar, `animation: fadeUp 0.75s` on four guide heroes),
      and tokens cannot reach those.

   `animation-iteration-count: 1` with a near-zero duration lands each
   animation on its FINAL keyframe rather than freezing it at the start, so
   anything that fades or slides IN ends up visible rather than stuck
   invisible. Every animation on this site was checked against that: the four
   guide hero `fadeUp`s, the Budget Translator and Points Calculator step
   transitions, and the Northern Lights aurora all resolve to their intended
   resting state. Nothing on the site listens for `transitionend` or
   `animationend`, so no logic depends on a transition actually running.

   `0.01ms` rather than `0`: some browsers skip firing events entirely at
   exactly zero, and a hair above zero is indistinguishable to the eye. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0.01ms;
    --dur-base: 0.01ms;
    --dur-slow: 0.01ms;
  }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}
