/* ==========================================================================
   James Santiago Landscape Architect · Sample Website
   Built by GoldsWebsite.com
   --------------------------------------------------------------------------
   Design system: "bright modern luxury":
     Surfaces  white + cool mist, generous negative space, hairline rules
     Anchor    deep forest green, used sparingly for weight
     Accent    crisp green / mint. No gold, no tan, no warm neutrals.
     Type      Instrument Serif (display) + Inter (UI & body)
     Geometry  2px radii, squared forms, architectural rather than soft
     Motif     survey contour lines + drafting grid + crop marks, all at
               very low opacity, so the page reads like a drawing sheet
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Surfaces */
  --paper:       #FFFFFF;
  --mist:        #F4F8F5;
  --stone:       #E9F0EB;

  /* Anchor greens */
  --forest:      #0F2E24;
  --forest-deep: #08201A;
  --forest-soft: #17493A;

  /* Accent */
  --accent:      #1C7A53;
  --accent-deep: #145F40;
  --accent-soft: #6FD3A4;

  /* Text */
  --ink:           #0B1510;
  --ink-soft:      #3B4842;
  --ink-muted:     #69756F;
  --on-dark:       #F2F7F4;
  --on-dark-muted: rgba(242, 247, 244, 0.66);

  /* Lines */
  --line:        rgba(11, 21, 16, 0.10);
  --line-strong: rgba(11, 21, 16, 0.19);
  --line-dark:   rgba(242, 247, 244, 0.16);

  /* Type */
  --font-display: "Instrument Serif", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  /* Rhythm */
  --wrap:      1280px;
  --wrap-slim: 880px;
  --gutter:    clamp(1.15rem, 4vw, 3.25rem);
  --section-y: clamp(3.75rem, 9.5vw, 9rem);
  --header-h:  86px;

  /* Motion */
  --ease: cubic-bezier(0.22, 0.72, 0.24, 1);

  /* Elevation: cool, low, never heavy */
  --shadow-sm: 0 1px 3px rgba(11, 21, 16, 0.04);
  --shadow-md: 0 18px 44px -26px rgba(11, 21, 16, 0.30);
  --shadow-lg: 0 40px 90px -46px rgba(11, 21, 16, 0.38);

  --radius: 2px;

  /* Texture: survey contours. Decorative only, always behind content. */
  --contour-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 800'%3E%3Cg fill='none' stroke='%230F2E24' stroke-width='1.1'%3E%3Cellipse cx='400' cy='400' rx='46' ry='30' transform='rotate(-16 400 400)'/%3E%3Cellipse cx='396' cy='402' rx='96' ry='66' transform='rotate(-14 400 400)'/%3E%3Cellipse cx='392' cy='405' rx='150' ry='104' transform='rotate(-12 400 400)'/%3E%3Cellipse cx='388' cy='408' rx='206' ry='144' transform='rotate(-10 400 400)'/%3E%3Cellipse cx='384' cy='411' rx='264' ry='186' transform='rotate(-8 400 400)'/%3E%3Cellipse cx='380' cy='414' rx='324' ry='230' transform='rotate(-6 400 400)'/%3E%3Cellipse cx='376' cy='417' rx='386' ry='276' transform='rotate(-4 400 400)'/%3E%3C/g%3E%3C/svg%3E");
  --contour-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 800'%3E%3Cg fill='none' stroke='%236FD3A4' stroke-width='1.1'%3E%3Cellipse cx='400' cy='400' rx='46' ry='30' transform='rotate(-16 400 400)'/%3E%3Cellipse cx='396' cy='402' rx='96' ry='66' transform='rotate(-14 400 400)'/%3E%3Cellipse cx='392' cy='405' rx='150' ry='104' transform='rotate(-12 400 400)'/%3E%3Cellipse cx='388' cy='408' rx='206' ry='144' transform='rotate(-10 400 400)'/%3E%3Cellipse cx='384' cy='411' rx='264' ry='186' transform='rotate(-8 400 400)'/%3E%3Cellipse cx='380' cy='414' rx='324' ry='230' transform='rotate(-6 400 400)'/%3E%3Cellipse cx='376' cy='417' rx='386' ry='276' transform='rotate(-4 400 400)'/%3E%3C/g%3E%3C/svg%3E");

  /* Texture: drafting grid. Seamless, so it can tile safely. */
  --grid-fine:
    repeating-linear-gradient(0deg,  rgba(11, 21, 16, 0.030) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, rgba(11, 21, 16, 0.030) 0 1px, transparent 1px 34px);
}

/* --------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: clamp(88px, 14vw, 128px);
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.72;
  color: var(--ink-soft);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: rgba(28, 122, 83, 0.14);
  overflow-x: hidden;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  color: var(--ink);
  line-height: 1.04;
  letter-spacing: -0.012em;
  margin: 0 0 0.55em;
  text-wrap: balance;
}

/* Display sizes scale all the way down: at 360px the h1 lands near 40px,
   which fits two words per line instead of breaking mid-word. */
h1 { font-size: clamp(2.55rem, 8.6vw, 5.9rem); }
h2 { font-size: clamp(2rem, 5.4vw, 3.9rem); }
h3 { font-size: clamp(1.4rem, 2.2vw, 1.9rem); line-height: 1.14; }
h4 { font-size: 1.2rem; line-height: 1.2; }

p { margin: 0 0 1.15em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); text-decoration: none; transition: color 0.25s var(--ease); }
a:hover { color: var(--forest); }

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

::selection { background: var(--accent); color: #fff; }

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

/* Reading progress: a hairline that fills as the page scrolls. */
.progress-bar {
  position: fixed;
  inset: 0 auto auto 0;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  background: linear-gradient(90deg, var(--accent), var(--accent-soft));
  z-index: 80;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   3. Layout helpers
   -------------------------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }
.wrap--slim { max-width: var(--wrap-slim); }
.section { padding-block: var(--section-y); position: relative; }
.section--tight { padding-block: clamp(2.75rem, 6vw, 5.5rem); }
.section--mist { background: var(--mist); }
.section--paper { background: var(--paper); }
.section--dark { background: var(--forest); color: var(--on-dark-muted); }
.section--dark h1, .section--dark h2, .section--dark h3, .section--dark h4 { color: var(--on-dark); }
.section--dark a { color: var(--accent-soft); }

/* Mist sections carry a faint drafting grid that fades out downward, so the
   alternating band reads as paper stock rather than a flat grey. */
.section--mist { overflow: hidden; }
.section--mist::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--grid-fine);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.35) 46%, transparent 88%);
          mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.35) 46%, transparent 88%);
  pointer-events: none;
}
.section--mist > * { position: relative; z-index: 1; }

/* A hairline seam between two consecutive light sections keeps the rhythm
   readable without adding another border colour. */
.section + .section:not(.section--mist):not(.cta-band)::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--gutter);
  right: var(--gutter);
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), var(--line) 32%, transparent 72%);
}

.center { text-align: center; }
/* Centre the block itself whether .center sits on the head or on a parent */
.center .section-head,
.section-head.center { margin-inline: auto; }

/* Eyebrow */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.69rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1.5rem;
}
.eyebrow::before {
  content: "";
  width: 26px; height: 1px;
  background: currentColor;
  opacity: 0.55;
}
.eyebrow--center::after {
  content: "";
  width: 26px; height: 1px;
  background: currentColor;
  opacity: 0.55;
}
.center .eyebrow { justify-content: center; }
.section--dark .eyebrow { color: var(--accent-soft); }
@media (max-width: 420px) { .eyebrow { font-size: 0.64rem; letter-spacing: 0.2em; gap: 0.55rem; } }

.section-head { max-width: 60ch; margin-bottom: clamp(2.25rem, 5vw, 4.25rem); }
.section-head p.lead { font-size: clamp(1.02rem, 1.5vw, 1.22rem); color: var(--ink-muted); }
.section--dark .section-head p.lead { color: var(--on-dark-muted); }

.lead { font-size: clamp(1.05rem, 1.7vw, 1.32rem); line-height: 1.6; color: var(--ink-soft); }

.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* --------------------------------------------------------------------------
   4. Buttons: squared, architectural
   -------------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--forest);
  --btn-fg: var(--paper);
  --btn-bd: var(--forest);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.65rem;
  padding: 1.08rem 2.25rem;
  min-height: 48px;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 1px solid var(--btn-bd);
  border-radius: var(--radius);
  cursor: pointer;
  overflow: hidden;
  transition: transform 0.35s var(--ease), background 0.35s var(--ease),
              color 0.35s var(--ease), border-color 0.35s var(--ease), box-shadow 0.35s var(--ease);
  white-space: nowrap;
}
/* A soft sheen that sweeps once on hover. Subtle enough to read as material,
   not as a "shiny button". */
.btn::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 -60%;
  width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.22), transparent);
  transform: skewX(-18deg);
  transition: transform 0.75s var(--ease);
  pointer-events: none;
}
.btn:hover::after { transform: skewX(-18deg) translateX(340%); }
.btn:hover {
  --btn-bg: var(--accent);
  --btn-bd: var(--accent);
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 14px 30px -16px rgba(28, 122, 83, 0.7);
}
.btn svg { width: 15px; height: 15px; position: relative; z-index: 1; }
.btn > * { position: relative; z-index: 1; }

.btn--ghost { --btn-bg: transparent; --btn-fg: var(--forest); --btn-bd: var(--line-strong); }
.btn--ghost:hover { --btn-fg: #fff; }
/* Solid mid-green. Used where a secondary button still needs to carry weight
   on a light ground, instead of reading as an empty outline. */
.btn--accent { --btn-bg: var(--accent); --btn-fg: #fff; --btn-bd: var(--accent); }
.btn--accent:hover { --btn-bg: var(--forest); --btn-bd: var(--forest); color: #fff; box-shadow: 0 14px 30px -16px rgba(15, 46, 36, 0.7); }
.btn--light  { --btn-bg: var(--paper); --btn-fg: var(--forest); --btn-bd: var(--paper); }
.btn--light:hover { --btn-bg: var(--accent-soft); --btn-bd: var(--accent-soft); --btn-fg: var(--forest-deep); color: var(--forest-deep); }
.btn--light::after { background: linear-gradient(100deg, transparent, rgba(15, 46, 36, 0.10), transparent); }
.btn--outline-light { --btn-bg: transparent; --btn-fg: var(--on-dark); --btn-bd: rgba(242,247,244,0.34); }
.btn--outline-light:hover { --btn-bg: var(--accent-soft); --btn-bd: var(--accent-soft); --btn-fg: var(--forest-deep); color: var(--forest-deep); box-shadow: none; }
.btn--sm { padding: 0.82rem 1.55rem; min-height: 42px; font-size: 0.67rem; }
.btn--block { width: 100%; }

/* On narrow screens a long label must wrap instead of forcing the page wider. */
@media (max-width: 560px) {
  .btn { white-space: normal; text-align: center; line-height: 1.45; padding: 1rem 1.4rem; font-size: 0.69rem; letter-spacing: 0.14em; }
}

/* Text link with arrow */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  padding-block: 0.35rem;
}
.link-arrow svg { width: 16px; height: 16px; transition: transform 0.3s var(--ease); }
.link-arrow:hover { color: var(--forest); }
.link-arrow:hover svg { transform: translateX(5px); }
.section--dark .link-arrow { color: var(--accent-soft); }

/* --------------------------------------------------------------------------
   5. Header / navigation
   -------------------------------------------------------------------------- */
.topbar {
  background: var(--forest);
  color: var(--on-dark-muted);
  font-size: 0.74rem;
  letter-spacing: 0.05em;
  position: relative;
  z-index: 60;
}
.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 42px;
  padding-block: 0.45rem;
}
.topbar a { color: var(--on-dark-muted); }
.topbar a:hover { color: var(--accent-soft); }
.topbar__contact { display: flex; gap: 1.7rem; flex-wrap: wrap; }
.topbar__contact a { display: inline-flex; align-items: center; gap: 0.45rem; }
.topbar__contact svg { width: 13px; height: 13px; opacity: 0.65; }
.topbar__note { display: none; }
@media (min-width: 900px) { .topbar__note { display: block; } }

/* Phones: the two links have to share one 320px line without wrapping the bar
   into two rows, so the gap tightens and the email truncates gracefully. */
@media (max-width: 560px) {
  .topbar { font-size: 0.7rem; }
  .topbar__inner { gap: 0.9rem; justify-content: center; }
  .topbar__contact { gap: 1.05rem; flex-wrap: nowrap; min-width: 0; }
  .topbar__contact a { min-width: 0; }
  .topbar__contact a:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
@media (max-width: 380px) {
  .topbar__contact a:last-child span { display: none; }
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: var(--header-h);
}
@media (max-width: 640px) { .site-header__inner { min-height: 70px; gap: 0.75rem; } }

/* Transparent header over the hero (home page).
   At rest it sits absolutely, directly beneath the top bar, floating over the
   image. Once scrolled it becomes a solid fixed bar pinned to the viewport.
   --topbar-h is measured and set by script.js. */
body.has-overlay-header .site-header {
  position: absolute;
  top: var(--topbar-h, 42px);
  left: 0; right: 0;
  background: transparent;
  border-bottom-color: transparent;
}
/* Must out-specify the transparent rule above, or the solid bar never appears. */
body.has-overlay-header .site-header.is-stuck {
  position: fixed;
  top: 0;
  background: rgba(255, 255, 255, 0.90);
  border-bottom-color: var(--line);
}
body.has-overlay-header .site-header:not(.is-stuck) .brand__name,
body.has-overlay-header .site-header:not(.is-stuck) .nav__link,
body.has-overlay-header .site-header:not(.is-stuck) .nav-toggle { color: var(--on-dark); }
body.has-overlay-header .site-header:not(.is-stuck) .brand__mark { border-color: rgba(242,247,244,0.42); color: var(--on-dark); }
body.has-overlay-header .site-header:not(.is-stuck) .brand__tag { color: var(--on-dark-muted); }
body.has-overlay-header .site-header:not(.is-stuck) .btn--nav { --btn-bg: transparent; --btn-fg: var(--on-dark); --btn-bd: rgba(242,247,244,0.42); }

.site-header.is-stuck {
  background: rgba(255, 255, 255, 0.90);
  backdrop-filter: saturate(160%) blur(16px);
  -webkit-backdrop-filter: saturate(160%) blur(16px);
  border-bottom-color: var(--line);
  box-shadow: 0 10px 34px -28px rgba(11, 21, 16, 0.55);
}

/* While the mobile drawer is open the header sits on top of the dark panel,
   so it drops its own surface and switches to light type. */
body.nav-open .site-header,
body.nav-open .site-header.is-stuck {
  background: transparent;
  border-bottom-color: transparent;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.nav-open .brand__name,
body.nav-open .nav-toggle { color: var(--on-dark); }
body.nav-open .brand__tag { color: var(--on-dark-muted); }
body.nav-open .brand__mark { border-color: var(--line-dark); color: var(--accent-soft); }

/* Brand */
.brand { display: flex; align-items: center; gap: 0.9rem; min-width: 0; }
.brand__mark {
  width: 42px; height: 42px;
  flex: 0 0 42px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  display: grid;
  place-items: center;
  color: var(--accent);
  transition: border-color 0.4s var(--ease), color 0.4s var(--ease), background 0.4s var(--ease);
}
.brand:hover .brand__mark { background: var(--accent); color: #fff; border-color: var(--accent); }
.brand__mark svg { width: 21px; height: 21px; }
.brand__text { display: flex; flex-direction: column; line-height: 1.12; min-width: 0; }
.brand__name {
  font-family: var(--font-display);
  font-size: 1.35rem;
  letter-spacing: -0.005em;
  color: var(--ink);
  white-space: nowrap;
  transition: color 0.4s var(--ease);
}
.brand__tag {
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-muted);
  white-space: nowrap;
  transition: color 0.4s var(--ease);
}
@media (max-width: 400px) {
  .brand { gap: 0.65rem; }
  .brand__mark { width: 36px; height: 36px; flex-basis: 36px; }
  .brand__mark svg { width: 18px; height: 18px; }
  .brand__name { font-size: 1.15rem; }
  .brand__tag { font-size: 0.52rem; letter-spacing: 0.17em; }
}

/* Nav */
.nav { display: none; align-items: center; gap: 2.3rem; }
@media (min-width: 1000px) { .nav { display: flex; } }

.nav__link {
  position: relative;
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-block: 0.4rem;
  transition: color 0.3s var(--ease);
}
.nav__link::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.35s var(--ease);
}
.nav__link:hover { color: var(--accent); }
.nav__link:hover::after,
.nav__link[aria-current="page"]::after { transform: scaleX(1); transform-origin: left; }
.nav__link[aria-current="page"] { color: var(--accent); }

.header__actions { display: flex; align-items: center; gap: 0.9rem; }
.btn--nav { display: none; }
@media (min-width: 1000px) { .btn--nav { display: inline-flex; } }

/* Mobile toggle */
.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 46px; height: 46px;
  margin-right: -0.4rem;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--ink);
}
@media (min-width: 1000px) { .nav-toggle { display: none; } }
.nav-toggle span {
  display: block;
  width: 22px; height: 1.5px;
  margin-inline: auto;
  background: currentColor;
  transition: transform 0.35s var(--ease), opacity 0.25s var(--ease);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* Mobile drawer */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 45;
  background: var(--forest);
  color: var(--on-dark);
  padding: calc(var(--topbar-h, 42px) + 5.5rem) var(--gutter) max(2.5rem, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-12px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease), visibility 0.4s;
  /* Explicit per-axis overflow. `overflow-y: auto` alone makes the x axis
     compute to `auto` as well, so the decorative contour bleeding off the
     right edge became a horizontal scrollbar you could drag the panel around
     with. Hidden on x, auto on y, and it stays put. */
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
/* Anchored to bottom:0, not past it. An abspos decoration hanging below the
   padding box adds scrollable height, which is what let the open drawer be
   dragged up and down with nothing to show. */
.mobile-nav::before {
  content: "";
  position: absolute;
  right: -10rem;
  bottom: 0;
  width: 32rem; height: 32rem;
  background: var(--contour-dark) center / contain no-repeat;
  opacity: 0.12;
  pointer-events: none;
}
.mobile-nav.is-open { opacity: 1; visibility: visible; transform: none; }
.mobile-nav a.mobile-nav__link {
  position: relative;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 6.8vw, 2.1rem);
  color: var(--on-dark);
  padding-block: 0.7rem;
  border-bottom: 1px solid var(--line-dark);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease), color 0.25s var(--ease);
}
.mobile-nav.is-open a.mobile-nav__link { opacity: 1; transform: none; }
.mobile-nav.is-open a.mobile-nav__link:nth-child(1) { transition-delay: 0.06s; }
.mobile-nav.is-open a.mobile-nav__link:nth-child(2) { transition-delay: 0.11s; }
.mobile-nav.is-open a.mobile-nav__link:nth-child(3) { transition-delay: 0.16s; }
.mobile-nav.is-open a.mobile-nav__link:nth-child(4) { transition-delay: 0.21s; }
.mobile-nav.is-open a.mobile-nav__link:nth-child(5) { transition-delay: 0.26s; }
.mobile-nav a.mobile-nav__link:hover { color: var(--accent-soft); }
.mobile-nav__foot {
  position: relative;
  margin-top: auto;
  padding-top: 2.25rem;
  display: grid;
  gap: 0.85rem;
  justify-items: start;
}
/* :not(.btn) matters: this rule out-specifies .btn, so without it the light
   CTA below renders muted-white-on-white and all but disappears. */
.mobile-nav__foot a:not(.btn) { color: var(--on-dark-muted); font-size: 0.95rem; }
.mobile-nav__foot .btn { width: 100%; }

/* Scroll lock. `overflow: hidden` on its own is ignored by iOS Safari, so the
   page is pinned with position:fixed and script.js restores the offset on
   close. Without this the page behind the drawer still scrolls under a drag. */
body.nav-open {
  position: fixed;
  left: 0; right: 0;
  width: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}
/* The drawer sits above both, so they would only show through its edges. */
body.nav-open .quickbar,
body.nav-open .to-top,
body.nav-open .quickbar-reopen { opacity: 0; pointer-events: none; }

/* --------------------------------------------------------------------------
   6. Imagery
   -------------------------------------------------------------------------- */
.site-image {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  background: var(--stone);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.site-image--wide     { aspect-ratio: 16 / 9; }
.site-image--ultra    { aspect-ratio: 21 / 9; }
.site-image--portrait { aspect-ratio: 4 / 5; }
.site-image--square   { aspect-ratio: 1; }
.site-image--tall     { aspect-ratio: 3 / 4; }

/* On phones the tallest crops eat the whole screen, so they relax toward
   something closer to 4:5 and the ultra-wide strip gets taller. */
@media (max-width: 700px) {
  .site-image--tall  { aspect-ratio: 4 / 5; }
  .site-image--ultra { aspect-ratio: 16 / 10; }
}

/* Crop marks: two hairline corner brackets, the way a drawing is trimmed.
   Purely decorative, and they sit inside the wrap gutter on mobile. */
.media-frame { position: relative; }
.media-frame::before,
.media-frame::after {
  content: "";
  position: absolute;
  width: clamp(16px, 3vw, 26px);
  height: clamp(16px, 3vw, 26px);
  border: 1px solid var(--accent);
  opacity: 0.5;
  pointer-events: none;
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.media-frame::before {
  top: -7px; left: -7px;
  border-right: 0; border-bottom: 0;
}
.media-frame::after {
  bottom: -7px; right: -7px;
  border-left: 0; border-top: 0;
}
@media (min-width: 940px) {
  .media-frame::before { top: -11px; left: -11px; }
  .media-frame::after  { bottom: -11px; right: -11px; }
}
.media-frame:hover::before,
.media-frame:hover::after { opacity: 0.9; transform: scale(1.12); }

/* --------------------------------------------------------------------------
   7. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: min(94svh, 920px);
  display: flex;
  align-items: flex-end;
  background: var(--forest-deep);
  color: var(--on-dark);
  overflow: hidden;
  padding-top: calc(var(--topbar-h, 42px) + 96px);
}
@supports not (height: 1svh) { .hero { min-height: min(94vh, 920px); } }
@media (max-width: 640px) {
  .hero { min-height: min(88svh, 760px); padding-top: calc(var(--topbar-h, 42px) + 78px); }
}

.hero__media { position: absolute; inset: 0; }
.hero__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  animation: heroSettle 1.8s var(--ease) both;
}
@keyframes heroSettle { from { transform: scale(1.07); } to { transform: none; } }

/* Two scrims: a vertical one for the headline block, and a soft left-hand
   wash so the type keeps contrast wherever the photo is bright. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8,32,26,0.50) 0%, rgba(8,32,26,0.16) 34%, rgba(8,32,26,0.78) 76%, rgba(8,32,26,0.93) 100%);
  pointer-events: none;
}
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(102deg, rgba(8,32,26,0.62) 0%, rgba(8,32,26,0.20) 44%, rgba(8,32,26,0) 74%);
  pointer-events: none;
}

.hero__inner { position: relative; z-index: 2; width: 100%; padding-bottom: clamp(3rem, 7vw, 5.5rem); }
.hero h1 { color: var(--on-dark); max-width: 15ch; margin-bottom: 1.35rem; }
.hero h1 em { font-style: italic; color: var(--accent-soft); }
.hero__sub { max-width: 54ch; font-size: clamp(1.02rem, 1.6vw, 1.26rem); color: var(--on-dark-muted); line-height: 1.66; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-top: 2.2rem; }
.hero .eyebrow { color: var(--accent-soft); }
@media (max-width: 520px) {
  .hero__actions { gap: 0.7rem; }
  .hero__actions .btn { flex: 1 1 100%; }
}

/* Hero footnote strip: a quiet credential line pinned to the bottom rule. */
.hero__foot {
  position: relative;
  z-index: 2;
  display: none;
  gap: 2.4rem;
  align-items: center;
  padding-block: 1.1rem;
  border-top: 1px solid rgba(242, 247, 244, 0.18);
  margin-top: 2.6rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--on-dark-muted);
}
@media (min-width: 860px) { .hero__foot { display: flex; } }
.hero__foot span { display: inline-flex; align-items: center; gap: 0.6rem; }
.hero__foot span::before { content: ""; width: 5px; height: 5px; background: var(--accent-soft); border-radius: 50%; }

/* Scroll cue */
.hero__cue {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(2.2rem, 6vw, 3.6rem);
  z-index: 3;
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--on-dark-muted);
  writing-mode: vertical-rl;
}
@media (min-width: 1100px) { .hero__cue { display: flex; } }
.hero__cue::after {
  content: "";
  width: 1px; height: 56px;
  background: linear-gradient(180deg, var(--accent-soft), transparent);
  animation: cueDrift 2.4s var(--ease) infinite;
}
@keyframes cueDrift {
  0%   { transform: scaleY(0.25); transform-origin: top; opacity: 0.3; }
  45%  { transform: scaleY(1);    transform-origin: top; opacity: 1; }
  100% { transform: scaleY(0.25); transform-origin: bottom; opacity: 0.3; }
}

/* Page hero (inner pages): light, editorial, lots of air */
.page-hero {
  position: relative;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  padding-block: clamp(2.5rem, 7.5vw, 6.5rem);
  overflow: hidden;
}
.page-hero::before {
  content: "";
  position: absolute;
  right: -10%;
  top: -55%;
  width: 44rem; height: 44rem;
  background: radial-gradient(circle, rgba(28, 122, 83, 0.09), transparent 62%);
  pointer-events: none;
}
/* Contour motif, ghosted into the right margin of every inner-page hero. */
.page-hero::after {
  content: "";
  position: absolute;
  right: -12rem;
  top: 50%;
  width: 38rem; height: 38rem;
  transform: translateY(-50%);
  background: var(--contour-light) center / contain no-repeat;
  opacity: 0.07;
  pointer-events: none;
}
/* On phones the motif would cross straight through the display type, so it
   drops below the headline and thins out. */
@media (max-width: 900px) {
  .page-hero::after {
    width: 30rem; height: 30rem;
    right: -15rem;
    top: auto; bottom: -13rem;
    transform: none;
    opacity: 0.05;
  }
}
.page-hero__inner { position: relative; z-index: 2; max-width: 70ch; }
.page-hero h1 { margin-bottom: 1.15rem; }
.page-hero p { color: var(--ink-muted); font-size: clamp(1.02rem, 1.5vw, 1.22rem); max-width: 58ch; }

/* Breadcrumb */
.crumbs { font-size: 0.71rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: 1.5rem; }
.crumbs a { color: var(--ink-muted); }
.crumbs a:hover { color: var(--accent); }
.crumbs span { opacity: 0.45; margin-inline: 0.5rem; }

/* --------------------------------------------------------------------------
   8. Stats bar
   -------------------------------------------------------------------------- */
/* Breathing room between the dark hero and the credentials band, so the two
   do not collide edge to edge. */
.stats-band { padding-top: clamp(2.5rem, 6vw, 4rem); }

.stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
}
@media (min-width: 860px) { .stats { grid-template-columns: repeat(4, 1fr); } }
.stat {
  position: relative;
  background: var(--paper);
  padding: clamp(1.55rem, 3.2vw, 2.9rem) clamp(0.9rem, 2.5vw, 2rem);
  text-align: center;
}
/* A short accent rule that draws itself in as the stat scrolls into view. */
.stat::before {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  width: 0; height: 2px;
  background: var(--accent);
  transform: translateX(-50%);
  transition: width 0.85s 0.1s var(--ease);
}
.stat.is-in::before { width: 38px; }
.stat__num {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.95rem, 3.8vw, 3.1rem);
  line-height: 1;
  color: var(--forest);
  margin-bottom: 0.55rem;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
}
.stat__label {
  font-size: 0.63rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-muted);
  line-height: 1.6;
}
@media (min-width: 560px) { .stat__label { font-size: 0.68rem; letter-spacing: 0.17em; } }

/* --------------------------------------------------------------------------
   9. Split (image + text) sections
   -------------------------------------------------------------------------- */
.split {
  display: grid;
  gap: clamp(2.6rem, 5vw, 4.75rem);
  align-items: center;
}
@media (min-width: 940px) {
  .split { grid-template-columns: 1fr 1fr; }
  .split--wide-text { grid-template-columns: 0.88fr 1.12fr; }
  .split--wide-media { grid-template-columns: 1.12fr 0.88fr; }
  .split--reverse > *:first-child { order: 2; }
}
.split__media { position: relative; }
.split__badge {
  position: absolute;
  right: -0.5rem;
  bottom: -1rem;
  background: var(--forest);
  color: var(--on-dark);
  padding: 1.35rem 1.65rem;
  border-radius: var(--radius);
  max-width: 15rem;
  box-shadow: var(--shadow-md);
}
/* On phones the badge must not hang off the gutter, so it tucks inside. */
@media (max-width: 700px) {
  .split__badge { right: 0.75rem; bottom: 0.75rem; padding: 1rem 1.2rem; max-width: 12.5rem; }
}
.split__badge strong {
  display: block;
  font-family: var(--font-display);
  font-size: 2.1rem;
  line-height: 1;
  color: var(--accent-soft);
  margin-bottom: 0.4rem;
}
@media (max-width: 700px) { .split__badge strong { font-size: 1.6rem; } }
.split__badge span { font-size: 0.65rem; letter-spacing: 0.15em; text-transform: uppercase; color: var(--on-dark-muted); }

/* Credential list */
.cred-list { display: grid; gap: 0.85rem; margin: 2rem 0 2.4rem; }
.cred-list li { display: flex; gap: 0.85rem; align-items: flex-start; font-size: 0.97rem; }
.cred-list svg { width: 17px; height: 17px; flex: 0 0 17px; margin-top: 0.35rem; color: var(--accent); }
.cred-list strong { color: var(--ink); font-weight: 600; }
.section--dark .cred-list svg { color: var(--accent-soft); }
.section--dark .cred-list strong { color: var(--on-dark); }

/* Signature */
.signature {
  position: relative;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.85rem;
  color: var(--forest);
  margin-top: 2.25rem;
  padding-top: 1.6rem;
  line-height: 1.15;
}
.signature::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 52px; height: 1px;
  background: var(--accent);
}
.signature small {
  display: block;
  font-family: var(--font-body);
  font-style: normal;
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-top: 0.7rem;
}

/* --------------------------------------------------------------------------
   10. Cards & grids
   -------------------------------------------------------------------------- */
/* Explicit column counts: auto-fit would silently give a 2-up grid a third
   column at desktop widths and shrink the imagery. */
.grid { display: grid; gap: clamp(1.4rem, 2.5vw, 2rem); grid-template-columns: 1fr; }
@media (min-width: 780px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 660px)  { .grid--3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px)  { .grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 660px)  { .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .grid--4 { grid-template-columns: repeat(4, 1fr); } }

.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.6rem, 3vw, 2.6rem);
  display: flex;
  flex-direction: column;
  gap: 1rem;
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease), border-color 0.4s var(--ease);
  position: relative;
  overflow: hidden;
}
.card::after {
  content: "";
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s var(--ease);
}
/* A ghosted display numeral in the corner gives the card depth without
   another border or shadow. */
.card::before {
  content: attr(data-figure);
  position: absolute;
  right: -0.4rem; bottom: -1.6rem;
  font-family: var(--font-display);
  font-size: 7rem;
  line-height: 1;
  color: var(--accent);
  opacity: 0.055;
  pointer-events: none;
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}
.card:hover::before { opacity: 0.1; transform: translateY(-6px); }
.card:hover { transform: translateY(-6px); box-shadow: var(--shadow-md); border-color: var(--line-strong); }
.card:hover::after { transform: scaleX(1); }
.card__num {
  font-family: var(--font-body);
  font-size: 0.67rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  position: relative;
}
.card h3 { margin: 0; position: relative; }
.card p { font-size: 0.96rem; color: var(--ink-muted); position: relative; }
.card .link-arrow { margin-top: auto; padding-top: 0.6rem; position: relative; }
.card .cred-list { position: relative; }
.section--dark .card { background: var(--forest-soft); border-color: var(--line-dark); }
.section--dark .card p { color: var(--on-dark-muted); }
.section--dark .card__num { color: var(--accent-soft); }

/* Icon */
.icon-circle {
  width: 52px; height: 52px;
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  display: grid;
  place-items: center;
  color: var(--accent);
  margin-bottom: 0.4rem;
  position: relative;
  transition: background 0.4s var(--ease), color 0.4s var(--ease), border-color 0.4s var(--ease);
}
.icon-circle svg { width: 23px; height: 23px; }
.card:hover .icon-circle { background: var(--forest); color: var(--accent-soft); border-color: var(--forest); }

/* Card with photography.
   The image carries the section visually so three stacked text blocks stop
   reading as a wall of copy on a phone. The icon tile straddles the seam
   between image and body, which is what keeps it from looking like a
   stock-photo card. */
.card--media { padding: 0; gap: 0; }
.card--media .card__media {
  position: relative;
  overflow: hidden;
  background: var(--stone);
}
.card--media .card__media img {
  width: 100%;
  /* height:auto is load-bearing. Without it the img's height="1448" attribute
     wins and aspect-ratio is ignored, giving a 1448px-tall card. */
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform 0.9s var(--ease);
}
.card--media:hover .card__media img { transform: scale(1.04); }
.card--media .card__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8, 32, 26, 0.06) 0%, transparent 40%, rgba(8, 32, 26, 0.24) 100%);
  pointer-events: none;
}
.card--media .card__body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  flex: 1;
  padding: clamp(2.5rem, 3.4vw, 3rem) clamp(1.4rem, 3vw, 2.2rem) clamp(1.6rem, 3vw, 2.2rem);
}
/* The tile is anchored to the body's top edge, which is the seam under the
   photo, so it straddles the join. It lives in the body rather than the media
   box because the media box clips (for the hover zoom) and would cut it in half. */
.card--media .icon-circle {
  position: absolute;
  left: clamp(1.4rem, 3vw, 2.2rem);
  top: 0;
  z-index: 2;
  margin: 0;
  transform: translateY(-50%);
  width: 48px; height: 48px;
  background: var(--forest);
  border-color: var(--forest);
  color: var(--accent-soft);
  box-shadow: var(--shadow-md);
}
.card--media:hover .icon-circle { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Capability chips.
   A grid rather than wrapped flex: equal-width cells line up in true columns
   and rows, so seventeen items of wildly different label lengths read as an
   ordered schedule instead of a ragged pile. Rows stretch to the tallest cell,
   which keeps two-line labels flush with one-line neighbours. */
.chips {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 0.5rem;
  align-items: stretch;
}
@media (min-width: 560px) { .chips { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); } }

/* Every box is the same size, deliberately.
   Equal width comes from the 1fr columns. Equal HEIGHT is the harder half:
   five of the seventeen labels wrap to two lines, which would make their rows
   taller than the rest and give the block that stepped, ragged look. So the
   min-height is set to the two-line height and the label is centred inside
   it. One-line and two-line chips then occupy identical boxes, every row
   matches, and nothing has to be abbreviated to make the grid behave.
   The value is per-breakpoint because the font size changes with it. */
.chip {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 3.7rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-size: 0.79rem;
  line-height: 1.35;
  color: var(--ink-soft);
  background: var(--paper);
  transition: background 0.3s var(--ease), color 0.3s var(--ease), border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
@media (min-width: 560px) { .chip { min-height: 4rem; font-size: 0.85rem; padding: 0.75rem 1.05rem; } }
/* Pinned to the first line's optical centre so the bullets stay in a straight
   column whether the label runs to one line or two. */
.chip::before {
  content: "";
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--accent);
  flex: 0 0 4px;
  align-self: center;
}
.chip:hover { background: var(--forest); color: var(--on-dark); border-color: var(--forest); transform: translateY(-2px); }
.chip:hover::before { background: var(--accent-soft); }
.section--dark .chip { background: transparent; border-color: var(--line-dark); color: var(--on-dark-muted); }
.section--dark .chip::before { background: var(--accent-soft); }
.section--dark .chip:hover { background: var(--accent-soft); color: var(--forest-deep); border-color: var(--accent-soft); }

/* Capability grid */
.cap-grid { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
@media (min-width: 620px) { .cap-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .cap-grid { grid-template-columns: repeat(3, 1fr); } }
.cap {
  background: var(--paper);
  padding: clamp(1.35rem, 2.6vw, 2.1rem);
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  position: relative;
  transition: background 0.35s var(--ease);
}
.cap::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease);
}
.cap:hover { background: var(--mist); }
.cap:hover::after { transform: scaleX(1); }
.cap__icon { color: var(--accent); transition: transform 0.4s var(--ease); }
.cap:hover .cap__icon { transform: translateY(-2px); }
.cap__icon svg { width: 22px; height: 22px; }
.cap h4 { margin: 0; font-family: var(--font-body); font-size: 0.97rem; font-weight: 600; color: var(--ink); letter-spacing: 0; }
.cap p { font-size: 0.875rem; line-height: 1.62; color: var(--ink-muted); margin: 0; }

/* Project cards */
.project { position: relative; display: flex; flex-direction: column; gap: 1.15rem; }
.project__media { overflow: hidden; border-radius: var(--radius); position: relative; }
.project__media .site-image { transition: transform 0.9s var(--ease); }
.project__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 46%, rgba(8, 32, 26, 0.45));
  opacity: 0;
  transition: opacity 0.5s var(--ease);
  pointer-events: none;
}
.project:hover .project__media .site-image { transform: scale(1.04); }
.project:hover .project__media::after { opacity: 1; }
.project__index {
  position: absolute;
  left: 0; top: 0;
  z-index: 2;
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--on-dark);
  background: rgba(8, 32, 26, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  padding: 0.5rem 0.85rem;
}
.project__meta { display: flex; flex-direction: column; gap: 0.35rem; }
.project__cat { font-size: 0.64rem; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent); }
.project h3 { margin: 0; font-size: clamp(1.3rem, 1.9vw, 1.7rem); }
.project__place {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--ink-muted);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.project__place::before { content: ""; width: 16px; height: 1px; background: var(--line-strong); }
.project p { font-size: 0.93rem; color: var(--ink-muted); margin: 0.35rem 0 0; }
.section--dark .project p { color: var(--on-dark-muted); }
.section--dark .project__cat { color: var(--accent-soft); }

/* --------------------------------------------------------------------------
   11. Process
   -------------------------------------------------------------------------- */
.process { display: grid; gap: 0; }
@media (min-width: 900px) { .process { grid-template-columns: repeat(4, 1fr); } }
.step {
  position: relative;
  padding: 2.25rem 0 2.25rem 0;
  border-top: 1px solid var(--line);
}
@media (min-width: 900px) { .step { padding: 2.5rem 2.4rem 2.5rem 0; } }
/* Node + growing rule on the step's own top border: the four steps read as
   one measured line across the page. */
.step::before {
  content: "";
  position: absolute;
  left: 0; top: -4px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--paper);
  border: 1.5px solid var(--accent);
}
.step::after {
  content: "";
  position: absolute;
  left: 0; top: -1px;
  height: 2px; width: 0;
  background: var(--accent);
  transition: width 0.9s 0.2s var(--ease);
}
.step.is-in::after { width: 46px; }
.step__num {
  display: block;
  font-family: var(--font-display);
  font-size: 2.4rem;
  line-height: 1;
  color: var(--accent);
  margin-bottom: 1rem;
  letter-spacing: -0.02em;
}
.step h3 { font-size: 1.28rem; margin-bottom: 0.6rem; }
.step p { font-size: 0.93rem; margin: 0; color: var(--ink-muted); }
.section--dark .step { border-top-color: var(--line-dark); }
.section--dark .step::before { background: var(--forest); border-color: var(--accent-soft); }
.section--dark .step__num { color: var(--accent-soft); }
.section--dark .step p { color: var(--on-dark-muted); }

/* --------------------------------------------------------------------------
   12. Testimonials
   -------------------------------------------------------------------------- */
.quote {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.9rem, 3vw, 2.7rem);
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
  overflow: hidden;
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease), border-color 0.4s var(--ease);
}
/* Accent rule across the top, drawn in on hover, matching the service cards. */
.quote::after {
  content: "";
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s var(--ease);
}
.quote:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: var(--line-strong); }
.quote:hover::after { transform: scaleX(1); }

/* The quote mark is a watermark behind the text, not a glyph in the flow.
   That buys the copy its full measure and gives the card a focal point. */
.quote__mark {
  position: absolute;
  right: 0.55rem;
  top: 0.1rem;
  font-family: var(--font-display);
  font-size: 8rem;
  line-height: 1;
  color: var(--accent);
  opacity: 0.1;
  pointer-events: none;
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}
.quote:hover .quote__mark { opacity: 0.16; transform: translateY(3px); }

.quote p {
  position: relative;
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 1.6vw, 1.42rem);
  line-height: 1.44;
  color: var(--ink);
  margin: 0;
}
.quote footer {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin-top: auto;
  padding-top: 1.15rem;
  border-top: 1px solid var(--line);
}
/* Monogram tile: gives the attribution a visual anchor without inventing a
   photograph of someone. Swap for a real headshot if one is available. */
.quote__avatar {
  flex: 0 0 42px;
  width: 42px; height: 42px;
  display: grid;
  place-items: center;
  border-radius: var(--radius);
  background: var(--mist);
  border: 1px solid var(--line-strong);
  color: var(--accent);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  transition: background 0.35s var(--ease), color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.quote:hover .quote__avatar { background: var(--accent); border-color: var(--accent); color: #fff; }
.quote__who { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.quote cite { font-style: normal; font-weight: 600; font-size: 0.92rem; color: var(--ink); }
.quote small { font-size: 0.75rem; color: var(--ink-muted); letter-spacing: 0.03em; }

/* One card runs dark so the row has a centre of gravity instead of three
   identical white boxes. On a phone, where they stack, it still breaks up
   the column. */
.quote--feature {
  background: var(--forest);
  border-color: var(--forest);
}
.quote--feature::before {
  content: "";
  position: absolute;
  right: -9rem; bottom: -11rem;
  width: 24rem; height: 24rem;
  background: var(--contour-dark) center / contain no-repeat;
  opacity: 0.12;
  pointer-events: none;
}
.quote--feature p { color: var(--on-dark); }
.quote--feature .quote__mark { color: var(--accent-soft); opacity: 0.18; }
.quote--feature:hover .quote__mark { opacity: 0.26; }
.quote--feature footer { border-top-color: var(--line-dark); }
.quote--feature cite { color: var(--on-dark); }
.quote--feature small { color: var(--on-dark-muted); }
.quote--feature .quote__avatar { background: transparent; border-color: rgba(242, 247, 244, 0.34); color: var(--accent-soft); }
.quote--feature:hover .quote__avatar { background: var(--accent-soft); border-color: var(--accent-soft); color: var(--forest-deep); }
.quote--feature::after { background: var(--accent-soft); }

/* --------------------------------------------------------------------------
   13. Service areas
   -------------------------------------------------------------------------- */
.areas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 0.15rem 1.5rem;
}
.areas li {
  padding: 0.55rem 0;
  font-size: 0.9rem;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 0.65rem;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.areas li::before { content: ""; width: 4px; height: 4px; border-radius: 50%; background: var(--accent); flex: 0 0 4px; transition: transform 0.25s var(--ease); }
.areas li:hover { color: var(--ink); border-bottom-color: var(--line-strong); }
.areas li:hover::before { transform: scale(1.7); }

/* --------------------------------------------------------------------------
   14. CTA band
   -------------------------------------------------------------------------- */
.cta-band {
  position: relative;
  background: var(--forest);
  color: var(--on-dark-muted);
  overflow: hidden;
}
.cta-band::before {
  content: "";
  position: absolute;
  left: 50%; top: -60%;
  width: 60rem; height: 60rem;
  transform: translateX(-50%);
  background: radial-gradient(circle, rgba(111, 211, 164, 0.14), transparent 60%);
  pointer-events: none;
}
/* Contour motif anchored to the left edge, mirrored by the glow above. */
.cta-band::after {
  content: "";
  position: absolute;
  left: -14rem;
  bottom: -16rem;
  width: 42rem; height: 42rem;
  background: var(--contour-dark) center / contain no-repeat;
  opacity: 0.10;
  pointer-events: none;
}
@media (max-width: 760px) { .cta-band::after { left: -22rem; opacity: 0.07; } }
/* Wide enough that the action row never wraps; the copy keeps its own measure. */
.cta-band__inner { position: relative; z-index: 2; text-align: center; max-width: 70ch; margin-inline: auto; }
.cta-band h2 { color: var(--on-dark); margin-bottom: 1rem; max-width: 20ch; margin-inline: auto; }
.cta-band p { color: var(--on-dark-muted); font-size: clamp(1rem, 1.5vw, 1.16rem); max-width: 54ch; margin-inline: auto; }
.cta-band .eyebrow { color: var(--accent-soft); }
.cta-band__actions { display: flex; flex-wrap: wrap; gap: 0.85rem; justify-content: center; margin-top: 2.2rem; }
@media (max-width: 520px) { .cta-band__actions .btn { flex: 1 1 100%; } }

/* --------------------------------------------------------------------------
   15. Forms
   -------------------------------------------------------------------------- */
.form-layout { display: grid; gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
@media (min-width: 980px) { .form-layout { grid-template-columns: 1.35fr 0.65fr; } }

.form-card {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.35rem, 3.6vw, 3.1rem);
  box-shadow: var(--shadow-sm);
}
.form-card::before {
  content: "";
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 3px;
  background: linear-gradient(90deg, var(--forest), var(--accent) 55%, var(--accent-soft));
}
.form-card > h2 { margin-top: 0.35rem; }
.form-grid { display: grid; gap: 1.35rem; }
@media (min-width: 640px) { .form-grid--2 { grid-template-columns: 1fr 1fr; } }

.field { display: flex; flex-direction: column; gap: 0.5rem; }
.field label {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink);
}
.field label .req { color: var(--accent); }
.field label .optional {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  color: var(--ink-muted);
}
/* 16px keeps iOS from zooming the viewport when a field takes focus. */
.field input,
.field select,
.field textarea {
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.95rem 1.1rem;
  width: 100%;
  min-height: 50px;
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease), box-shadow 0.25s var(--ease);
  appearance: none;
}
.field textarea { min-height: 150px; resize: vertical; line-height: 1.62; }
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230F2E24' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 16px;
  padding-right: 2.8rem;
  cursor: pointer;
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--line-strong); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  background: var(--paper);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(28, 122, 83, 0.13);
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-muted); opacity: 0.62; }

.field--error input, .field--error select, .field--error textarea { border-color: #C0453A; background: #FEF6F5; }
.field__error { display: none; font-size: 0.8rem; color: #C0453A; }
.field--error .field__error { display: block; }

.checkbox { display: flex; align-items: flex-start; gap: 0.75rem; font-size: 0.87rem; color: var(--ink-muted); line-height: 1.6; cursor: pointer; }
.checkbox input { width: 20px; height: 20px; flex: 0 0 20px; margin-top: 0.18rem; accent-color: var(--accent); appearance: auto; padding: 0; min-height: 0; }

.form-note { font-size: 0.8rem; color: var(--ink-muted); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-success {
  display: none;
  position: relative;
  background: var(--forest);
  color: var(--on-dark);
  border-radius: var(--radius);
  padding: clamp(1.75rem, 4vw, 3.4rem);
  text-align: center;
  overflow: hidden;
}
.form-success::after {
  content: "";
  position: absolute;
  right: -12rem; top: -10rem;
  width: 30rem; height: 30rem;
  background: var(--contour-dark) center / contain no-repeat;
  opacity: 0.1;
  pointer-events: none;
}
.form-success.is-visible { display: block; animation: rise 0.6s var(--ease) both; }
.form-success > * { position: relative; z-index: 1; }
.form-success h3 { color: var(--on-dark); }
.form-success p { color: var(--on-dark-muted); }
.form-success__icon {
  width: 60px; height: 60px;
  border-radius: var(--radius);
  border: 1px solid var(--accent-soft);
  color: var(--accent-soft);
  display: grid; place-items: center;
  margin: 0 auto 1.6rem;
}
.form-success__icon svg { width: 26px; height: 26px; }

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

/* Contact sidebar */
.contact-aside { display: grid; gap: 1.15rem; }
.info-card {
  position: relative;
  background: var(--forest);
  color: var(--on-dark-muted);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3vw, 2.3rem);
  overflow: hidden;
}
.info-card::after {
  content: "";
  position: absolute;
  right: -9rem; bottom: -11rem;
  width: 26rem; height: 26rem;
  background: var(--contour-dark) center / contain no-repeat;
  opacity: 0.1;
  pointer-events: none;
}
.info-card > * { position: relative; z-index: 1; }
.info-card h3 { color: var(--on-dark); font-size: 1.45rem; margin-bottom: 1.5rem; }
.info-list { display: grid; gap: 1.35rem; }
.info-list li { display: flex; gap: 0.95rem; align-items: flex-start; }
.info-list svg { width: 18px; height: 18px; flex: 0 0 18px; margin-top: 0.3rem; color: var(--accent-soft); }
.info-list span { display: block; font-size: 0.63rem; font-weight: 600; letter-spacing: 0.19em; text-transform: uppercase; color: var(--on-dark-muted); margin-bottom: 0.25rem; }
.info-list a, .info-list p { color: var(--on-dark); font-size: 1rem; margin: 0; line-height: 1.5; overflow-wrap: anywhere; }
.info-list a:hover { color: var(--accent-soft); }
.info-list .info-link { font-size: 0.85rem; display: inline-block; margin-top: 0.35rem; color: var(--accent-soft); }

.hours-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3vw, 2.3rem);
}
.hours-card h3 { font-size: 1.35rem; margin-bottom: 1.2rem; }
.hours { display: grid; gap: 0.7rem; }
/* Narrow sidebar: let a row wrap as two whole phrases rather than breaking mid-phrase. */
.hours li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.15rem 1rem; font-size: 0.88rem; padding-bottom: 0.7rem; border-bottom: 1px solid var(--line); }
.hours strong, .hours span { white-space: nowrap; }
.hours li:last-child { border-bottom: 0; padding-bottom: 0; }
.hours strong { color: var(--ink); font-weight: 500; }
.hours span { color: var(--ink-muted); }

/* --------------------------------------------------------------------------
   16. FAQ
   -------------------------------------------------------------------------- */
.faq { display: grid; gap: 0; border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  list-style: none;
  cursor: pointer;
  padding: 1.45rem 2.6rem 1.45rem 0;
  position: relative;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.7vw, 1.5rem);
  line-height: 1.24;
  color: var(--ink);
  transition: color 0.25s var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }
.faq summary::after {
  content: "";
  position: absolute;
  right: 0.4rem; top: 50%;
  width: 13px; height: 13px;
  margin-top: -6px;
  background: var(--accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 5v14M5 12h14' stroke='black' stroke-width='2.4' stroke-linecap='round' fill='none'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 5v14M5 12h14' stroke='black' stroke-width='2.4' stroke-linecap='round' fill='none'/%3E%3C/svg%3E") center/contain no-repeat;
  transition: transform 0.35s var(--ease);
}
.faq details[open] summary::after { transform: rotate(135deg); }
.faq details[open] summary { color: var(--accent); }
.faq__body { padding: 0 2.6rem 1.7rem 0; font-size: 0.96rem; color: var(--ink-muted); animation: rise 0.4s var(--ease) both; }
.faq__body p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   17. Footer
   -------------------------------------------------------------------------- */
.site-footer {
  position: relative;
  background: var(--forest-deep);
  color: var(--on-dark-muted);
  padding-top: clamp(3rem, 7vw, 5.5rem);
  font-size: 0.93rem;
  overflow: hidden;
}
.site-footer::before {
  content: "";
  position: absolute;
  right: -16rem; top: -14rem;
  width: 46rem; height: 46rem;
  background: var(--contour-dark) center / contain no-repeat;
  opacity: 0.08;
  pointer-events: none;
}
/* Hairline of accent along the very top edge of the footer. */
.site-footer::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, var(--accent), rgba(111, 211, 164, 0.25) 45%, transparent 85%);
}
.footer-grid { position: relative; z-index: 1; display: grid; gap: clamp(2rem, 4vw, 3.5rem); padding-bottom: clamp(2.25rem, 5vw, 4rem); }
@media (min-width: 780px) { .footer-grid { grid-template-columns: 1.5fr 1fr 1fr; } }
@media (min-width: 1060px) { .footer-grid { grid-template-columns: 1.7fr 1fr 1fr 1.2fr; } }
.site-footer h4 {
  font-family: var(--font-body);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.21em;
  text-transform: uppercase;
  color: var(--accent-soft);
  margin-bottom: 1.4rem;
}
.site-footer a { color: var(--on-dark-muted); }
.site-footer a:hover { color: var(--accent-soft); }
.footer-links { display: grid; gap: 0.72rem; }
.footer-links a { display: inline-block; padding-block: 0.1rem; }
.footer-brand .brand__name { color: var(--on-dark); font-size: 1.45rem; }
.footer-brand .brand__tag { color: var(--on-dark-muted); }
.footer-brand .brand__mark { border-color: var(--line-dark); color: var(--accent-soft); }
.footer-brand p { margin-top: 1.5rem; max-width: 34ch; font-size: 0.92rem; line-height: 1.72; }
.footer-social { display: flex; gap: 0.6rem; margin-top: 1.7rem; }
.footer-social a {
  width: 44px; height: 44px;
  border: 1px solid var(--line-dark);
  border-radius: var(--radius);
  display: grid; place-items: center;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease), color 0.3s var(--ease), transform 0.3s var(--ease);
}
.footer-social a:hover { background: var(--accent-soft); border-color: var(--accent-soft); color: var(--forest-deep); transform: translateY(-2px); }
.footer-social svg { width: 16px; height: 16px; }
.footer-bottom {
  position: relative;
  z-index: 1;
  border-top: 1px solid var(--line-dark);
  padding-block: 1.6rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem 1.6rem;
  justify-content: space-between;
  align-items: center;
  font-size: 0.79rem;
}
.footer-bottom p { margin: 0; }
.footer-legal { display: flex; gap: 1.4rem; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   18. Reveal on scroll
   -------------------------------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: 0.10s; }
.reveal[data-delay="2"] { transition-delay: 0.20s; }
.reveal[data-delay="3"] { transition-delay: 0.30s; }
.reveal[data-delay="4"] { transition-delay: 0.40s; }

/* Touch targets: on phones the inline text links sit at their 19-20px line
   box, which is below the 24px minimum. Vertical padding grows the hit area
   without changing how any of it looks, so the list gaps shrink to match. */
@media (max-width: 999px) {
  .topbar__contact a { padding-block: 0.5rem; }
  .footer-links { gap: 0.3rem; }
  .footer-links a { padding-block: 0.42rem; }
  .footer-legal a { padding-block: 0.4rem; }
  .info-list a { display: inline-block; padding-block: 0.28rem; }
  .crumbs a { display: inline-block; padding-block: 0.3rem; }
  .mobile-nav__foot a:not(.btn) { padding-block: 0.4rem; }
  .areas li { padding-block: 0.7rem; }
}

/* Touch devices: hover transforms latch on after a tap, so they are dropped. */
@media (hover: none) {
  .card:hover, .quote:hover, .btn:hover, .chip:hover, .footer-social a:hover { transform: none; }
  .project:hover .project__media .site-image { transform: none; }
  .media-frame:hover::before, .media-frame:hover::after { transform: none; opacity: 0.5; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .hero__image { animation: none; }
  .hero__cue::after { animation: none; }
  .progress-bar { display: none; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* --------------------------------------------------------------------------
   19. Sticky mobile actions: quick contact bar + back to top
   --------------------------------------------------------------------------
   Both reuse the existing button and tile language rather than inventing a
   new one: the same 2px geometry, the same forest/mint pairing used on every
   dark band, and the same .btn--light / .btn--outline-light pairing the hero
   already uses on a dark ground.
   -------------------------------------------------------------------------- */
.quickbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 44;
  display: none;
  align-items: center;
  gap: 0.55rem;
  padding: 0.7rem var(--gutter);
  padding-bottom: calc(0.7rem + env(safe-area-inset-bottom));
  background: rgba(15, 46, 36, 0.97);
  backdrop-filter: saturate(150%) blur(12px);
  -webkit-backdrop-filter: saturate(150%) blur(12px);
  border-top: 1px solid rgba(111, 211, 164, 0.3);
  box-shadow: 0 -14px 34px -24px rgba(8, 32, 26, 0.9);
  transform: translateY(110%);
  transition: transform 0.45s var(--ease), opacity 0.3s var(--ease);
}
/* Phones and small tablets only. On desktop the header CTA already does this. */
@media (max-width: 860px) { .quickbar { display: flex; } }
/* Must beat the media query above, which would otherwise re-show a dismissed
   bar by out-specifying the UA rule for [hidden]. */
.quickbar[hidden] { display: none !important; }
.quickbar.is-visible { transform: none; }
.quickbar .btn {
  flex: 1 1 0;
  min-width: 0;
  padding: 0.92rem 0.6rem;
  min-height: 48px;
  font-size: 0.68rem;
  letter-spacing: 0.13em;
  gap: 0.5rem;
}
.quickbar .btn svg { width: 15px; height: 15px; flex: 0 0 15px; }
.quickbar__close {
  flex: 0 0 40px;
  width: 40px; height: 40px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1px solid rgba(242, 247, 244, 0.26);
  border-radius: var(--radius);
  color: var(--on-dark-muted);
  cursor: pointer;
  padding: 0;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.quickbar__close:hover { color: var(--forest-deep); background: var(--accent-soft); border-color: var(--accent-soft); }
.quickbar__close svg { width: 15px; height: 15px; }

/* The floating right-hand rail: back-to-top on top, and the control that
   brings a dismissed quick bar back sitting directly beneath it. Both are
   circles, the one place the 2px geometry is set aside, because a floating
   action that overlaps scrolling content reads better with no corners. */
.to-top,
.quickbar-reopen {
  position: fixed;
  right: var(--gutter);
  z-index: 40;
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  padding: 0;
  background: var(--forest);
  color: var(--on-dark);
  /* A mint hairline rather than a forest one: these float over both the white
     sections and the near-black footer, and forest-on-forest-deep would
     vanish against the latter. */
  border: 1px solid rgba(111, 211, 164, 0.45);
  border-radius: 50%;
  box-shadow: var(--shadow-md);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease),
              visibility 0.35s, background 0.3s var(--ease), border-color 0.3s var(--ease), bottom 0.45s var(--ease);
}
.to-top { bottom: calc(1.15rem + env(safe-area-inset-bottom)); }
.to-top.is-visible,
.quickbar-reopen.is-visible { opacity: 1; visibility: visible; transform: none; }
.to-top:hover,
.quickbar-reopen:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.to-top svg { width: 18px; height: 18px; }
.quickbar-reopen svg { width: 17px; height: 17px; }

/* Only exists once the bar has been dismissed, and only where the bar runs. */
.quickbar-reopen { display: none; bottom: calc(1.15rem + env(safe-area-inset-bottom)); }
@media (max-width: 860px) {
  body.quickbar-dismissed .quickbar-reopen { display: grid; }
  /* The arrow steps up one slot so the reopen control tucks in beneath it. */
  body.quickbar-dismissed .to-top { bottom: calc(1.15rem + 46px + 0.6rem + env(safe-area-inset-bottom)); }
}
/* Space is reserved as soon as the bar is live, not when it slides in, so its
   arrival never reflows the page under the reader. */
@media (max-width: 860px) {
  body.quickbar-active .to-top { bottom: calc(var(--quickbar-h, 4.5rem) + 1rem + env(safe-area-inset-bottom)); }
  body.quickbar-active .site-footer { padding-bottom: var(--quickbar-h, 4.5rem); }
}

@media (prefers-reduced-motion: reduce) {
  .quickbar, .to-top { transition: none; }
}

/* --------------------------------------------------------------------------
   20. Utilities
   -------------------------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--forest);
  color: var(--paper);
  padding: 0.9rem 1.4rem;
  z-index: 100;
  border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus { left: 0; color: var(--paper); }

.mt-0 { margin-top: 0; }
.mt-2 { margin-top: 2rem; }
.mb-0 { margin-bottom: 0; }
.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;
}

/* --------------------------------------------------------------------------
   21. Print
   -------------------------------------------------------------------------- */
@media print {
  .topbar, .site-header, .mobile-nav, .progress-bar, .hero__cue, .cta-band,
  .footer-social, .quickbar, .to-top { display: none !important; }
  body { color: #000; font-size: 11pt; }
  .reveal { opacity: 1 !important; transform: none !important; }
  .section { padding-block: 1.5rem; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
}
