/* ==========================================================================
   Zacs Valley Resort and Wellness Retreat
   Shared landing page system. Built to Brand Guidelines v1.0 (2026).

   Palette, typography and spacing are fixed here. Each landing page adds its
   own section layouts in assets/css/lpN.css and never overrides a token.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Colour. Brand Guidelines p.14. Nothing outside this palette. */
  --forest: #2b5748;          /* Deep Forest, primary */
  --sage: #618764;            /* Valley Sage, accent only, never body text */
  --moss: #9cb080;            /* Morning Moss, accent only, never body text */
  --night: #000000;
  --white: #ffffff;
  --mist: #f4f6f1;            /* the only permitted light ground, p.15 */

  /* Hairlines. Night at low opacity so rules stay inside the palette. */
  --rule: rgba(0, 0, 0, 0.14);
  --rule-strong: rgba(0, 0, 0, 0.28);
  --rule-on-dark: rgba(255, 255, 255, 0.22);
  --rule-on-dark-strong: rgba(255, 255, 255, 0.4);

  /* Type. Span (Jamie Clarke Type) is the display face, self hosted, per
     client direction of August 2026. It sets every headline, pull quote,
     rate, villa name and programme name across all eight pages.

     Note for the brand custodian: Brand Guidelines v1.0 p.17 names Bressay
     Display for headlines. Span replaces it here on client instruction and
     the guidelines document should be amended to match.

     Avenir Next remains the working face for body and interface text, per
     p.18, with Jost standing in where it is not installed. */
  --serif: "Span", Georgia, "Times New Roman", serif;
  --sans: "Avenir Next", Avenir, "Jost", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* Scale */
  --step--1: 0.8125rem;
  --step-0: 1.0625rem;
  --step-1: clamp(1.125rem, 1.05rem + 0.35vw, 1.3125rem);
  --step-2: clamp(1.375rem, 1.24rem + 0.65vw, 1.75rem);
  /* The three display steps are set in Span only, and are pitched 10% below
     the rest of the scale. Span runs 11% wider and 11% taller in the cap than
     the face this layout was first drawn against, so without this the hero
     headlines break to five lines. Steps 2 and below are shared with Avenir
     Next and are left alone. */
  --step-3: clamp(1.4375rem, 1.24rem + 1.04vw, 2.125rem);
  --step-4: clamp(1.8rem, 1.4rem + 1.9vw, 2.9rem);
  --step-5: clamp(2.125rem, 1.44rem + 3.15vw, 4rem);

  /* Space */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
  --s8: 64px;
  --s9: 96px;
  --s10: 128px;
  --s11: 160px;

  --gutter: clamp(20px, 5vw, 64px);
  --section-y: clamp(56px, 8vw, 120px);
  --measure: 62ch;

  /* Sized to the logo, not the other way round. The full lockup is carried at
     140px wide, its screen minimum (Brand Guidelines p.10), at one constant
     size from the hero to the footer. The header is as slim as that permits. */
  --header-h: 98px;
  --stickybar-h: 64px;
}

@media (min-width: 900px) {
  :root {
    --stickybar-h: 0px;
  }
}

/* --------------------------------------------------------------------------
   1b. Span

   Self hosted from the supplied files, subset to Latin plus the rupee sign,
   multiplication sign, degree sign and middle dot these pages actually set.
   22.9 KB per weight. Only the standard width is loaded: the Compressed and
   Condensed cuts in the bundle are italics of a narrower width and nothing
   here calls for either.

   LICENCE: these were supplied from a free-download distributor, whose tier
   covers personal and non profit use only. A commercial web licence from
   jamieclarketype.com, or the Adobe Fonts embed, is required before these
   pages carry paid traffic. Swapping route is a one line change here.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Span";
  src: url("../fonts/span-300.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Span";
  src: url("../fonts/span-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Span";
  src: url("../fonts/span-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   2. Reset and base
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
  margin: 0;
  background: var(--white);
  color: var(--night);
  font-family: var(--sans);
  font-size: var(--step-0);
  font-weight: 400;
  line-height: 1.68;
  font-feature-settings: "kern" 1;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  padding-bottom: var(--stickybar-h);
}

img,
svg,
video { display: block; max-width: 100%; height: auto; }

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 400;
  letter-spacing: 0.004em;   /* Bressay tracking 0 to +10, p.17 */
  margin: 0;
  text-wrap: balance;
}

h1 { font-size: var(--step-5); line-height: 1.04; }
h2 { font-size: var(--step-4); line-height: 1.1; }
h3 { font-size: var(--step-2); line-height: 1.18; }
h4 { font-size: var(--step-1); line-height: 1.25; }

p { margin: 0 0 var(--s5); max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

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

strong, b { font-weight: 500; }

table { border-collapse: collapse; width: 100%; }

button { font: inherit; color: inherit; }

::selection { background: var(--moss); color: var(--night); }

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--forest);
  color: var(--white);
  padding: var(--s3) var(--s5);
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.wrap--narrow { max-width: 860px; }
.wrap--wide { max-width: 1480px; }

.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(40px, 5vw, 72px); }
.section--mist { background: var(--mist); }
.section--forest { background: var(--forest); color: var(--white); }
.section--night { background: var(--night); color: var(--white); }

.section--forest a,
.section--night a { color: var(--white); }

.bleed { width: 100%; }

/* --------------------------------------------------------------------------
   4. Type helpers
   -------------------------------------------------------------------------- */

/* Labels: Avenir Next Medium, all capitals, tracking +200 to +320. p.18 */
.eyebrow {
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  line-height: 1.4;
  margin: 0 0 var(--s5);
  color: var(--forest);
}
.on-dark .eyebrow,
.section--forest .eyebrow,
.section--night .eyebrow { color: var(--moss); }

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  max-width: 46ch;
}

.serif-lede {
  font-family: var(--serif);
  font-size: var(--step-3);
  line-height: 1.22;
  max-width: 22ch;
}

.small { font-size: var(--step--1); line-height: 1.6; }

.muted { opacity: 0.72; }

.nums { font-variant-numeric: tabular-nums; }

.rule-top { border-top: 1px solid var(--rule); }
.section--forest .rule-top,
.section--night .rule-top { border-color: var(--rule-on-dark); }

/* Anything the client still has to supply is marked, so nothing ships
   with a placeholder nobody noticed. Hidden with ?final=1. */
/* Derived from the text colour, so the marker stays visible on a dark ground
   as well as a light one. Without this a placeholder can sit invisible on a
   dark section and ship as a live [X]. */
.tbc {
  font-style: normal;
  border-bottom: 1px dashed var(--rule-strong);
  border-bottom-color: color-mix(in srgb, currentColor 45%, transparent);
  padding-bottom: 1px;
}

/* --------------------------------------------------------------------------
   5. Buttons and links
   -------------------------------------------------------------------------- */

/* One size for every button on the site, header CTA included. Height and
   inline padding live here and are not overridden per page, so nothing can
   drift out of step again. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  /* 46px keeps a comfortable margin over the 44px tap target minimum while
     carrying far less visual weight. The label drops to 11px so it sits on
     the same scale as every other label on the pages, and the tracking eases
     from 0.22em to 0.18em so a two word CTA stops sprawling. */
  min-height: 46px;
  padding: 0 24px;
  border: 1px solid transparent;
  border-radius: 0;
  background: var(--forest);
  color: var(--white);
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.btn:hover { background: var(--night); }

.btn--ghost {
  background: transparent;
  color: var(--night);
  border-color: var(--rule-strong);
}
.btn--ghost:hover {
  background: var(--night);
  color: var(--white);
  border-color: var(--night);
}

.btn--on-dark {
  background: var(--white);
  color: var(--night);
}
.btn--on-dark:hover { background: var(--moss); color: var(--night); }

.btn--ghost-on-dark {
  background: transparent;
  color: var(--white);
  border-color: var(--rule-on-dark-strong);
}
.btn--ghost-on-dark:hover { background: var(--white); color: var(--night); }

.btn--block { width: 100%; }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  align-items: center;
}

/* Understated text link with a rule that grows on hover. */
.tlink {
  position: relative;
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--rule-strong);
  transition: border-color 0.25s ease;
}
.tlink:hover { border-color: currentColor; }

/* Widens the tap area to 44px without moving the underline. */
.tlink::after {
  content: "";
  position: absolute;
  inset: -9px 0 -8px;
}

.section--forest .tlink,
.section--night .tlink { border-bottom-color: var(--rule-on-dark-strong); }

/* --------------------------------------------------------------------------
   6. Header
   -------------------------------------------------------------------------- */

/* Paid traffic only: logo, phone, one CTA. No global navigation, and no
   property investment link on any of these pages.

   One header carries the mark for the whole page. The lockup is fixed artwork
   and never changes size, colourway or position between the hero and the
   sections below it. Only the ground behind it changes. */
.site-header {
  position: relative;
  z-index: 60;
  background: var(--white);
  border-bottom: 1px solid var(--rule);
}

.site-header--over {
  position: absolute;
  inset: 0 0 auto;
  background: transparent;
  border-bottom-color: rgba(255, 255, 255, 0.2);
}

@media (min-width: 900px) {
  /* In flow, so no compensating offset is needed. */
  .site-header {
    position: sticky;
    top: 0;
    transition: box-shadow 0.3s ease, background 0.3s ease, border-color 0.3s ease;
  }

  /* Already overlaying the hero, so it can be pinned without shifting layout. */
  .site-header--over {
    position: fixed;
    transition: background 0.3s ease, border-color 0.3s ease;
  }

  /* Without scripting the header cannot know where the hero ends, so it keeps
     a dark ground from the start rather than risk a white mark on a white
     section. Legibility never depends on a script arriving. */
  .site-header--over {
    background: var(--forest);
    border-bottom-color: var(--rule-on-dark);
  }

  .js .site-header--over {
    background: transparent;
    border-bottom-color: rgba(255, 255, 255, 0.2);
  }

  /* Once the hero has gone, the reversed lockup gets its dark ground back so
     the identical artwork stays legible over light sections. */
  .js .site-header--over.is-stuck {
    background: var(--forest);
    border-bottom-color: var(--rule-on-dark);
  }

  .site-header:not(.site-header--over).is-stuck {
    box-shadow: 0 1px 0 var(--rule);
  }
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s5);
  min-height: var(--header-h);
  padding-block: var(--s2);
}

/* 140px is the minimum permitted screen width for the full lockup, and it is
   also the size used, everywhere, in both scroll states. The mark never
   scales, swaps or recomposes. */
.site-header__logo img { width: 140px; height: auto; }

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--s5);
}

.site-header__phone {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;          /* tap target */
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  white-space: nowrap;
}
.site-header__phone:not(.btn):hover { text-decoration: underline; text-underline-offset: 4px; }

.site-header--over .site-header__phone { color: var(--white); }

/* Icon only: a square that matches the CTA's height exactly, so the pair reads
   as one control group rather than a button and a smaller thing beside it. The
   number lives in the accessible name, and still in full in the enquiry form,
   the footer and the schema. */
.site-header__phone.btn {
  /* The plain link's 44px tap floor is declared later than .btn and would
     otherwise leave the two buttons two pixels out of line with each other. */
  width: 46px;
  min-height: 46px;
  padding: 0;
  gap: 0;
}
.site-header__phone-icon {
  flex: none;
  width: 17px;
  height: 17px;
  fill: currentColor;
}

/* Over a hero the hairline has to come off the dark side of the palette or the
   button loses its edge against the photograph. */
.site-header--over .site-header__phone.btn { border-color: var(--rule-on-dark-strong); }
.site-header--over .site-header__phone.btn:hover {
  background: var(--white);
  color: var(--night);
  border-color: var(--white);
}

.site-header__cta { display: none; }

@media (min-width: 900px) {
  .site-header__cta { display: inline-flex; }
}

/* Pages still carrying the number as text need it to shrink on a small screen.
   The icon button has no text to shrink, so it is excluded. */
@media (max-width: 420px) {
  .site-header__phone:not(.btn) { font-size: 0.8125rem; }
  .site-header__actions { gap: var(--s3); }
}

/* The slim scroll bar that used to appear here has been removed. It set the
   property name as live serif text, which is a retyped wordmark and a listed
   misuse (Brand Guidelines p.12), and it replaced the lockup with something
   different halfway down the page. The sticky header above does its job with
   the real artwork instead. */

/* --------------------------------------------------------------------------
   7. Sticky mobile action bar. Three actions, nothing else.
   -------------------------------------------------------------------------- */

.stickybar {
  position: fixed;
  inset: auto 0 0;
  z-index: 80;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background: var(--forest);
  border-top: 1px solid var(--rule-on-dark);
}

.stickybar a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: var(--stickybar-h);
  padding: var(--s2) var(--s1);
  color: var(--white);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
}

.stickybar a + a { border-left: 1px solid var(--rule-on-dark); }
.stickybar a:active { background: var(--night); }
.stickybar svg { width: 18px; height: 18px; }

@media (min-width: 900px) {
  .stickybar { display: none; }
}

/* --------------------------------------------------------------------------
   8. Hero shared parts
   -------------------------------------------------------------------------- */

.hero { position: relative; }

.hero__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Legibility scrim over photography. Neutral black, no palette tint. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.28) 45%, rgba(0, 0, 0, 0.62) 100%);
}

.hero__body { position: relative; z-index: 2; }

.rate-line {
  font-family: var(--serif);
  font-size: var(--step-2);
  line-height: 1.3;
  margin: 0;
}

.micro {
  font-size: 0.8125rem;
  line-height: 1.55;
  opacity: 0.85;
  margin: 0;
  max-width: 46ch;
}

/* Trust strip: dot separated, wraps cleanly on small screens. */
.trust {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s4);
  font-size: 0.8125rem;
  letter-spacing: 0.03em;
  margin: 0;
}
.trust li { display: flex; align-items: center; gap: var(--s4); }
.trust li + li::before {
  content: "";
  width: 3px;
  height: 3px;
  background: currentColor;
  opacity: 0.5;
  border-radius: 50%;
  margin-left: calc(var(--s4) * -1 + 0px);
}
.trust li + li { padding-left: 0; }

/* At a glance strip. Six facts, no prose. */
.glance {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4) var(--s7);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.glance li { display: flex; align-items: center; gap: var(--s7); }
.glance li + li::before {
  content: "";
  width: 1px;
  height: 14px;
  background: var(--rule-strong);
  margin-left: calc(var(--s7) * -1);
}
.section--forest .glance li + li::before,
.section--night .glance li + li::before { background: var(--rule-on-dark-strong); }

/* --------------------------------------------------------------------------
   9. Photography placeholders
   Swap each .shot for <img> once real property photography lands.
   -------------------------------------------------------------------------- */

.shot {
  position: relative;
  display: block;
  margin: 0;
  aspect-ratio: var(--ar, 3 / 2);
  background: var(--mist);
  border: 1px solid var(--rule);
  overflow: hidden;
}

.shot::before {
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px solid var(--rule);
}

.shot::after {
  content: attr(data-shot);
  position: absolute;
  inset: auto 0 0;
  padding: var(--s5) var(--s5) var(--s5);
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--forest);
}

.shot--dark {
  background: var(--forest);
  border-color: var(--rule-on-dark);
}
.shot--dark::before { border-color: var(--rule-on-dark); }
.shot--dark::after { color: var(--moss); }

.shot--fill { height: 100%; aspect-ratio: auto; }

/* --------------------------------------------------------------------------
   10. Tables. Used heavily. Rates, specifications, drive times.
   -------------------------------------------------------------------------- */

.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.tbl {
  font-size: 0.9375rem;
  min-width: 520px;
}

.tbl caption {
  text-align: left;
  font-size: 0.8125rem;
  padding-bottom: var(--s4);
  opacity: 0.7;
}

.tbl th,
.tbl td {
  text-align: left;
  padding: var(--s4) var(--s5) var(--s4) 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
}

.tbl thead th {
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  border-bottom-color: var(--rule-strong);
  padding-bottom: var(--s3);
}

.tbl tbody th { font-weight: 500; }

.tbl td:last-child,
.tbl th:last-child { padding-right: 0; }

.tbl .num {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.section--forest .tbl th,
.section--forest .tbl td,
.section--night .tbl th,
.section--night .tbl td { border-bottom-color: var(--rule-on-dark); }
.section--forest .tbl thead th,
.section--night .tbl thead th { border-bottom-color: var(--rule-on-dark-strong); }

/* Two column specification sheet. */
.spec {
  border-top: 1px solid var(--rule-strong);
  font-size: 0.9375rem;
}
/* Label above value on narrow screens. Two columns once there is room for
   both without forcing the panel wider than its container. */
.spec div {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s2);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--rule);
}

@media (min-width: 560px) {
  .spec div {
    grid-template-columns: minmax(140px, 0.7fr) 1.3fr;
    gap: var(--s4) var(--s5);
  }
}
.spec dt {
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding-top: 3px;
  opacity: 0.8;
}
.spec dd { margin: 0; }

.section--forest .spec,
.section--night .spec { border-top-color: var(--rule-on-dark-strong); }
.section--forest .spec div,
.section--night .spec div { border-bottom-color: var(--rule-on-dark); }

/* --------------------------------------------------------------------------
   11. Reviews
   -------------------------------------------------------------------------- */

.quote {
  margin: 0;
  padding-top: var(--s5);
  border-top: 1px solid var(--rule-strong);
}
.quote p {
  font-family: var(--serif);
  font-size: var(--step-1);
  line-height: 1.42;
  margin: 0 0 var(--s4);
  max-width: none;
}
.quote figcaption {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.section--forest .quote,
.section--night .quote { border-top-color: var(--rule-on-dark-strong); }

/* --------------------------------------------------------------------------
   12. FAQ
   -------------------------------------------------------------------------- */

.faq { border-top: 1px solid var(--rule-strong); }

.faq details {
  border-bottom: 1px solid var(--rule);
}

.faq summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s5);
  padding: var(--s5) 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--serif);
  font-size: var(--step-1);
  line-height: 1.35;
}
.faq summary::-webkit-details-marker { display: none; }

.faq summary::after {
  content: "";
  flex: none;
  width: 13px;
  height: 13px;
  margin-top: 8px;
  background:
    linear-gradient(currentColor, currentColor) center/100% 1px no-repeat,
    linear-gradient(currentColor, currentColor) center/1px 100% no-repeat;
  transition: transform 0.25s ease;
}
.faq details[open] summary::after { transform: rotate(45deg); }
/* Closing holds the details open until the glide finishes, so the marker is
   turned back by hand instead of waiting for the attribute to drop. */
.faq details.is-closing summary::after { transform: none; }

.faq .faq__a {
  padding: 0 0 var(--s6);
  max-width: var(--measure);
}
.faq .faq__a p { margin-bottom: var(--s4); }

.section--forest .faq,
.section--night .faq { border-top-color: var(--rule-on-dark-strong); }
.section--forest .faq details,
.section--night .faq details { border-bottom-color: var(--rule-on-dark); }

/* --------------------------------------------------------------------------
   13. Forms. Four fields. Five on the corporate page.
   -------------------------------------------------------------------------- */

.form { display: grid; gap: var(--s5); }

.form__grid {
  display: grid;
  gap: var(--s5);
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .form__grid--2 { grid-template-columns: 1fr 1fr; }
}

.field { display: grid; gap: var(--s2); }

.field label {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.85;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 52px;
  padding: var(--s3) 0;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 1rem;
  transition: border-color 0.2s ease;
}
.field textarea { min-height: 92px; padding-top: var(--s3); resize: vertical; }

.field select {
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 8px center, right 2px center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: var(--s6);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--forest);
  border-bottom-width: 2px;
  padding-bottom: calc(var(--s3) - 1px);
}

.field input::placeholder,
.field textarea::placeholder { color: currentColor; opacity: 0.42; }

.section--forest .field input,
.section--forest .field select,
.section--forest .field textarea,
.section--night .field input,
.section--night .field select,
.section--night .field textarea { border-bottom-color: var(--rule-on-dark-strong); }

.section--forest .field input:focus,
.section--forest .field select:focus,
.section--forest .field textarea:focus,
.section--night .field input:focus,
.section--night .field select:focus,
.section--night .field textarea:focus { border-bottom-color: var(--white); }

/* Honeypot. Off screen, never announced. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.field__error {
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  color: var(--night);
  font-weight: 500;
}
.section--forest .field__error,
.section--night .field__error { color: var(--moss); }

.field.is-invalid input,
.field.is-invalid select { border-bottom-color: currentColor; border-bottom-width: 2px; }

.form__note { font-size: 0.8125rem; line-height: 1.55; opacity: 0.8; margin: 0; }

.form__done {
  border: 1px solid var(--rule-strong);
  padding: var(--s6);
}
.form__done h3 { margin-bottom: var(--s3); }
.section--forest .form__done,
.section--night .form__done { border-color: var(--rule-on-dark-strong); }

[hidden] { display: none !important; }

/* --------------------------------------------------------------------------
   14. Map
   -------------------------------------------------------------------------- */

.map {
  border: 1px solid var(--rule);
  aspect-ratio: 16 / 9;
  width: 100%;
}
.map iframe { width: 100%; height: 100%; border: 0; display: block; }

/* --------------------------------------------------------------------------
   15. Footer
   -------------------------------------------------------------------------- */

.site-footer {
  background: var(--night);
  color: var(--white);
  padding-block: var(--s8) var(--s7);
  font-size: 0.875rem;
}

.site-footer__top {
  display: grid;
  gap: var(--s7);
  padding-bottom: var(--s7);
  border-bottom: 1px solid var(--rule-on-dark);
}

@media (min-width: 860px) {
  .site-footer__top { grid-template-columns: 260px 1fr; gap: var(--s9); align-items: start; }
}

.site-footer__logo img { width: 150px; }

.site-footer__trust { line-height: 1.8; margin: 0; max-width: 60ch; }
.site-footer__trust a { text-decoration: none; }
.site-footer__trust a:hover { text-decoration: underline; text-underline-offset: 3px; }

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4) var(--s6);
  align-items: center;
  justify-content: space-between;
  padding-top: var(--s5);
  font-size: 0.8125rem;
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4) var(--s6);
}
.site-footer__links a { text-decoration: none; opacity: 0.85; }
.site-footer__links a:hover { opacity: 1; text-decoration: underline; text-underline-offset: 3px; }

.site-footer__legal { opacity: 0.6; margin: 0; }

/* --------------------------------------------------------------------------
   16. Motion. Quiet, and off entirely when the visitor asks for that.
   -------------------------------------------------------------------------- */

/* Reveal is additive, never subtractive. A .reveal block is fully visible at
   rest; script only adds a short rise as it comes into view. Nothing on a
   paid landing page is ever held at zero opacity waiting for JavaScript, so
   a blocked, failed or slow script cannot leave a section blank. */
.reveal { opacity: 1; transform: none; }

.js .reveal.is-in { animation: zv-rise 0.7s ease both; }

@keyframes zv-rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal.is-in,
  .reveal { opacity: 1; transform: none; transition: none; animation: none; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* --------------------------------------------------------------------------
   17. Grid helpers used across pages
   -------------------------------------------------------------------------- */

.grid { display: grid; gap: var(--s6); }
.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }
.grid--4 { grid-template-columns: 1fr 1fr; }

@media (min-width: 720px) {
  .grid--2 { grid-template-columns: 1fr 1fr; }
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1000px) {
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
}

.stack { display: grid; gap: var(--s5); justify-items: start; }
.stack--center { justify-items: center; text-align: center; }

/* Section heading block: eyebrow, heading, optional standfirst. */
.head { max-width: 44ch; margin-bottom: var(--s8); }
.head p { margin-top: var(--s5); margin-bottom: 0; }
.head--center { margin-inline: auto; text-align: center; }
.head--center p { margin-inline: auto; }
.head--wide { max-width: 60ch; }
