/* ==========================================================================
   Impact Trails Asia - Constructivist design system
   Palette and ratio per brand guide:
   60% Warm Sand (background) / 30% Deep Forest (logo, headings) / 10% Terracotta (accent)
   ========================================================================== */

/* --- 1. Tokens ----------------------------------------------------------- */
:root {
  /* Primary */
  --sand:        #F2E8D5;
  --forest:      #173F35;
  --terracotta:  #C76545;

  /* Approved alternatives */
  --slate:       #2F3E46;
  --terracotta-2:#C05746;
  --sea:         #84A98C;
  --white:       #FFFFFF;

  /* Derived surfaces (tints of the primaries only) */
  --sand-deep:   #E7D9BF;
  --sand-line:   #D9C7A6;
  --forest-soft: #21584A;
  /* Darker approved terracotta, reserved for accent TEXT so it clears WCAG contrast
     on sand. Plain --terracotta stays for fills, rules and shapes. */
  --accent-text: #C05746;
  --ink:         var(--forest);

  /* Type */
  --font-display: "Archivo Black", "Arial Black", "Helvetica Neue", Arial, sans-serif;
  --font-cond:    "Archivo Narrow", "Arial Narrow", Arial, sans-serif;
  --font-body:    "Archivo", "Helvetica Neue", Arial, sans-serif;

  --step--1: clamp(0.82rem, 0.79rem + 0.15vw, 0.9rem);
  --step-0:  clamp(1rem, 0.96rem + 0.2vw, 1.125rem);
  --step-1:  clamp(1.2rem, 1.1rem + 0.5vw, 1.5rem);
  --step-2:  clamp(1.5rem, 1.3rem + 1vw, 2.25rem);
  --step-3:  clamp(2rem, 1.6rem + 2vw, 3.25rem);
  --step-4:  clamp(2.6rem, 1.8rem + 4vw, 5.5rem);
  --step-5:  clamp(3.2rem, 1.9rem + 6.4vw, 8rem);

  /* Structure */
  --rule: 3px;
  --rule-thick: 6px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --max: 1240px;
  --masthead-h: 132px;
  --block-shadow: 10px 10px 0 var(--forest);

  /* Corner radii. Pills (--radius-pill) stay fully round; every other bordered
     rectangle and button uses one of the two below. */
  --radius:      16px;
  --radius-sm:   10px;
  --radius-pill: 999px;
}

/* --- 2. Reset / base ----------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
/* Jump-link targets stop below the sticky masthead rather than under it. */
[id] { scroll-margin-top: calc(var(--masthead-h) + 1.5rem); }

body {
  margin: 0;
  background: var(--sand);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.62;
  overflow-x: hidden;
  /* Faint constructivist grid, printed onto the sand */
  background-image:
    repeating-linear-gradient(to right,  rgba(23,63,53,.055) 0 1px, transparent 1px 96px),
    repeating-linear-gradient(to bottom, rgba(23,63,53,.055) 0 1px, transparent 1px 96px);
}

h1, h2, h3, h4 {
  font-family: var(--font-display); font-weight: 400; line-height: 0.95;
  letter-spacing: -0.02em; margin: 0 0 .6em; text-wrap: balance;
}
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); line-height: 1.05; }
h4 { font-size: var(--step-0); letter-spacing: 0; }
p  { margin: 0 0 1.1em; max-width: 68ch; }
ul, ol { margin: 0 0 1.1em; padding-left: 1.15rem; max-width: 68ch; }
li { margin-bottom: .45em; }
img, svg { max-width: 100%; height: auto; display: block; }
strong { font-weight: 700; }

a { color: inherit; text-decoration-thickness: 2px; text-underline-offset: 3px; }
a:hover { text-decoration-color: var(--terracotta); }

:focus-visible { outline: var(--rule) solid var(--terracotta); outline-offset: 3px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--forest); color: var(--sand);
  padding: .75rem 1.25rem; font-family: var(--font-cond);
  text-transform: uppercase; letter-spacing: .12em;
  border-bottom-right-radius: var(--radius-sm);
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- 3. Layout ----------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.section { position: relative; padding-block: clamp(3.5rem, 8vw, 7rem); }
.section--forest { background: var(--forest); color: var(--sand); }
.section--slate  { background: var(--slate); color: var(--sand); }
.section--band   { background: var(--sand-deep); }

.grid { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); }
/* Grid items default to min-width:auto, so a long unbreakable token (an email
   address in a button) can force a column wider than the viewport. */
.grid > * { min-width: 0; }
/* start, not the default: the two columns hold .phase blocks of differing
   length, and without it a short one sits level with the bottom of a tall
   one beside it, so the day labels no longer line up across the row. */
@media (min-width: 720px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); align-items: start; } }
@media (min-width: 900px)  { .grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1000px) { .grid--split { grid-template-columns: 1.15fr .85fr; align-items: start; } }
/* Stacked, the details panel sits between the opening paragraphs and the body
   copy - the practical facts before the pitch. Placed explicitly above 1000px
   so it still occupies the right-hand column there. */
@media (min-width: 1000px) {
  .trail-layout__intro { grid-column: 1; grid-row: 1; }
  .trail-layout__body  { grid-column: 1; grid-row: 2; }
  .trail-layout__aside { grid-column: 2; grid-row: 1 / span 2; align-self: start; }
}

/* Meet the team, pulled up by ten per cent of the screen height, with the same
   floor so it never collides with the statements above it. */
.section--team { padding-top: max(1.5rem, calc(clamp(3.5rem, 8vw, 7rem) - 10vh)); }

/* Recent projects on the home page, pulled up by eight per cent of the screen
   height, with the same floor. */
.section--recent { padding-top: max(1.5rem, calc(clamp(3.5rem, 8vw, 7rem) - 8vh)); }

/* --- 4. Constructivist devices ------------------------------------------- */
.kicker {
  display: inline-flex; align-items: center; gap: .6rem;
  font-family: var(--font-cond); font-weight: 700;
  text-transform: uppercase; letter-spacing: .22em;
  font-size: var(--step--1); margin: 0 0 1rem;
}
.kicker::before { content: ""; width: 2.5rem; height: var(--rule); background: var(--terracotta); }

.section-head { margin-bottom: clamp(2rem, 4vw, 3rem); }
/* Outlined poster numeral. Decorative only - the heading beside it carries the meaning. */
.section-head__num {
  font-family: var(--font-display); font-size: var(--step-3); line-height: 1;
  color: transparent; -webkit-text-stroke: 2px var(--accent-text);
}
.section--forest .section-head__num,
.section--slate .section-head__num { -webkit-text-stroke-color: var(--terracotta); }
.section-head__bar { height: var(--rule-thick); background: currentColor; margin: .8rem 0 1.4rem; }

.block {
  background: var(--sand); border: var(--rule) solid var(--forest);
  box-shadow: var(--block-shadow); padding: clamp(1.4rem, 3vw, 2.2rem);
  border-radius: var(--radius);
}
.block--forest { background: var(--forest); color: var(--sand); box-shadow: 10px 10px 0 var(--terracotta); }
.block--terracotta { background: var(--terracotta); color: var(--forest); box-shadow: 10px 10px 0 var(--forest); }
.block--flat { box-shadow: none; }

.stripe {
  background-image: repeating-linear-gradient(-45deg, var(--terracotta) 0 8px, transparent 8px 18px);
}

.slant-bottom { clip-path: polygon(0 0, 100% 0, 100% calc(100% - 3.5vw), 0 100%); }

/* --- 5. Buttons ---------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: .7rem;
  font-family: var(--font-cond); font-weight: 700; font-size: var(--step-0);
  text-transform: uppercase; letter-spacing: .1em; text-decoration: none;
  /* Labels containing an email address must be able to break on narrow screens.
     No flex-wrap: the label wraps within its own flex item so the trailing
     arrow stays beside it instead of dropping to a line of its own. */
  max-width: 100%; overflow-wrap: anywhere;
  padding: .85rem 1.5rem; border: var(--rule) solid var(--forest);
  background: var(--terracotta); color: var(--forest);
  box-shadow: 6px 6px 0 var(--forest); cursor: pointer;
  border-radius: var(--radius-sm);
  transition: transform .12s linear, box-shadow .12s linear;
}
.btn:hover, .btn:focus-visible { transform: translate(3px, 3px); box-shadow: 3px 3px 0 var(--forest); }
.btn--ghost { background: transparent; color: inherit; border-color: currentColor; box-shadow: 6px 6px 0 var(--terracotta); }
.btn--ghost:hover, .btn--ghost:focus-visible { box-shadow: 3px 3px 0 var(--terracotta); }
.btn--sand { background: var(--sand); color: var(--forest); border-color: var(--sand); box-shadow: 6px 6px 0 var(--terracotta); }
@media (prefers-reduced-motion: reduce) { .btn { transition: none; } }

/* A primary action that should read as the point of the panel it sits in:
   larger type, deeper padding, and filling its column rather than floating
   at label width. */
.btn--lg { font-size: var(--step-1); padding: 1.05rem 2rem; box-shadow: 8px 8px 0 var(--forest); }
.btn--lg:hover, .btn--lg:focus-visible { box-shadow: 4px 4px 0 var(--forest); }
.btn--block { width: 100%; justify-content: center; }

.btn-row { display: flex; flex-wrap: wrap; gap: 1rem 1.4rem; margin-top: 1.75rem; }

/* --- 6. Header / navigation ---------------------------------------------- */
.masthead {
  position: sticky; top: 0; z-index: 50;
  background: var(--forest); color: var(--sand);
  border-bottom: var(--rule-thick) solid var(--terracotta);
}
.masthead__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; min-height: var(--masthead-h);
  /* Tighter than the page gutter, so the wordmark sits closer to the edge. */
  padding-inline: clamp(1rem, 2vw, 1.75rem);
}

.brand { display: flex; align-items: center; gap: .75rem; text-decoration: none; color: inherit; }
/* No logo in the masthead - the wordmark carries the brand here, and the logo
   appears full size in the home hero instead. */
.brand__name { font-family: var(--font-display); font-size: clamp(1.15rem, 4.4vw, 1.9rem); line-height: 1; text-transform: uppercase; white-space: nowrap; }

.nav__list { display: flex; gap: clamp(1.25rem, 2.6vw, 2.5rem); list-style: none; margin: 0; padding: 0; }
.nav__list li { margin: 0; }
.nav__link {
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .1em; font-size: 1.3rem; text-decoration: none; white-space: nowrap;
  padding: .5rem 0; border-bottom: var(--rule) solid transparent; display: block;
}
.nav__link:hover { border-bottom-color: var(--terracotta); }
.nav__link[aria-current="page"] { border-bottom-color: var(--terracotta); }

.nav-toggle { display: none; }
/* Three bars that fold into a cross when the menu is open. The button keeps a
   real text label for screen readers; only the glyph is visual. */
.nav-toggle__bars { display: block; position: relative; width: 24px; height: 18px; }
.nav-toggle__bars span {
  position: absolute; left: 0; width: 100%; height: 3px;
  background: var(--terracotta); border-radius: 2px;
  transition: transform .18s ease, opacity .12s linear;
}
.nav-toggle__bars span:nth-child(1) { top: 0; }
.nav-toggle__bars span:nth-child(2) { top: 50%; transform: translateY(-50%); }
.nav-toggle__bars span:nth-child(3) { bottom: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1) { top: 50%; transform: translateY(-50%) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3) { bottom: 50%; transform: translateY(50%) rotate(-45deg); }
@media (prefers-reduced-motion: reduce) { .nav-toggle__bars span { transition: none; } }

/* Below this the wordmark and four links no longer fit on one line together,
   so the menu button takes over rather than letting labels wrap. */
@media (max-width: 1120px) {
  :root { --masthead-h: 108px; }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    background: none; color: inherit;
    border: 0; cursor: pointer;
    /* Keep a 48px touch target now that the border no longer adds to it. */
    padding: .75rem; min-width: 48px; min-height: 48px;
    border-radius: var(--radius-sm);
  }
  .nav {
    position: absolute; inset: 100% 0 auto 0; background: var(--forest);
    border-bottom: var(--rule-thick) solid var(--terracotta);
    padding: 1rem var(--gutter) 1.5rem; display: none;
  }
  .nav[data-open="true"] { display: block; }
  .nav__list { flex-direction: column; gap: 0; }
  .nav__link { padding: .8rem 0; border-bottom: 1px solid rgba(242,232,213,.2); }
  .nav__link[aria-current="page"] { border-bottom-color: var(--terracotta); }
}

/* --- 7. Hero ------------------------------------------------------------- */
/* The extra 4vh on the top pushes the hero down by four per cent of the screen
   height, so it scales with the viewport rather than being a fixed nudge. */
.hero {
  position: relative; overflow: hidden; background: var(--sand);
  padding-block: calc(clamp(3rem, 7vw, 6rem) + 4vh) clamp(2rem, 4vw, 3.25rem);
}
.hero__inner { display: grid; gap: clamp(2rem, 4vw, 3.5rem); align-items: center; }
/* The logo leads: left column on wide screens, above the headline when the
   hero stacks. The swap is done with `order` so the h1 still comes first in
   the document, whatever the visual order. */
.hero__art  { order: 1; }
.hero__copy { order: 2; }
@media (min-width: 1000px) {
  .hero__inner { grid-template-columns: .95fr 1.05fr; }
}

/* Sits between the h2 and h1 steps: still the largest thing on the page, but
   no longer overpowering the logo beside it. */
.hero__title { font-size: clamp(1.8rem, 1.3rem + 2.4vw, 3.2rem); margin-bottom: .45em; }
.hero__title-accent { color: var(--accent-text); display: block; }
.hero__lead { font-size: var(--step-1); line-height: 1.4; max-width: 34ch; margin: 0 0 .2em; }
.hero__art { position: relative; }
/* Background-free logo, sitting straight on the Warm Sand hero, nudged up by
   3% of its own height (down from an original 10% after several adjustments). */
.hero__logo {
  width: min(100%, 360px); height: auto; margin-inline: auto;
  transform: translateY(-3%);
}
/* Stacked, the logo sits above the headline and at full size it dominated the
   first screen, so it drops 30% there and keeps its desktop size alongside. */
@media (max-width: 999px) { .hero__logo { width: min(70%, 252px); } }

/* --- 8. Figures ---------------------------------------------------------- */
.figures { display: grid; gap: 0; border: var(--rule) solid currentColor; border-radius: var(--radius); overflow: hidden; }
@media (min-width: 760px) { .figures { grid-template-columns: repeat(4, 1fr); } }
.figure { padding: clamp(1.2rem, 2.5vw, 1.8rem); border-bottom: var(--rule) solid currentColor; }
.figure:last-child { border-bottom: 0; }
@media (min-width: 760px) {
  .figure { border-bottom: 0; border-right: var(--rule) solid currentColor; }
  .figure:last-child { border-right: 0; }
}
.figure__value { font-family: var(--font-display); font-size: var(--step-3); line-height: 1; color: var(--accent-text); }
.figure__label { font-family: var(--font-cond); text-transform: uppercase; letter-spacing: .12em; font-size: var(--step--1); margin-top: .6rem; }

/* --- 10. Pillars --------------------------------------------------------- */
.pillar { position: relative; border-top: var(--rule-thick) solid var(--forest); padding-top: 1.4rem; }
.pillar__num { font-family: var(--font-display); font-size: var(--step-2); line-height: 1; color: var(--accent-text); display: block; margin-bottom: .4rem; }
.pillar__rule { font-family: var(--font-cond); text-transform: uppercase; letter-spacing: .12em; font-size: var(--step--1); border-top: 1px solid var(--sand-line); padding-top: .8rem; margin-top: 1rem; }

/* --- 11. Cards ----------------------------------------------------------- */
.card { border: var(--rule) solid var(--forest); background: var(--sand); display: flex; flex-direction: column; height: 100%; border-radius: var(--radius); overflow: hidden; }
.card__head { background: var(--forest); color: var(--sand); padding: 1rem 1.25rem; display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.card__eyebrow { font-family: var(--font-cond); text-transform: uppercase; letter-spacing: .16em; font-size: var(--step--1); font-weight: 700; }
.card__body { padding: clamp(1.25rem, 2.5vw, 1.75rem); flex: 1; }
.card__foot { padding: 0 clamp(1.25rem, 2.5vw, 1.75rem) clamp(1.25rem, 2.5vw, 1.75rem); }

/* Pill: fully rounded ends. Extra horizontal padding keeps the text off the curve. */
.badge {
  display: inline-flex; align-items: center; gap: .45rem;
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; font-size: var(--step--1);
  border: 2px solid currentColor; padding: .25rem .85rem;
  border-radius: var(--radius-pill);
}
.badge__dot { width: 9px; height: 9px; background: currentColor; border-radius: 50%; flex: none; }

.meta { margin: 0 0 1.4rem; }
.meta > div { display: grid; grid-template-columns: 9rem 1fr; gap: .75rem; padding: .55rem 0; border-bottom: 1px solid var(--sand-line); align-items: baseline; }
.meta dt { font-family: var(--font-cond); text-transform: uppercase; letter-spacing: .12em; font-size: var(--step--1); font-weight: 700; }
.meta dd { margin: 0; }
@media (max-width: 480px) { .meta > div { grid-template-columns: 1fr; gap: .1rem; } }

.price { font-family: var(--font-display); font-size: var(--step-2); line-height: 1; }
.price small { font-family: var(--font-cond); font-size: var(--step--1); text-transform: uppercase; letter-spacing: .14em; display: block; margin-top: .5rem; font-weight: 700; }

/* --- 11b. Jump links (in-page navigation) -------------------------------- */
.jumplinks { display: flex; flex-wrap: wrap; gap: .6rem; list-style: none; margin: 1.75rem 0 0; padding: 0; }
.jumplinks li { margin: 0; }
.jumplink {
  display: inline-flex; align-items: center;
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; font-size: var(--step--1); text-decoration: none;
  padding: .5rem 1.25rem; border: 2px solid currentColor;
  border-radius: var(--radius-pill);
}
.jumplink:hover, .jumplink:focus-visible { background: var(--sand); color: var(--forest); border-color: var(--sand); }

/* --- 13. Team ------------------------------------------------------------ */
/* Each profile is a horizontal pill: portrait at the left, text beside it.
   Generous side padding keeps content clear of the rounded ends. */
.grid--people { grid-template-columns: 1fr; }

.person {
  background: var(--sand-deep);
  border: var(--rule) solid var(--forest);
  border-radius: 24px;
  /* Rectangular rather than a capsule, so the side padding no longer has to
     clear a curve and the text can sit closer to the edges. */
  padding: clamp(1.75rem, 3vw, 2.25rem) clamp(1.75rem, 3vw, 2.5rem);
  display: flex; flex-direction: row; align-items: center;
  gap: clamp(1.5rem, 3vw, 2.75rem);
}
.person__body { flex: 1; min-width: 0; }

@media (max-width: 640px) {
  /* Too narrow for a side-by-side pill, so the portrait sits above the text. */
  .person {
    flex-direction: column; align-items: center; text-align: center;
    padding: clamp(1.75rem, 6vw, 2.25rem) clamp(1.5rem, 5vw, 2rem);
  }
  .person__body { width: 100%; }
  .person p:not(.person__role) { text-align: left; }
}
.person__name { font-family: var(--font-display); font-size: var(--step-1); margin: 0 0 .25rem; }
/* Accent carried by a terracotta rule rather than coloured text, so the label
   keeps full contrast on both sand and forest. */
.person__role {
  font-family: var(--font-cond); text-transform: uppercase; letter-spacing: .14em;
  font-size: var(--step--1); font-weight: 700; margin: 0 0 1.1rem;
  display: inline-block; padding-bottom: .5rem; border-bottom: var(--rule) solid var(--terracotta);
}
/* Portrait and initials fallback share a size so the team grid stays even.
   Round, to sit with the pill card. */
.person__photo,
.person__initial {
  width: 124px; height: 124px; margin: 0 0 1.25rem;
  border: var(--rule) solid var(--forest); border-radius: 50%;
  overflow: hidden; flex: none;
}
.person__photo { background: var(--sand-deep); }
.person__photo img {
  width: 100%; height: 100%; object-fit: cover;
  /* Per-person framing: --pos centres the face, --zoom crops in on wider shots. */
  object-position: var(--pos, 50% 30%);
  transform: scale(var(--zoom, 1));
  transform-origin: var(--origin, 50% 30%);
}
.person__initial {
  display: grid; place-items: center;
  background: var(--terracotta); color: var(--forest);
  font-family: var(--font-display); font-size: 2rem; line-height: 1;
}

/* Expand / collapse for the longer biographies. Added by JavaScript, so with
   scripting off every paragraph is simply shown. */
.person__toggle {
  margin-top: 1.25rem; cursor: pointer;
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; font-size: var(--step--1);
  background: transparent; color: var(--forest);
  border: 2px solid var(--forest); border-radius: var(--radius-pill);
  padding: .5rem 1.35rem;
}
.person__toggle:hover, .person__toggle:focus-visible { background: var(--terracotta); border-color: var(--terracotta); }
.person__more > p:last-child { margin-bottom: 0; }

/* --- 13b. Story pills ----------------------------------------------------
   The whole card is the link, so there is one tab stop per project rather than
   a separate cue link inside each. */
.story-pill {
  display: flex; flex-direction: column; height: 100%;
  background: var(--sand-deep); color: inherit; text-decoration: none;
  border: var(--rule) solid var(--forest); border-radius: 24px;
  padding: clamp(1.75rem, 3vw, 2.25rem);
  transition: transform .12s linear, box-shadow .12s linear;
}
.story-pill:hover, .story-pill:focus-visible {
  transform: translate(-3px, -3px);
  box-shadow: 6px 6px 0 var(--terracotta);
}
@media (prefers-reduced-motion: reduce) { .story-pill { transition: none; } }

/* A pill carrying its project photo becomes two columns above 720px: image
   left, text right. The body keeps its own column so the cue still sits at
   the bottom of the card. */
.story-pill__body { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.story-pill__media {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border: var(--rule) solid var(--forest); border-radius: var(--radius-sm);
  margin-bottom: 1.5rem; background: var(--sand);
}
@media (min-width: 720px) {
  .story-pill:has(.story-pill__media) { flex-direction: row; gap: clamp(1.25rem, 3vw, 2rem); }
  .story-pill__media {
    flex: 0 0 auto; width: clamp(200px, 30%, 330px);
    height: auto; align-self: stretch; aspect-ratio: auto; margin-bottom: 0;
  }
}

.story-pill__place {
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .14em; font-size: var(--step--1); margin: 0 0 .9rem;
  padding-bottom: .5rem; border-bottom: var(--rule) solid var(--terracotta);
  display: inline-block; align-self: flex-start;
}
.story-pill__title { font-size: var(--step-1); margin-bottom: .7em; }
.story-pill__summary { margin-bottom: 1.5rem; }
/* Pushed to the bottom so the cue lines up across cards of unequal length. */
.story-pill__cue {
  margin-top: auto; display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; font-size: var(--step--1); color: var(--accent-text);
}
.story-pill:hover .story-pill__cue { text-decoration: underline; text-underline-offset: 4px; }

/* --- 13b2. Trail pills ---------------------------------------------------
   A compact version of the story pill: enough to decide whether to click, with
   the full itinerary, fee and booking on the trail's own page. */
.trail-pill {
  display: flex; flex-direction: row; align-items: stretch; height: 100%;
  background: var(--sand-deep); color: inherit; text-decoration: none;
  border: var(--rule) solid var(--forest); border-radius: 24px;
  padding: clamp(1.5rem, 2.5vw, 1.9rem) clamp(1.5rem, 2.5vw, 2rem);
  gap: clamp(1.5rem, 3vw, 2.5rem);
  transition: transform .12s linear, box-shadow .12s linear;
}
.trail-pill:hover, .trail-pill:focus-visible {
  transform: translate(-3px, -3px);
  box-shadow: 6px 6px 0 var(--terracotta);
}
@media (prefers-reduced-motion: reduce) { .trail-pill { transition: none; } }

/* A pill carrying a photo keeps its row: the image is a narrow column on the
   left, so the card stays the height of its copy rather than growing to fit a
   banner. */
.trail-pill__media {
  flex: 0 0 auto; width: clamp(150px, 23%, 260px);
  align-self: stretch; height: auto; object-fit: cover; object-position: 50% 40%;
  border: var(--rule) solid var(--forest); border-radius: var(--radius-sm);
  background: var(--sand);
}
.trail-pill__row { flex: 1 1 auto; min-width: 0; display: flex; align-items: stretch; gap: clamp(1.5rem, 3vw, 2.5rem); }
@media (max-width: 760px) {
  /* Stacked, the photo goes full width above the copy. */
  .trail-pill__media { width: 100%; aspect-ratio: 16 / 9; align-self: auto; }
  .trail-pill__row { flex-direction: column; }
}

.trail-pill__main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.trail-pill__title { font-size: var(--step-1); margin-bottom: .5em; }
.trail-pill__summary { margin-bottom: 1.25rem; }
.trail-pill__cue {
  margin-top: auto; display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; font-size: var(--step--1); color: var(--accent-text);
}
.trail-pill:hover .trail-pill__cue { text-decoration: underline; text-underline-offset: 4px; }

/* Dates, length and fee sit in their own column at the right, divided from the
   copy by a rule rather than a gap so the pill still reads as one object. */
.trail-pill__facts {
  flex: none; width: 15rem; margin: 0;
  border-left: var(--rule) solid var(--terracotta);
  padding-left: clamp(1.25rem, 2.5vw, 1.75rem);
}
.trail-pill__facts > div + div { margin-top: .9rem; }
.trail-pill__facts dt {
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .14em; font-size: var(--step--1); margin-bottom: .15rem;
}
.trail-pill__facts dd { margin: 0; font-family: var(--font-cond); font-weight: 700; font-size: var(--step-0); }
.trail-pill__fee { font-family: var(--font-display) !important; font-size: var(--step-1) !important; }

@media (max-width: 760px) {
  /* Too narrow for two columns: the facts move under the copy. */
  .trail-pill { flex-direction: column; }
  .trail-pill__facts {
    width: 100%; margin-top: 1.5rem; padding-left: 0; padding-top: 1.25rem;
    border-left: 0; border-top: var(--rule) solid var(--terracotta);
    display: flex; flex-wrap: wrap; gap: 1.25rem 2rem;
  }
  .trail-pill__facts > div + div { margin-top: 0; }
}

/* --- 13c. Story pages ---------------------------------------------------- */
/* These titles carry a story number and a full place name, so they run long.
   Set two steps down from the site h1 to keep them to a couple of lines. */
.section--story h1 { font-size: var(--step-2); }

/* The part of a heading before the colon takes its own line, so the label and
   the subject read as two steps rather than one long run-on. */
.head-label { display: block; }

.story-body { max-width: 78ch; }
.story-body h2 { font-size: var(--step-2); margin-top: 2.5em; }
.story-body > :first-child { margin-top: 0; }
.story-body ul ul { margin-top: .8rem; }

.story-figure { margin: 0 0 2.5rem; }
.story-figure img {
  width: 100%; height: auto;
  border: var(--rule) solid var(--forest); border-radius: var(--radius);
}
/* Photographs that follow the copy sit in a pair on wider screens. */
.story-figure + .story-figure { margin-top: -1rem; }

/* --- 14. Phases ---------------------------------------------------------- */
.phase { border-left: var(--rule-thick) solid var(--terracotta); padding-left: clamp(1.2rem, 3vw, 2rem); }
.phase + .phase { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
/* That margin is for phases following one another in normal flow. Inside a
   grid the gap already spaces them, and the margin only pushes an item down
   within its own cell — which left the second column sitting lower than the
   first and the day labels out of line across the row. Direct children only:
   a .stack of phases nested inside a grid still needs its stacking margin. */
.grid > .phase + .phase { margin-top: 0; }
.phase__tag { font-family: var(--font-cond); font-weight: 700; text-transform: uppercase; letter-spacing: .18em; font-size: var(--step--1); display: block; margin-bottom: .5rem; }

/* --- 15. Partner tiles --------------------------------------------------- */
.partner { border: var(--rule) solid var(--forest); padding: clamp(1.2rem, 2.5vw, 1.75rem); display: flex; flex-direction: column; gap: .6rem; background: var(--sand); height: 100%; border-radius: var(--radius); }
.partner__name { font-family: var(--font-display); font-size: var(--step-1); margin: 0; }
.partner__mark { width: 46px; height: 46px; background: var(--forest); color: var(--sand); display: grid; place-items: center; font-family: var(--font-display); font-size: 1.1rem; border-radius: var(--radius-sm); }
/* A logo wall: no card, no plate. The border wraps each logo at its own
   proportions rather than boxing it into a fixed tile. */
.partner--plain {
  border: 0; background: none; padding: 0; border-radius: 0;
  align-items: flex-start;
}
.partner--plain .partner__logo {
  width: auto; height: auto; max-width: 100%; max-height: 116px;
  background: none; padding: 0; margin-bottom: 0;
  border: var(--rule) solid var(--forest); border-radius: var(--radius-sm);
}
/* The Yes We Can PNG carries real transparency, so on the sand band it needs a
   ground of its own. The other logos have their backgrounds baked in. */
.partner--plain .partner__logo--plate { background: var(--white); padding: 8px; }

/* A logo wall is a single 116px row, so the full section rhythm - meant for a
   band of prose - left it floating in space. Tightened top, bottom and the
   gap under the heading. */
#partners { padding-block: clamp(2rem, 4vw, 3rem); }
#partners .section-head { margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem); }

/* Six partners on a fixed three-column grid, so they read as two even rows
   rather than however many happen to fit. Equal cells also keep the logos
   evenly spaced despite their very different proportions. */
.partner-wall {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.75rem, 3.5vw, 2.75rem);
  align-items: center; justify-items: center;
}
@media (min-width: 760px) { .partner-wall { grid-template-columns: repeat(3, 1fr); } }
.partner-wall .partner--plain { align-items: center; width: 100%; }

/* Supplied logos carry their own backgrounds - three white, one black, one dark
   blue - so each sits in a uniform white tile at a fixed height. contain keeps
   every logo whole whatever its aspect ratio. */
.partner__logo {
  width: 100%; height: 116px; object-fit: contain;
  background: var(--white); border: var(--rule) solid var(--forest);
  border-radius: var(--radius-sm); padding: 12px; margin-bottom: .3rem;
}

/* --- 16. Callout --------------------------------------------------------- */
/* Top rule only. A bottom rule would draw a green line between the callout and
   the footer's own terracotta rule, which read as a stray stripe. */
.callout { background: var(--terracotta); color: var(--forest); border-top: var(--rule-thick) solid var(--forest); }
.callout h2 { max-width: 22ch; }
/* Buttons sit level with the heading beside them rather than pinned to the top
   of their column, then drop a further tenth of their own height. */
.callout__actions { margin-top: 0; align-self: center; transform: translateY(10%); }
@media (max-width: 999px) { .callout__actions { align-self: start; transform: none; margin-top: 1.75rem; } }

/* --- 17. Footer ---------------------------------------------------------- */
.footer { background: var(--forest); color: var(--sand); padding-block: clamp(1.1rem, 2vw, 1.5rem); border-top: var(--rule-thick) solid var(--terracotta); }
.footer__grid { display: grid; gap: 2.5rem; }
@media (min-width: 760px) { .footer__grid { grid-template-columns: 1.5fr 1fr 1fr; } }
.footer__title {
  font-family: var(--font-cond); text-transform: uppercase; letter-spacing: .18em;
  font-size: var(--step--1); font-weight: 700; margin: 0 0 1.1rem;
  display: inline-block; padding-bottom: .5rem; border-bottom: var(--rule) solid var(--terracotta);
}
.footer__list { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.footer__list li { margin: 0; }
.footer__bottom {
  margin-top: clamp(2.5rem, 5vw, 4rem); padding-top: 1.25rem;
  border-top: 1px solid rgba(242,232,213,.25);
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
  font-family: var(--font-cond); text-transform: uppercase; letter-spacing: .12em; font-size: var(--step--1);
}

/* With the three-column block gone, the bottom bar is all the footer holds.
   Its top rule and the gap above it would otherwise hang off nothing. */
.footer__bottom:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
@media (max-width: 640px) {
  .footer__bottom { flex-direction: column; align-items: center; text-align: center; gap: .35rem; }
  .footer__bottom p { margin: 0; }
}

/* --- 18. Interior page header -------------------------------------------- */
.page-head { position: relative; overflow: hidden; background: var(--forest); color: var(--sand); padding-block: clamp(3rem, 7vw, 5.5rem); }
.page-head h1 { max-width: 16ch; }
/* Headers carrying a title alone, with no supporting line beneath it, are set
   a step down so the band does not tower over the content it introduces. */
.page-head--compact h1 { font-size: var(--step-3); max-width: 22ch; }
.page-head__lead { font-size: var(--step-1); max-width: 48ch; line-height: 1.4; }

/* --- 19. Prose helpers --------------------------------------------------- */
.lead { font-size: var(--step-1); line-height: 1.45; max-width: 54ch; }
/* The vision and mission statements run to the full content width so they line
   up with the edges of the list beneath them. Everything in the section is set
   a tenth smaller than the site scale; the type steps are absolute clamps, so
   each one is scaled explicitly rather than inherited from a parent per cent. */
.section--statement .lead { max-width: none; font-size: calc(var(--step-1) * 0.72); }
/* Short statements, not a band of prose - the full section rhythm left a lot
   of empty ground above and below them. */
.section--statement { padding-block: clamp(2.25rem, 4.5vw, 3.25rem); }
.section--statement h1,
.section--statement h2 { margin-bottom: .55rem; }

/* "Vision Statement" is the page h1, so it takes the h2 size to match
   "Mission Statement" visually while keeping the heading order intact. */
.section--statement h1,
.section--statement h2 { font-size: calc(var(--step-3) * 0.72); }

/* A heading kept at its size but set in the body face at regular weight, so it
   reads as a lead-in rather than a bold display heading. */
.heading--plain { font-family: var(--font-body); font-weight: 400; letter-spacing: 0; }
.note { font-size: var(--step--1); border-left: var(--rule) solid var(--terracotta); padding-left: 1rem; max-width: 62ch; }
.list-clean { list-style: none; padding: 0; }
.list-clean li { position: relative; padding-left: 1.6rem; }
.list-clean li::before { content: ""; position: absolute; left: 0; top: .62em; width: .7rem; height: .7rem; background: var(--terracotta); }
.stack > * + * { margin-top: 1.5rem; }
/* A short primer above the trail listing: deliberately lighter than a full
   section, so it introduces without competing with the trail it precedes. */
.trail-primer { padding-block: clamp(1.75rem, 3.5vw, 2.75rem) 0; }
.trail-primer__title { font-size: var(--step-1); margin-bottom: .4em; }
.trail-primer__text { max-width: none; margin: 0 0 .9em; }
.trail-primer__text:last-child { margin-bottom: 0; }
.trail-primer__text + .trail-primer__text + .trail-primer__text { margin-top: -.6em; }

/* Sits directly under the hero on the same ground, so it does not need the
   full section rhythm above it as well. */
[aria-labelledby="what-is-a-trail"] { padding-top: clamp(1.5rem, 3vw, 2.5rem); }
.prose-measure, .prose-measure p { max-width: none; }
.prose-measure .lead + p { margin-bottom: .3em; }

/* --- 20. Reveal on scroll ------------------------------------------------ */
/* Guarded by the `js` class so content is always visible without JavaScript. */
.js .reveal { opacity: 0; transform: translateY(18px); transition: opacity .5s ease-out, transform .5s ease-out; }
.js .reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .js .reveal { opacity: 1; transform: none; transition: none; } }
@media print { .js .reveal { opacity: 1; transform: none; } }

/* --- 21. Contact form ---------------------------------------------------- */
/* No backend on this site, so the form composes a pre-addressed message and
   hands it to the visitor's mail app. The plain address stays visible above it
   so there is always a route that does not depend on JavaScript. */
.contact-form { display: grid; gap: 1.35rem; max-width: 46rem; }
/* .field is a <p>, so the global 68ch paragraph cap would otherwise size the
   fields by accident. The width is set once, on the form. */
.field { display: grid; gap: .5rem; max-width: none; }
.field > label {
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .16em; font-size: var(--step--1);
}
.field input,
.field textarea {
  font: inherit; color: var(--forest); width: 100%;
  background: var(--white); border: var(--rule) solid var(--forest);
  border-radius: var(--radius-sm); padding: .8rem 1rem;
}
.field textarea { resize: vertical; min-height: 10rem; }
.field input::placeholder,
.field textarea::placeholder { color: var(--slate); opacity: .55; }
.field input:focus-visible,
.field textarea:focus-visible { outline: var(--rule) solid var(--terracotta); outline-offset: 2px; }
/* The browser's own :invalid fires before the field has been touched, so the
   marker is held back until a submit has been attempted. */
.contact-form[data-submitted="true"] input:invalid,
.contact-form[data-submitted="true"] textarea:invalid { border-color: var(--terracotta-2); }

.form-status {
  border-left: var(--rule) solid var(--terracotta); padding-left: 1rem;
  max-width: 62ch; font-size: var(--step--1); margin: 0;
}

/* --- 24. Booking bar ----------------------------------------------------- */
/* Narrow screens only: the trail page runs past 4,000px, so the price and the
   booking action would otherwise be a long scroll back up. */
.book-bar { display: none; }
@media (max-width: 999px) {
  .book-bar {
    /* sticky, not fixed: it rides the foot of the screen while .book-zone is on
       it, then settles at the zone's end - immediately above the FAQ. */
    display: block; position: sticky; bottom: 0; z-index: 40;
    background: var(--forest); border-top: var(--rule) solid var(--terracotta);
    padding-block: .7rem;
  }
  .book-bar__inner { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
  .book-bar__price {
    margin: 0; color: var(--sand); font-family: var(--font-display);
    font-size: var(--step-1); line-height: 1;
  }
  .book-bar__price span {
    display: block; font-family: var(--font-cond); font-weight: 700;
    text-transform: uppercase; letter-spacing: .12em; font-size: .68rem;
    margin-top: .3rem; opacity: .8;
  }
  /* Sand label and edge on the terracotta button, with no offset shadow: the
     border alone carries the definition down here. */
  .book-bar .btn {
    flex: 0 0 auto;
    color: var(--sand);
    border-color: var(--sand);
    box-shadow: none;
  }
  /* With no shadow to shorten, the press reads as a darker fill instead of a
     nudge - and :active matters because touch has no hover. */
  .book-bar .btn:hover,
  .book-bar .btn:focus-visible,
  .book-bar .btn:active {
    transform: none;
    box-shadow: none;
    background: var(--accent-text);
  }
  /* The bar carries this action here, so the panel keeps the facts only. */
  .trail-layout__aside .btn-row { display: none; }
}

/* --- 22. FAQ ------------------------------------------------------------- */
/* Native <details>, so every answer is reachable with JavaScript disabled and
   the disclosure state is handled by the browser rather than by script. */
.faq { display: grid; gap: 1rem; }
.faq__item {
  border: var(--rule) solid var(--forest); border-radius: var(--radius);
  background: var(--sand); padding: clamp(1rem, 2.2vw, 1.4rem) clamp(1.1rem, 2.5vw, 1.6rem);
}
.faq__q {
  cursor: pointer; list-style: none;
  display: flex; align-items: baseline; gap: .9rem;
  font-family: var(--font-display); font-size: var(--step-1); line-height: 1.15;
}
/* Both are needed: WebKit uses its own pseudo-element for the marker. */
.faq__q::-webkit-details-marker { display: none; }
.faq__q::marker { content: ""; }
.faq__q:focus-visible { outline: var(--rule) solid var(--terracotta); outline-offset: 4px; }
/* A plain +/- drawn in text, so it needs hiding from the accessible name -
   the open/closed state is already announced by details itself. */
.faq__sign {
  flex: 0 0 auto; color: var(--accent-text);
  font-family: var(--font-cond); font-weight: 700;
}
.faq__item[open] .faq__sign::before { content: "\2212"; }
.faq__sign::before { content: "+"; }
.faq__a { margin-top: 1rem; }
.faq__a > :last-child { margin-bottom: 0; }

/* --- 23. Booking form embed ---------------------------------------------- */
/* Until a form URL is set the container holds the email fallback, so it is
   sized by its content rather than given a frame-shaped hole. */
.form-embed { min-width: 0; }
.form-embed__pending {
  border: var(--rule) solid var(--forest); border-radius: var(--radius);
  background: var(--sand-deep); padding: clamp(1.2rem, 2.5vw, 1.75rem); margin: 0;
}
.form-embed__frame {
  display: block; width: 100%; height: 620px; border: 0;
  border-radius: var(--radius); background: var(--sand);
}
.form-embed__direct { font-size: var(--step--1); margin: 1rem 0 0; }

/* The crumb is inside the layout now, so it carries its own bottom gap. */
.booking-crumb { margin-bottom: clamp(1.25rem, 3vw, 2rem); }
.booking-section { padding-block: clamp(1.5rem, 3vw, 2.5rem) clamp(3.5rem, 8vw, 7rem); }
@media (max-width: 999px) {
  .booking-summary { margin-top: clamp(2.25rem, 6vw, 3.25rem); margin-bottom: 0; }
}

/* --- 25. Booking summary -------------------------------------------------- */
/* A disclosure on narrow screens - the facts sit above the form, folded away so
   the form itself is reachable without scrolling past them. Above 1000px the
   summary reverts to a plain panel in the right-hand column. */
.booking-summary__box {
  border: var(--rule) solid var(--forest); border-radius: var(--radius);
  background: var(--sand); box-shadow: var(--block-shadow);
  padding: clamp(1.1rem, 2.5vw, 1.75rem);
}
.booking-summary__head {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: .75rem;
}
/* Both are needed: WebKit uses its own pseudo-element for the marker. */
.booking-summary__head::-webkit-details-marker { display: none; }
.booking-summary__head::marker { content: ""; }
.booking-summary__head:focus-visible { outline: var(--rule) solid var(--terracotta); outline-offset: 4px; }
.booking-summary__title { margin: 0; font-size: var(--step-1); flex: 1 1 auto; }
.booking-summary__chip {
  font-family: var(--font-display); font-size: var(--step-1); line-height: 1;
  color: var(--accent-text); flex: 0 0 auto;
}
/* The price is in the body once the panel is open, so the chip is for the
   folded state only. */
.booking-summary__box[open] .booking-summary__chip { display: none; }
.booking-summary__mark {
  flex: 0 0 auto; width: .7rem; height: .7rem; border-right: 3px solid var(--forest);
  border-bottom: 3px solid var(--forest); transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .18s ease;
}
.booking-summary__box[open] .booking-summary__mark { transform: rotate(-135deg) translate(-4px, -4px); }
.booking-summary__body { margin-top: 1.25rem; }
@media (prefers-reduced-motion: reduce) { .booking-summary__mark { transition: none; } }

@media (min-width: 1000px) {
  /* The summary leads the markup so it tops the page on a phone. Here the rows
     are named explicitly instead, restoring the full-width heading with the
     form and summary side by side beneath it. */
  .booking-layout { display: grid; grid-template-columns: 1.15fr .85fr; column-gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
  .booking-crumb { grid-column: 1 / -1; grid-row: 1; }
  .booking-layout > .section-head { grid-column: 1 / -1; grid-row: 2; }
  .booking-form-col { grid-column: 1; grid-row: 3; }
  .booking-summary  { grid-column: 2; grid-row: 3; }
  /* Always open, and with no disclosure affordance to suggest otherwise. */
  .booking-summary__head { cursor: default; }
  .booking-summary__mark { display: none; }
}

/* --- 21. Trails from the CMS --------------------------------------------
   The trails listing is written into trails.html and replaced at runtime by
   trips-render.js with whatever the trip editor holds. These rules cover the
   parts a written pill does not need: status badges, the filter bar, the
   action row and the lightbox. Everything else reuses .trail-pill. */

/* A rendered pill is an <article>, not a link — it carries its own buttons, and
   an anchor cannot contain them. So it takes the border and ground of a pill
   without the hover lift, which would promise a click the card does not have. */
.trail-pill--cms { transition: none; }
.trail-pill--cms:hover { transform: none; box-shadow: none; }

.trip-badges { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1rem; }

.badge--upcoming { color: var(--forest-soft); }
.badge--past     { color: var(--slate); opacity: .85; }
.badge--planning { color: var(--accent-text); }
/* A test booking must not read as one more neutral label, so it inverts. */
.badge--test { color: var(--white); background: var(--accent-text); border-color: var(--accent-text); }

/* --- 26. Pictures on a trip card ----------------------------------------
   A trail carries one to three pictures and they all sit on the card, as a
   column beside the copy. The itinerary poster is not among them: it is text
   on an image, so it only ever opens full size from its own button. */

.trip-media {
  flex: 0 0 auto; width: clamp(150px, 23%, 260px); align-self: flex-start;
  display: flex; flex-direction: column; gap: .6rem;
}

/* The photo becomes a button so it can be enlarged. Reset the button chrome so
   it is the image that shows, not a control wrapped around one. */
/* Not stretched to the card's height. A CMS card runs as tall as its
   description, and a stretched column turned into a tall portrait slot — at
   707px it held a 2.26:1 landscape photo in a 0.39:1 box, so object-fit: cover
   discarded 83% of the width and showed a sliver. The box is therefore a fixed
   landscape shape, aligned to the top, which keeps a wide photo recognisable
   whatever length the copy runs to. Full size is one tap away in the lightbox. */
.trip-media-btn {
  width: 100%; aspect-ratio: 4 / 3;
  padding: 0; border: 0; background: none; cursor: zoom-in; display: flex;
  border-radius: var(--radius-sm); overflow: hidden;
  /* A flex item's automatic minimum is its content, so a portrait photograph
     grew its own frame taller than the ratio and sat out of line with the
     landscape ones beside it. Zeroed on both axes, since the strip runs down
     the card on a wide screen and across it on a narrow one. */
  min-height: 0; min-width: 0;
}
.trip-media-btn .trail-pill__media { width: 100%; height: 100%; }
.trip-media-btn:focus-visible { outline: 3px solid var(--accent-text); outline-offset: 3px; }
@media (max-width: 760px) {
  /* Stacked, the pictures go full width above the copy and run across rather
     than down, so three of them do not push the copy off the screen. */
  /* flex-start, not the default stretch: stretched, each thumbnail takes its
     height from the strip rather than from its own ratio, and with the content
     minimum zeroed there is nothing left to give it one, so it collapses. */
  .trip-media { width: 100%; align-self: auto; flex-direction: row; align-items: flex-start; }
  .trip-media-btn { flex: 1 1 0; }
  /* A lone picture has the width to itself, so it takes the wider frame. */
  .trip-media-btn:only-child { aspect-ratio: 16 / 9; }
}

.trip-actions { margin-top: auto; padding-top: 1.25rem; }
.trip-info-btn { cursor: zoom-in; }

.trip-test-note {
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .1em; font-size: var(--step--1); color: var(--accent-text);
  border-left: var(--rule) solid var(--accent-text); padding-left: .75rem;
  margin: 0 0 1rem;
}

.trip-empty { font-size: var(--step-1); font-family: var(--font-cond); font-weight: 700; }

/* --- Filter bar --- */
.trip-filters { display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: clamp(1.5rem, 3vw, 2rem); }
.trip-filter {
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; font-size: var(--step--1);
  border: 2px solid var(--forest); background: none; color: var(--forest);
  padding: .35rem 1.1rem; border-radius: var(--radius-pill); cursor: pointer;
}
.trip-filter:hover { background: var(--sand-deep); }
.trip-filter[aria-pressed="true"] { background: var(--forest); color: var(--sand); }
.trip-filter:focus-visible { outline: 3px solid var(--accent-text); outline-offset: 2px; }

/* --- Lightbox --- */
.lightbox {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(23, 63, 53, .92);
  opacity: 0; transition: opacity .2s linear;
}
/* The rule above sets display on a class, which outranks the browser's own
   [hidden] { display: none } — so the element stayed laid out while the script
   believed it was hidden, and an invisible full-screen box sat over the page
   swallowing every click. Restore it explicitly. Anything that hides itself
   with the hidden property needs this whenever its own CSS sets display. */
.lightbox[hidden] { display: none; }

.lightbox.is-open { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .lightbox { transition: none; } }

.lightbox__img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  border: var(--rule) solid var(--sand); border-radius: var(--radius-sm);
  background: var(--sand);
}
.lightbox__close {
  position: absolute; top: clamp(.75rem, 2vw, 1.5rem); right: clamp(.75rem, 2vw, 1.5rem);
  width: 48px; height: 48px; font-size: 2rem; line-height: 1;
  background: var(--sand); color: var(--forest);
  border: var(--rule) solid var(--forest); border-radius: var(--radius-sm);
  cursor: pointer;
}
.lightbox__close:focus-visible { outline: 3px solid var(--accent-text); outline-offset: 3px; }

/* Stop the page behind the lightbox scrolling under it. */
body.lightbox-open { overflow: hidden; }

/* --- 22. Social links ----------------------------------------------------
   Carried over from the previous site's contact page. Built as buttons in the
   house style rather than bare icons: each one names its network in text, so
   the link is not carried by a glyph alone and reads the same to a screen
   reader as it does on screen. The icons are marked decorative for that
   reason. */

.social__heading { font-size: var(--step-1); margin-top: 2.5rem; }

.social {
  list-style: none; margin: 1.25rem 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .75rem;
}

.social__link {
  display: inline-flex; align-items: center; gap: .6rem;
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; font-size: var(--step--1); text-decoration: none;
  color: var(--forest); background: var(--sand);
  border: var(--rule) solid var(--forest); border-radius: var(--radius-sm);
  padding: .6rem 1.1rem;
  transition: transform .12s linear, box-shadow .12s linear;
}
.social__link:hover, .social__link:focus-visible {
  transform: translate(-3px, -3px);
  box-shadow: 6px 6px 0 var(--terracotta);
}
@media (prefers-reduced-motion: reduce) { .social__link { transition: none; } }

.social__icon { flex: none; }

/* Narrow screens: the three fill the row rather than leaving a ragged edge. */
@media (max-width: 480px) {
  .social { gap: .6rem; }
  .social__link { flex: 1 1 auto; justify-content: center; padding-inline: .75rem; }
}

/* --- 25. The CMS-built trail page ----------------------------------------
   This page's copy is typed by staff, so it can contain a long unbreakable
   run — a pasted URL, a hashtag, a product code — that no line break will
   split. overflow-wrap: anywhere rather than break-word, because only
   "anywhere" also reduces the element's min-content width, and it is that
   width which would otherwise force the page wider than a narrow screen. */
#trail-root { overflow-wrap: anywhere; }

/* --- Stepping between pictures in the viewer --- */
.lightbox__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 52px; height: 52px; font-size: 2rem; line-height: 1;
  background: var(--sand); color: var(--forest);
  border: var(--rule) solid var(--forest); border-radius: var(--radius-sm);
  cursor: pointer; z-index: 1;
}
.lightbox__nav--prev { left: clamp(.5rem, 2vw, 1.5rem); }
.lightbox__nav--next { right: clamp(.5rem, 2vw, 1.5rem); }
.lightbox__nav:focus-visible { outline: 3px solid var(--accent-text); outline-offset: 3px; }
/* Same trap as the overlay itself: a class sets display, which outranks the
   browser's [hidden] rule, so hiding one needs saying explicitly. */
.lightbox__nav[hidden] { display: none; }

.lightbox__count {
  position: absolute; bottom: clamp(.5rem, 2vw, 1.25rem); left: 50%;
  transform: translateX(-50%); margin: 0;
  font-family: var(--font-cond); font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; font-size: var(--step--1); color: var(--sand);
}
.lightbox__count[hidden] { display: none; }

/* The arrows sit over the picture on a narrow screen, so keep it clear of them. */
@media (max-width: 560px) { .lightbox__img { max-width: calc(100% - 7rem); } }
