/* ==========================================================================
   Globlo — global stylesheet
   Plain CSS, no build step. Custom properties define the design system.
   ========================================================================== */

:root {
  --jungle-moss: #1F3D2E;
  --tiger-gold: #C57B3B;
  --cream: #F7F3E9;
  --tiger-stripe: #2B1E13;
  --muted-sage: #A3B199;

  --jungle-moss-dark: #162C21;
  --tiger-gold-dark: #A6642C;
  --cream-dim: #EFE9D8;

  /* AA-accessible text variants: same hues as the brand colors above,
     adjusted in lightness so small text clears 4.5:1 on both cream and
     jungle-moss backgrounds. Use these instead of the raw brand colors
     whenever gold or sage is applied to text rather than a large surface. */
  --tiger-gold-deep: #8A5223;  /* gold text on cream/cream-dim */
  --tiger-gold-light: #E3B074; /* gold text on jungle-moss/jungle-moss-dark */
  --sage-deep: #556354;        /* sage text on cream/cream-dim */
  --error: #9A3324;            /* form validation / submission errors */

  --font-body: "Inter", system-ui, sans-serif;

  --content-max: 1100px;
  --wide-max: 1400px;

  --radius: 4px;
  --transition: 180ms ease;
  --ease-reveal: cubic-bezier(0.16, 1, 0.3, 1);

  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2.5rem;
  --space-5: 4rem;
  --space-6: 6rem;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  /* Safety net: nothing on this site is meant to scroll horizontally.
     The real fix for any overflow is structural (see grid/section rules
     below) — this just guarantees a stray pixel never produces a
     horizontal scrollbar. */
  overflow-x: hidden;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body, h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd {
  margin: 0;
}

ul, ol { padding: 0; list-style: none; }

img, picture, svg { display: block; max-width: 100%; }

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

button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

input, textarea { font: inherit; color: inherit; }

/* ---------- Base ---------- */
body {
  background: var(--cream);
  color: var(--tiger-stripe);
  font-family: var(--font-body);
  font-weight: 400;
  line-height: 1.6;
  text-align: left;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

main { display: block; }

h1, h2, h3, h4 {
  font-weight: 600;
  line-height: 1.25;
  color: var(--tiger-stripe);
}

h1 { font-size: clamp(2.25rem, 4.5vw, 3.5rem); font-weight: 700; }
h2 { font-size: clamp(1.75rem, 3vw, 2.5rem); }
h3 { font-size: clamp(1.25rem, 2vw, 1.5rem); }

/* No text-align here: left-alignment already comes from `body` by
   inheritance. Setting it directly on `p` would out-rank inherited
   text-align:center on the intentionally-centered paragraphs elsewhere
   (.stat-caption, .placeholder-label, etc.), since an element's own
   directly-matched rule always wins over an inherited one. */
p { max-width: 65ch; }

p.lede {
  font-size: 1.15rem;
  line-height: 1.7;
  color: var(--tiger-stripe);
}

.eyebrow {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tiger-gold-deep);
  margin-bottom: var(--space-2);
}

/* On dark (jungle-moss) section backgrounds, small gold text needs to shift
   lighter to keep 4.5:1 contrast — --tiger-gold-deep is tuned for cream. */
.page-header .eyebrow,
.closing-cta .eyebrow,
.stats-strip .eyebrow {
  color: var(--tiger-gold-light);
}

/* Focus visibility — required for keyboard operability */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--tiger-gold);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------- Layout helpers ---------- */
.container {
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto; /* fallback for margin-inline, kept alongside it below */
  margin-inline: auto;
  padding-inline: var(--space-3);
}

.container-wide {
  width: 100%;
  max-width: var(--wide-max);
  margin: 0 auto;
  margin-inline: auto;
  padding-inline: var(--space-3);
}

/* Every top-level section is a full-width, normal-flow block. `isolation`
   gives each one its own stacking context so nothing can ever paint over
   an adjacent section, and the width/max-width pairing keeps a section
   from ever growing past the viewport regardless of what a child does. */
section {
  position: relative;
  isolation: isolate;
  width: 100%;
  max-width: 100vw;
  padding-block: var(--space-6);
  text-align: left;
}

@media (max-width: 767px) {
  section { padding-block: var(--space-5); }
}

.section-head {
  max-width: 640px;
  margin-bottom: var(--space-4);
  text-align: left;
}

.section-head.center {
  margin-left: auto;
  margin-right: auto;
  margin-inline: auto;
  text-align: center;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.75rem;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  border-radius: var(--radius);
  transition: background var(--transition), color var(--transition), transform var(--transition);
}

.btn-primary,
.btn-on-dark {
  background: var(--tiger-gold);
  color: var(--tiger-stripe);
}

.btn-primary:hover,
.btn-on-dark:hover {
  background: var(--jungle-moss);
  color: var(--cream);
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.btn-ghost {
  background: transparent;
  border: 1px solid var(--muted-sage);
  color: var(--tiger-stripe);
}

.btn-ghost:hover { border-color: var(--tiger-gold); color: var(--tiger-gold-deep); }

/* ---------- Header / Nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(247, 243, 233, 0.92);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid rgba(43, 30, 19, 0.08);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-2);
}

.wordmark {
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--jungle-moss);
}

.nav-links {
  display: flex;
  gap: var(--space-4);
}

.nav-links a {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--tiger-stripe);
  position: relative;
  padding-block: 0.25rem;
}

.nav-links a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background: var(--tiger-gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--transition);
}

.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after {
  transform: scaleX(1);
}

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  padding: 0.5rem;
}

.nav-toggle .bar {
  width: 22px;
  height: 2px;
  background: var(--tiger-stripe);
  transition: transform var(--transition), opacity var(--transition);
}

.nav-toggle[aria-expanded="true"] .bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 767px) {
  .nav-toggle { display: inline-flex; }

  .nav-links {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--cream);
    flex-direction: column;
    gap: 0;
    border-bottom: 1px solid rgba(43, 30, 19, 0.08);
    max-height: 0;
    overflow: hidden;
    transition: max-height var(--transition);
  }

  .nav-links.open { max-height: 320px; }

  .nav-links a {
    padding: var(--space-2) var(--space-3);
    border-top: 1px solid rgba(43, 30, 19, 0.06);
  }

  .nav-links a::after { display: none; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  color: var(--cream);
  /* Full-bleed: override the base `section` block's padding-block so
     the hero image runs edge-to-edge under the sticky nav, not inset. */
  padding-block: 0;
}

.hero-media {
  position: relative;
  height: 92vh;
  min-height: 520px;
  max-height: 900px;
  overflow: hidden;
}

/* Hero slideshow — js/hero.js fills #hero-slideshow with one <img
   class="hero-slide"> per entry in assets/images/hero/manifest.json.
   Any number of slides works: each stacks in the same box and crossfades
   via opacity, so adding a third, fourth, etc. photo later only means
   editing the manifest, never this CSS. */
.hero-slideshow {
  position: absolute;
  inset: 0;
}

.hero-slideshow .placeholder-img {
  position: absolute;
  inset: 0;
}

.hero-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.6s ease-in-out;
}

.hero-slide.is-active {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .hero-slide { transition: none; }
}

.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(31, 61, 46, 0.35) 0%, rgba(22, 44, 33, 0.72) 100%);
}

.hero-content {
  /* Centered via left:50%/translateX rather than inset:0 + margin:auto —
     setting left, right, width, and margin all at once over-constrains
     the box and different engines resolve the conflict differently. */
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  padding: var(--space-5) var(--space-3) var(--space-6);
  width: 100%;
  max-width: var(--content-max);
  z-index: 2;
}

.hero-wordmark {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.3em;
  color: var(--cream);
  margin-bottom: var(--space-3);
}

.hero-content h1 {
  color: var(--cream);
  max-width: 14ch;
  margin-bottom: var(--space-2);
}

.hero-content p {
  color: var(--cream-dim);
  max-width: 46ch;
  font-size: 1.1rem;
  margin-bottom: var(--space-3);
}

/* ---------- Placeholder images ---------- */
.placeholder-img {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: linear-gradient(135deg, var(--jungle-moss) 0%, var(--muted-sage) 100%);
  overflow: hidden;
}

.placeholder-img .placeholder-label {
  color: var(--cream);
  font-size: 0.85rem;
  font-weight: 500;
  line-height: 1.5;
  padding: var(--space-3);
  max-width: 32ch;
  /* Solid backing (rather than relying on the gradient underneath) keeps
     this text at a reliable contrast ratio wherever it falls on the
     gradient — the sage end of it is too light for cream text alone. */
  background: rgba(22, 44, 33, 0.82);
  border: 1px dashed rgba(247, 243, 233, 0.45);
  border-radius: var(--radius);
}

.placeholder-img.compact .placeholder-label {
  font-size: 0.75rem;
  padding: var(--space-2);
}

/* real <img> that replaces a placeholder should fill the same box */
.media-box {
  position: relative;
  overflow: hidden;
}

.media-box img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------- What Globlo Is / Why Wild Places ---------- */
/* Shared text+image row: used for the single "What Globlo is" pairing
   and for each "Why wild places" block. `.reverse` flips which side the
   image sits on so consecutive rows can alternate; the DOM order always
   stays text-then-image so mobile stacking reads text-first regardless. */
.prose {
  max-width: 72ch;
}

.prose p + p { margin-top: var(--space-2); }

.split-stack > .split-row + .split-row {
  margin-top: var(--space-5);
}

.split-row {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  /* Keeps each row's glow (see below) from ever bleeding into the row
     above or below it, no matter how large the blur radius is. */
  overflow: hidden;
}

.split-row.reverse {
  flex-direction: row-reverse;
}

.split-text,
.split-media {
  flex: 1 1 0;
  min-width: 0;
}

.split-text h3 { margin-bottom: 0.5rem; }
.split-text p { color: var(--tiger-stripe); }

/* Soft, edgeless photo treatment: the full photo is shown untouched
   (nothing cropped or faded out of the image itself). A blurred, colour-
   matched copy of the same photo sits behind it as a faint ambient
   "glow", bleeding gently past the photo's own edges toward the text —
   so the blend comes from the image's own colours softening into the
   page, not from hiding any part of the picture.

   The fade (mask) and the blur (filter) are deliberately on two
   different elements — .split-media-glow does the fading,
   .split-media-glow-fill does the blurring — because combining a mask
   and a filter on the very same element renders inconsistently across
   browsers (the mask gets ignored and the blur shows through as a hard-
   edged rectangle, which is the bug this replaces). */
.split-media {
  position: relative;
}

.split-media-glow {
  position: absolute;
  inset: -6%;
  z-index: 0;
  overflow: hidden;
  -webkit-mask-image: radial-gradient(ellipse 58% 58% at 50% 50%, #000 0%, transparent 92%);
  mask-image: radial-gradient(ellipse 58% 58% at 50% 50%, #000 0%, transparent 92%);
}

.split-media-glow-fill {
  position: absolute;
  inset: -15%;
  background-size: cover;
  background-position: center;
  filter: blur(36px) saturate(1.1);
  opacity: 0.45;
}

.split-media img {
  position: relative;
  z-index: 1;
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 480px;
  margin-inline: auto;
  border-radius: var(--radius);
}

@media (max-width: 767px) {
  .split-row,
  .split-row.reverse {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }

  .split-media img {
    max-height: 420px;
  }
}

/* ---------- Stats strip ---------- */
.stats-strip {
  background: var(--jungle-moss);
  color: var(--cream);
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  text-align: center;
}

@media (max-width: 767px) {
  .stats-grid { grid-template-columns: 1fr; gap: var(--space-3); }
}

.stat-figure {
  font-size: clamp(2rem, 4vw, 2.75rem);
  font-weight: 700;
  color: var(--tiger-gold);
  margin-bottom: 0.4rem;
}

.stat-caption {
  color: var(--cream-dim);
  font-size: 0.9rem;
  max-width: 32ch;
  margin-inline: auto;
}

.stats-source {
  margin-top: var(--space-4);
  font-size: 0.78rem;
  color: var(--muted-sage);
  text-align: center;
}

/* ---------- Quotes ---------- */
.quotes-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
}

@media (max-width: 900px) {
  .quotes-grid { grid-template-columns: 1fr; }
}

.quote-card {
  border-left: 2px solid var(--tiger-gold);
  padding-left: var(--space-3);
}

.quote-card blockquote {
  font-size: 1.2rem;
  font-style: italic;
  color: var(--jungle-moss);
  line-height: 1.5;
  margin-bottom: var(--space-1);
}

.quote-card cite {
  font-style: normal;
  font-size: 0.85rem;
  color: var(--sage-deep);
  font-weight: 500;
}

/* ---------- Who it's for ---------- */
/* This is the platform's core three-sided model, so each role gets a
   full-width feature block (big image, then a heading and two
   paragraphs beneath it) rather than a small grid card. */
.role-feature-list > .role-feature + .role-feature {
  margin-top: var(--space-5);
}

.role-feature-media {
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: var(--space-3);
}

.role-feature-media img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.role-feature-body {
  max-width: 68ch;
}

.role-feature-body h3 { margin-bottom: 0.5rem; }

.role-feature-body p { color: var(--tiger-stripe); }

.role-feature-body p + p { margin-top: var(--space-2); }

@media (max-width: 767px) {
  .role-feature-media img { aspect-ratio: 4 / 3; }
}

/* ---------- Gallery ---------- */
.gallery-section {
  background: var(--jungle-moss-dark);
  color: var(--cream);
}

.gallery-section .section-head h2,
.gallery-section .eyebrow { color: var(--cream); }

.gallery-section .section-head p { color: var(--cream-dim); }

.gallery-grid {
  column-count: 1;
  column-gap: var(--space-2);
}

@media (min-width: 560px) {
  .gallery-grid { column-count: 2; }
}

@media (min-width: 900px) {
  .gallery-grid { column-count: 3; }
}

@media (min-width: 1300px) {
  .gallery-grid { column-count: 4; }
}

.gallery-item {
  break-inside: avoid;
  margin-bottom: var(--space-2);
  border-radius: var(--radius);
  overflow: hidden;
  position: relative;
}

.gallery-item img {
  width: 100%;
  display: block;
  transition: transform 260ms ease;
}

.gallery-item button {
  display: block;
  width: 100%;
}

.gallery-item button:hover img,
.gallery-item button:focus-visible img {
  transform: scale(1.03);
}

.gallery-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: var(--space-5) var(--space-3);
  border: 1px dashed rgba(247, 243, 233, 0.3);
  border-radius: var(--radius);
  color: var(--cream-dim);
  max-width: 520px;
  margin-inline: auto;
}

.gallery-empty .placeholder-label {
  color: var(--cream);
}

/* Lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(22, 44, 33, 0.96);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3);
}

.lightbox[hidden] { display: none; }

.lightbox img {
  max-width: min(90vw, 1200px);
  max-height: 84vh;
  width: auto;
  height: auto;
  margin-inline: auto;
  border-radius: var(--radius);
}

.lightbox-close,
.lightbox-prev,
.lightbox-next {
  position: absolute;
  color: var(--cream);
  background: rgba(31, 61, 46, 0.7);
  border-radius: 50%;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.4rem;
  transition: background var(--transition);
}

.lightbox-close:hover,
.lightbox-prev:hover,
.lightbox-next:hover { background: var(--tiger-gold); color: var(--jungle-moss-dark); }

.lightbox-close { top: var(--space-3); right: var(--space-3); }
.lightbox-prev { left: var(--space-3); top: 50%; transform: translateY(-50%); }
.lightbox-next { right: var(--space-3); top: 50%; transform: translateY(-50%); }

.lightbox-caption {
  position: absolute;
  bottom: var(--space-3);
  left: 0;
  right: 0;
  text-align: center;
  color: var(--cream-dim);
  font-size: 0.85rem;
}

@media (max-width: 600px) {
  .lightbox-prev, .lightbox-next { width: 36px; height: 36px; font-size: 1.1rem; }
}

/* ---------- Closing CTA ---------- */
.closing-cta {
  background: var(--jungle-moss);
  color: var(--cream);
  text-align: center;
}

.closing-cta .eyebrow { color: var(--tiger-gold); }

.closing-cta h2 { color: var(--cream); margin-bottom: var(--space-3); }

/* ---------- Page header (inner pages) ---------- */
.page-header {
  background: var(--jungle-moss);
  color: var(--cream);
  padding-block: var(--space-5);
}

.page-header .eyebrow { color: var(--tiger-gold); }

.page-header h1 { color: var(--cream); }

.page-header p { color: var(--cream-dim); margin-top: var(--space-2); }

/* ---------- Legal pages ---------- */
.legal-body h2 {
  margin-top: var(--space-4);
  margin-bottom: var(--space-2);
  font-size: 1.35rem;
}

.legal-body h2:first-of-type { margin-top: 0; }

.legal-body p { max-width: 72ch; margin-bottom: var(--space-2); color: var(--tiger-stripe); }

.legal-body ul { margin-bottom: var(--space-2); }

.legal-body li {
  position: relative;
  padding-left: 1.25rem;
  margin-bottom: 0.5rem;
  max-width: 68ch;
}

.legal-body li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.65em;
  width: 6px;
  height: 6px;
  background: var(--tiger-gold);
  border-radius: 50%;
}

.legal-meta {
  color: var(--sage-deep);
  font-size: 0.85rem;
  margin-bottom: var(--space-4);
}

.legal-body a { color: var(--jungle-moss); text-decoration: underline; text-underline-offset: 2px; }
.legal-body a:hover { color: var(--tiger-gold-deep); }

/* ---------- Contact ---------- */
.contact-layout {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: var(--space-5);
  align-items: start;
}

@media (max-width: 900px) {
  .contact-layout { grid-template-columns: 1fr; gap: var(--space-4); }
}

.contact-direct a {
  color: var(--jungle-moss);
  font-weight: 600;
  font-size: 1.15rem;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.contact-direct a:hover { color: var(--tiger-gold-deep); }

.field {
  margin-bottom: var(--space-3);
}

.field label {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}

.field input,
.field textarea {
  width: 100%;
  padding: 0.8rem 1rem;
  background: #fff;
  border: 1px solid rgba(43, 30, 19, 0.18);
  border-radius: var(--radius);
  color: var(--tiger-stripe);
  transition: border-color var(--transition);
}

.field input:focus,
.field textarea:focus {
  border-color: var(--tiger-gold);
  outline: none;
}

.field textarea { resize: vertical; min-height: 140px; }

.field input.has-error,
.field textarea.has-error {
  border-color: var(--error);
}

.field-error {
  font-size: 0.82rem;
  color: var(--error);
  margin-top: 0.35rem;
}

.field-error:empty {
  display: none;
}

.form-status {
  font-size: 0.85rem;
  color: var(--sage-deep);
  margin-top: var(--space-2);
}

.form-status.is-error {
  color: var(--error);
}

.form-status:empty {
  display: none;
}

.form-confirm {
  display: none;
  background: var(--jungle-moss);
  color: var(--cream);
  padding: var(--space-3);
  border-radius: var(--radius);
  margin-top: var(--space-3);
}

.form-confirm.show { display: block; }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--tiger-stripe);
  color: var(--cream-dim);
  padding-block: var(--space-4);
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.footer-links {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.footer-links a { color: var(--cream-dim); font-size: 0.9rem; }
.footer-links a:hover { color: var(--tiger-gold); }

.footer-meta {
  font-size: 0.85rem;
  color: var(--muted-sage);
}

.footer-meta a { color: var(--muted-sage); text-decoration: underline; text-underline-offset: 2px; }
.footer-meta a:hover { color: var(--tiger-gold); }

/* ---------- Utility ---------- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--space-2);
  top: -60px;
  background: var(--tiger-gold);
  color: var(--jungle-moss-dark);
  padding: 0.6rem 1rem;
  border-radius: var(--radius);
  font-weight: 600;
  z-index: 1100;
  transition: top var(--transition);
}

.skip-link:focus { top: var(--space-2); }

/* ---------- Scroll reveal ---------- */
/* Driven by an IntersectionObserver in js/main.js: elements start hidden
   and offset, then animate to their resting state the first time they
   enter the viewport. A second, slightly delayed class lets a section's
   body copy settle in just after its heading rather than simultaneously. */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 650ms var(--ease-reveal), transform 650ms var(--ease-reveal);
}

.reveal-delay {
  transition-delay: 130ms;
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Gallery tiles use the same curve but a shorter throw and a per-tile
   stagger set inline via --tile-index (see js/gallery.js). */
.gallery-item.reveal {
  transform: translateY(16px) scale(0.98);
  transition-duration: 500ms;
  transition-delay: calc(var(--tile-index, 0) * 60ms);
}

.gallery-item.reveal.is-visible {
  transform: translateY(0) scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .gallery-item.reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
