/* ==========================================================================
   base — design tokens, reset, typography, links, buttons
   ==========================================================================

   BREAKPOINTS USED BY THIS SITE
   -----------------------------
   The site uses four inconsistent max-width breakpoints. They are deliberately
   NOT unified, because each was tuned to the component it serves and changing
   any of them would move the layout:

     560px  .process-grid      2 columns -> 1 column        (components/process.css)
     640px  .lodge-card        gallery + body padding shrink (components/lodges.css)
     720px  site-wide "mobile" .wrap / .intro / .photo-grid /
            .team-list / .split / .contact-grid (layout.css,
            components/photo-grid.css), plus .map-marker text
            (components/namibia-map.css), .facts-layout
            (components/facts-globe.css) and .season-strip (components/season.css)
     900px  .process-grid      4 columns -> 2 columns        (components/process.css)

   Each media query lives in the file that owns the component it modifies,
   so a component's mobile behaviour is never more than a scroll away from
   its desktop behaviour.
   ========================================================================== */

:root {
  --charcoal: #16130F;
  --surface: #211B14;
  --sand: #EDE3D0;
  --bush: #4A5540;
  --rust: #AE6A34;
  --rust-text: #B1703C;
  --gold: #C9A227;
  --stone: #8F8875;
  --line: rgba(237, 227, 208, 0.16);

  /* Sticky header geometry.
     The header's vertical padding and the anchor landing offset are derived
     from the same three values, so they cannot drift apart: change a padding
     here and every anchor on the site re-aims itself automatically.

     --header-content-h is the height of the header's tallest child, the brand
     line box: the 19px Fraunces wordmark against the inherited 1.6 line
     height, which measures 30.4px and is taller than the 22px emblem. The nav
     added in phase 2 is deliberately kept under this, so adding the nav does
     not change the header's height and nothing below it moves.

     --header-border is the header's own bottom border, which is part of the
     height an anchor has to clear and is easy to forget. */
  --header-pad-y: 28px;
  --header-pad-y-scrolled: 18px;
  --header-content-h: 30.4px;
  --header-border: 1px;
  --header-h: calc(var(--header-content-h) + 2 * var(--header-pad-y) + var(--header-border));
  --header-h-scrolled: calc(var(--header-content-h) + 2 * var(--header-pad-y-scrolled) + var(--header-border));

  /* Anchor targets stop this far down so the sticky header never sits over
     them. The header is always in its shrunk .scrolled state by the time an
     in-page jump lands (it gains the class past 60px of scroll, and every
     section starts well below that), so the shrunk height is the one to
     clear. */
  --anchor-buffer: 16px;
  --anchor-offset: calc(var(--header-h-scrolled) + var(--anchor-buffer));
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  background: var(--charcoal);
  color: var(--sand);
  font-family: 'Archivo', sans-serif;
  line-height: 1.6;
  font-size: 16px;
}

h1, h2, h3 {
  font-family: 'Fraunces', serif;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.01em;
}

a { color: inherit; text-decoration: none; }

.btn {
  display: inline-block;
  padding: 15px 30px;
  background: var(--rust);
  color: var(--charcoal);
  font-size: 15px;
  font-weight: 600;
  border-radius: 2px;
  transition: background 0.2s ease, transform 0.15s ease-out;
}
.btn:hover { background: #bd6e33; }

/* Magnetic pull. The offsets are written as custom properties by
   js/modules/magnetic-buttons.js; this rule composes them. JS never touches
   style.transform itself, so the stylesheet keeps ownership — the old code
   wrote transform inline, which clobbered any CSS transform on the element
   and left a stale translate(0,0) behind after mouseleave.

   The transform is behind .is-magnetised rather than applied unconditionally
   so that a button at rest has no transform at all, exactly as before. An
   always-on transform would give every .btn its own stacking context and
   containing block, which is a rendering change even at translate(0, 0). */
.btn.is-magnetised {
  transform: translate(var(--btn-shift-x, 0px), var(--btn-shift-y, 0px));
}

:focus-visible {
  outline: 2px solid var(--rust);
  outline-offset: 3px;
}
