/* ==========================================================================
   Desert Systems — 2027
   Design system + site styles
   ========================================================================== */

/* --- Tokens --------------------------------------------------------------- */
:root {
  /* Brand */
  --bronze:        #b08d6a;
  --bronze-lt:     #cdae8c;
  --bronze-dk:     #8e6f50;

  /* Dark surfaces */
  --ink:           #0e0e10;
  --ink-2:         #16161a;
  --ink-3:         #1f1f25;

  /* Light surfaces */
  --paper:         #e7e0d5;   /* linen — warm enough not to read as a lit screen */
  --paper-2:       #ddd5c8;

  /* Text */
  --on-dark:       #f5f4f2;
  --on-dark-mute:  #a3a19e;
  --on-light:      #14141a;
  --on-light-mute: #5d5b57;

  /* Lines */
  --line-dark:     rgba(255, 255, 255, 0.11);
  --line-light:    rgba(0, 0, 0, 0.10);

  /* Type */
  --display: "Poppins", "Helvetica Neue", Arial, sans-serif;
  --body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  /* Rhythm */
  --gutter:  clamp(1.25rem, 5vw, 4.5rem);
  --section: clamp(4.5rem, 10vw, 9rem);
  --maxw:    1320px;

  /* Motion */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

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

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

body {
  margin: 0;
  font-family: var(--body);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.7;
  color: var(--on-dark);
  background: var(--ink);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 0 0 0.6em;
  text-wrap: balance;
}

h1 { font-size: clamp(2.05rem, 1.35rem + 3.2vw, 3.9rem); }
h2 { font-size: clamp(1.65rem, 1.2rem + 1.95vw, 2.7rem); }
h3 { font-size: clamp(1.15rem, 1.05rem + 0.6vw, 1.45rem); }
h4 { font-size: 1.0625rem; }

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

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

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

/* --- Layout helpers ------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

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

.section { padding-block: var(--section); }
.section--tight { padding-block: clamp(3rem, 6vw, 5rem); }

.section--light {
  /* Bronze at #b08d6a measures 2.8:1 on a pale background — under the 4.5:1
     minimum for small text. Re-declaring the token here means every eyebrow,
     rule, number and link inside a light section picks up the darker value
     automatically, and bronze stays as-is on the dark sections. */
  --bronze: #7a5c40;
  background: var(--paper);
  color: var(--on-light);
}
.section--light .lede,
.section--light .eyebrow + h2 + p { color: var(--on-light-mute); }

.section--ink-2 { background: var(--ink-2); }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--bronze-dk);   /* white on the light bronze was 3.1:1 */
  color: #fff;
  padding: 0.75rem 1.25rem;
  z-index: 200;
}
.skip-link:focus { left: 0; }

/* --- Type utilities ------------------------------------------------------- */
.eyebrow {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--bronze);
  margin: 0 0 1.25rem;
  display: flex;
  align-items: center;
  gap: 0.85rem;
}
.eyebrow::before {
  content: "";
  width: 2.25rem;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
  flex: none;
}

.lede {
  font-size: clamp(1rem, 0.95rem + 0.28vw, 1.175rem);
  line-height: 1.68;
  color: var(--on-dark-mute);
  max-width: 62ch;
}

.section-head { max-width: 760px; margin-bottom: clamp(2.5rem, 5vw, 4rem); }

/* --- Buttons -------------------------------------------------------------- */
.btn {
  /* White on the light bronze measured 3.1:1 — under the 4.5:1 small-text
     minimum. The fill is the deeper bronze, which clears at 4.6:1. */
  --btn-bg: var(--bronze-dk);
  --btn-fg: #fff;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--display);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 0.95rem 1.8rem;
  border: 1px solid var(--btn-bg);
  border-radius: 999px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease),
              color 0.3s var(--ease), transform 0.3s var(--ease);
}
.btn:hover { background: #6b4f36; border-color: #6b4f36; transform: translateY(-2px); }

.btn--ghost { --btn-bg: transparent; --btn-fg: var(--on-dark); border-color: var(--line-dark); }
.btn--ghost:hover { background: rgba(255, 255, 255, 0.06); border-color: var(--bronze); color: var(--on-dark); transform: translateY(-2px); }

.btn--ghost-dark { --btn-bg: transparent; --btn-fg: var(--on-light); border-color: var(--line-light); }
.btn--ghost-dark:hover { background: rgba(0, 0, 0, 0.05); border-color: var(--bronze); color: var(--on-light); }

.btn .arw { transition: transform 0.3s var(--ease); }
.btn:hover .arw { transform: translateX(4px); }

/* Text link with arrow */
.link-more {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--display);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bronze);
  padding-bottom: 0.35rem;
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), gap 0.3s var(--ease);
}
.link-more:hover { border-color: var(--bronze); gap: 0.9rem; }

/* --- Header --------------------------------------------------------------- */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  /* The bar is always present. A transparent header over a photograph cannot
     meet contrast — the nav links measured 1.0:1 against a bright sky, and no
     gradient fixes it without darkening the image more than the text is worth.
     With the bar, the links sit at 5.7:1 and the photograph keeps everything
     below 84px. */
  background: rgba(14, 14, 16, 0.86);
  backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease);
}
.site-header.is-stuck {
  background: rgba(14, 14, 16, 0.94);
  border-bottom-color: var(--line-dark);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  min-height: 84px;
}

/* Wordmark — the real logo, drawn from the Illustrator vectors.
   The path uses fill:currentColor, so it takes the colour of whatever it sits in. */
.wordmark {
  display: inline-flex;
  align-items: center;
  color: var(--on-dark);
  margin: 0;
  transition: color 0.25s var(--ease);
}
.wordmark__mark {
  display: block;
  /* SYSTEMS is hairline weight; below ~160px its arms fall off the pixel grid
     on 1x displays and the E can read as an F. */
  width: clamp(162px, 15vw, 206px);
  height: auto;
}
/* The lockup is the DS mark, a hairline, then the wordmark with the trade list
   under it. The mark is sized off the wordmark so the two scale together. */
.wordmark { gap: 0.6rem; }
.wordmark__ds {
  display: block;
  height: clamp(30px, 3vw, 38px);
  width: auto;
  flex: none;
}
.wordmark__rule {
  align-self: stretch;
  width: 1px;
  min-height: 30px;
  background: currentColor;
  opacity: 0.3;
  flex: none;
}
a.wordmark:hover { color: var(--bronze-lt); }

.wordmark--footer { margin-bottom: 1.35rem; gap: 0.55rem; }
.wordmark--footer .wordmark__mark { width: 176px; }
.wordmark--footer .wordmark__ds { height: 34px; }

/* Below the compact breakpoint the trade list is the first thing to go. */
@media (max-width: 620px) {
  .wordmark__ds { height: 28px; }
}

.nav { display: flex; align-items: center; gap: clamp(1rem, 2vw, 2.1rem); }

.nav a {
  font-family: var(--display);
  white-space: nowrap;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--on-dark-mute);
  padding-block: 0.35rem;
  position: relative;
  transition: color 0.25s var(--ease);
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--bronze);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease);
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--on-dark); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }

.nav .btn,
.nav a.btn[aria-current="page"] { padding: 0.7rem 1.4rem; color: #fff; }
.nav .btn::after { display: none; }

.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  border: 0;
  background: transparent;
  color: var(--on-dark);
  cursor: pointer;
  padding: 10px;
}
.nav-toggle span {
  display: block;
  height: 1.5px;
  background: currentColor;
  margin: 5px 0;
  transition: transform 0.3s var(--ease), opacity 0.2s 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); }

/* --- Hero ----------------------------------------------------------------- */
/* Stacked, not overlaid: the photograph runs as a clean full-width band and the
   text sits below it on the solid ground. Nothing is washed over the image, and
   the type sits at 17:1 against #0e0e10 instead of fighting a sky. */
.hero {
  position: relative;
  padding-top: 84px;              /* clear the fixed header bar */
  background: var(--ink);
}

.hero__media { position: relative; }
.hero__media img {
  width: 100%;
  height: auto;
  display: block;
  /* One photograph at every width, so the homepage is the same page on a phone
     as on a desktop. The ratio is pinned to the file so nothing is cropped and
     nothing shifts as it loads. */
  aspect-ratio: 12978 / 6362;
  object-fit: cover;
}

.hero__inner {
  width: 100%;
  padding-block: clamp(2.5rem, 5vw, 4rem) clamp(3rem, 6vw, 4.5rem);
}
.hero h1 { max-width: 18ch; margin-bottom: 1.25rem; }
.hero .lede { max-width: 58ch; color: var(--on-dark-mute); }
.hero__cta { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-top: 2.25rem; }

/* Page hero (interior pages) */
.page-hero {
  position: relative;
  padding-block: clamp(9rem, 16vw, 13rem) clamp(3rem, 6vw, 5rem);
  isolation: isolate;
  overflow: hidden;
}
.page-hero__media { position: absolute; inset: 0; z-index: -2; }
.page-hero__media img { width: 100%; height: 100%; object-fit: cover; }
.page-hero::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top, rgba(14,14,16,0.95), rgba(14,14,16,0.6));
}
/* Photo heroes carry the text on the left, so the ink goes there rather than over
   the whole picture. That lets the open side of the photograph sit about twice as
   bright as a flat overlay allowed, while the headline keeps a dark ground under
   it whatever the photograph happens to be doing. */
.page-hero:not(.page-hero--plain)::after {
  background: linear-gradient(to top, rgba(14,14,16,0.88), rgba(14,14,16,0.32));
}
.page-hero:not(.page-hero--plain)::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to right,
    rgba(14,14,16,0.93) 0%, rgba(14,14,16,0.88) 55%, rgba(14,14,16,0) 88%);
}
/* Muted grey was measuring 2.4:1 to 3.9:1 over these photographs. */
.page-hero:not(.page-hero--plain) .lede { color: #d2cfca; }
.page-hero h1 { max-width: 18ch; margin-bottom: 1.25rem; }
.page-hero--plain { background: var(--ink-2); border-bottom: 1px solid var(--line-dark); }

/* --- Split feature -------------------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.split--reverse > *:first-child { order: 2; }

.split__media { position: relative; }
.split__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 4px;
}

/* --- Service cards -------------------------------------------------------- */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: 1.5rem;
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 460px;
  padding: clamp(1.75rem, 3vw, 2.75rem);
  border-radius: 4px;
  overflow: hidden;
  isolation: isolate;
  color: var(--on-dark);
}
.card__media { position: absolute; inset: 0; z-index: -2; }
.card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.9s var(--ease);
}
.card::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top, rgba(14,14,16,0.94) 8%, rgba(14,14,16,0.35) 55%, rgba(14,14,16,0.15) 100%);
  transition: opacity 0.5s var(--ease);
}
.card:hover .card__media img { transform: scale(1.05); }
.card h3 { margin-bottom: 0.5rem; }
.card p { color: rgba(245,244,242,0.78); margin-bottom: 1.5rem; }

/* --- Principles (numbered) ------------------------------------------------ */
.principles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(1.75rem, 4vw, 3.5rem);
}
.principle { padding-top: 1.75rem; border-top: 1px solid var(--line-light); }
.section--light .principle { border-top-color: var(--line-light); }
.principle__num {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--bronze);
  display: block;
  margin-bottom: 1rem;
}
.principle h3 { margin-bottom: 0.65rem; }
.principle p { color: var(--on-light-mute); font-size: 0.9375rem; }

/* --- Service list (residential / commercial detail) ----------------------- */
.svc-list { display: grid; gap: clamp(3rem, 7vw, 6rem); }

.svc {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: center;
}
.svc:nth-child(even) .svc__media { order: 2; }
.svc__media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 4px;
}
.svc__body { max-width: 56ch; }

/* Compact grid for items without photos */
.svc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
.svc-grid > div { padding-top: 1.5rem; border-top: 1px solid var(--line-dark); }
.section--light .svc-grid > div { border-top-color: var(--line-light); }
.svc-grid h3 { font-size: 1.1875rem; margin-bottom: 0.5rem; }
.svc-grid p { font-size: 0.9375rem; color: var(--on-dark-mute); }
.section--light .svc-grid p { color: var(--on-light-mute); }

/* --- Gallery -------------------------------------------------------------- */
.gallery {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}
.gallery figure { margin: 0; position: relative; overflow: hidden; border-radius: 4px; grid-column: span 4; }
.gallery figure img {
  width: 100%; height: 100%;
  object-fit: cover;
  aspect-ratio: 3 / 2;
  transition: transform 0.9s var(--ease);
}
.gallery figure:hover img { transform: scale(1.04); }
.gallery .g-wide { grid-column: span 8; }
.gallery .g-full { grid-column: span 12; }
.gallery .g-tall img { aspect-ratio: 3 / 4; }

/* A strip of smaller tiles — for photography that does not hold up large. */
.gallery--strip { grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }
.gallery.gallery--strip figure { grid-column: auto; }

.gallery figcaption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 1.5rem 1.25rem 1.1rem;
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #fff;
  /* The caption sits over a photograph, so it carries its own gradient. Weighted
     toward the baseline where the text actually is, rather than fading evenly. */
  background: linear-gradient(to top,
    rgba(14,14,16,0.94) 0%, rgba(14,14,16,0.82) 45%,
    rgba(14,14,16,0.40) 78%, rgba(14,14,16,0) 100%);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
.gallery figure:hover figcaption { opacity: 1; transform: none; }

/* --- Stats / trust strip -------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  gap: clamp(1.5rem, 4vw, 3rem);
  text-align: left;
}
.stat__n {
  font-family: var(--display);
  font-size: clamp(2.25rem, 1.6rem + 2.6vw, 3.5rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--bronze);
  display: block;
  margin-bottom: 0.6rem;
}
.stat p { font-size: 0.875rem; color: var(--on-dark-mute); margin: 0; }

/* --- Quote ---------------------------------------------------------------- */
.quote {
  max-width: 24ch;
  font-family: var(--display);
  font-size: clamp(1.45rem, 1.05rem + 1.9vw, 2.4rem);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: -0.02em;
  margin: 0;
}
.quote em { font-style: normal; color: var(--bronze); }

/* --- Partners ------------------------------------------------------------- */
.partners {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2.75rem;
  align-items: center;
}
.partners li {
  font-family: var(--display);
  font-size: clamp(0.9375rem, 0.85rem + 0.4vw, 1.1875rem);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--on-light-mute);
  list-style: none;
}
.partners { margin: 0; padding: 0; }

/* --- CTA band ------------------------------------------------------------- */
.cta-band {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(4rem, 9vw, 7.5rem);
}
.cta-band__media { position: absolute; inset: 0; z-index: -2; }
.cta-band__media img { width: 100%; height: 100%; object-fit: cover; }
.cta-band::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: rgba(14, 14, 16, 0.82);
}
.cta-band h2 { max-width: 18ch; }

/* --- Contact -------------------------------------------------------------- */
.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(2rem, 5vw, 4rem);
}

.contact-item { margin-bottom: 2rem; }
.contact-item h4 {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bronze);
  margin-bottom: 0.5rem;
}
.contact-item a:hover { color: var(--bronze-lt); }

.form-row { display: grid; gap: 1.25rem; margin-bottom: 1.25rem; }
.form-row--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }

.field label {
  display: block;
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark-mute);
  margin-bottom: 0.5rem;
}
.field input,
.field select,
.field textarea {
  width: 100%;
  font: inherit;
  font-size: 0.9375rem;
  color: var(--on-dark);
  background: var(--ink-3);
  border: 1px solid var(--line-dark);
  border-radius: 3px;
  padding: 0.85rem 1rem;
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease);
}
.field textarea { min-height: 150px; resize: vertical; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--bronze);
  background: #23232a;
}
.field input::placeholder, .field textarea::placeholder { color: #6e6c69; }

.form-note { font-size: 0.8125rem; color: var(--on-dark-mute); margin-top: 1rem; }
#contact-status { color: var(--on-dark); }
#contact-status:empty { margin-top: 0; }
#contact-form .btn:disabled { opacity: 0.6; cursor: progress; transform: none; }
#contact-turnstile { min-height: 65px; margin-bottom: 1.25rem; } /* Turnstile widget height, kept to stop a layout jump */

/* --- Email reveal (email-reveal.js) ----------------------------------------- */
/* A button that looks like the links around it. The address appears after a Turnstile check. */
.email-reveal {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 0.25em;
  transition: color 0.25s var(--ease);
}
.email-reveal:hover { color: var(--bronze-lt); }
.email-reveal:disabled { cursor: progress; opacity: 0.7; }
.footer-grid .email-reveal { font-size: 0.9375rem; color: var(--on-dark-mute); }
.footer-grid .email-reveal:hover { color: var(--bronze-lt); }
.btn[data-email-reveal]:disabled { opacity: 0.6; cursor: progress; transform: none; }
.email-reveal__msg { display: block; margin-top: 0.4rem; font-size: 0.8125rem; color: var(--on-dark-mute); }

/* Holds the Turnstile widget. Hidden unless Cloudflare asks the visitor to click. */
.email-check {
  position: fixed;
  z-index: 1000;
  left: 50%;
  bottom: 1rem;
  transform: translateX(-50%);
  width: min(340px, calc(100vw - 1rem));
  padding: 1rem;
  background: var(--ink-2);
  border: 1px solid var(--line-dark);
  border-radius: 6px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  visibility: hidden;
}
.email-check.is-open { visibility: visible; }
.email-check__text { margin: 0 0 0.75rem; font-size: 0.875rem; color: var(--on-dark); }
.email-check__cancel {
  margin-top: 0.75rem;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--on-dark-mute);
  text-decoration: underline;
  cursor: pointer;
}

/* --- Footer --------------------------------------------------------------- */
.site-footer {
  background: var(--ink-2);
  border-top: 1px solid var(--line-dark);
  padding-block: clamp(3rem, 6vw, 5rem) 2rem;
}
.footer-grid {
  display: grid;
  /* repeat(auto-fit) needs every other track to be a definite size, so leading
     with 1.4fr made the whole declaration invalid and the footer dropped to a
     single column on every screen above the small breakpoint. Explicit tracks. */
  grid-template-columns: 1.5fr 1fr 1fr 1.25fr;
  gap: clamp(2rem, 5vw, 3.5rem);
  padding-bottom: 3rem;
}
@media (max-width: 900px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
}
/* Grid items default to a min-content floor, so one long unbreakable token —
   an email address — can force a track wider than the viewport. */
.footer-grid > *,
.cards > *,
.split > *,
.svc > *,
.svc-grid > *,
.contact-grid > * { min-width: 0; }

.footer-grid a,
.contact-item a,
.footer-blurb { overflow-wrap: anywhere; }

.footer-grid h4 {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--on-dark-mute);
  margin-bottom: 1.1rem;
}
.footer-grid ul { list-style: none; margin: 0; padding: 0; }
.footer-grid li { margin-bottom: 0.6rem; }
.footer-grid a { font-size: 0.9375rem; color: var(--on-dark-mute); transition: color 0.25s var(--ease); }
.footer-grid a:hover { color: var(--bronze-lt); }
.footer-blurb { font-size: 0.9375rem; color: var(--on-dark-mute); max-width: 34ch; }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  padding-top: 2rem;
  border-top: 1px solid var(--line-dark);
  font-size: 0.8125rem;
  color: #8a8783;          /* 5.1:1 on the footer ground; #6e6c69 was 3.4:1 */
}

/* The license line names the entities that actually hold the licenses, so the
   numbers can be checked against a name that appears on the page. */
.footer-bottom .entities {
  /* basis alone still shrinks to fit beside the copyright; this forces its own row */
  /* basis alone still shrinks to fit beside the copyright, and a max-width here
     caps the used size and lets it fit again — so neither is used. */
  flex: 0 0 100%;
  width: 100%;
  margin: 0.55rem 0 0;
  color: #6f6d69;
}

/* Credit line under supplier photography, so a manufacturer's image is never
   mistaken for one of our projects. */
.cred {
  margin: 0.6rem 0 0;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-dark-mute);
}
.section--light .cred { color: var(--on-light-mute); }

/* --- Reveal on scroll ----------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }

/* --- Responsive ----------------------------------------------------------- */
@media (max-width: 950px) {
  .nav-toggle { display: block; }

  .nav {
    position: fixed;
    inset: 84px 0 auto;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: rgba(14, 14, 16, 0.98);
    backdrop-filter: blur(16px);
    border-bottom: 1px solid var(--line-dark);
    padding: 1rem var(--gutter) 2rem;
    transform: translateY(-12px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
  }
  .nav.is-open { opacity: 1; transform: none; pointer-events: auto; }
  .nav a { font-size: 1.0625rem; padding-block: 0.9rem; border-bottom: 1px solid var(--line-dark); }
  .nav a::after { display: none; }
  .nav .btn { margin-top: 1.25rem; justify-content: center; border-bottom: 0; }

  .split--reverse > *:first-child,
  .svc:nth-child(even) .svc__media { order: 0; }

  .gallery figure,
  .gallery .g-wide { grid-column: span 6; }
  .gallery .g-full { grid-column: span 12; }
}

@media (max-width: 620px) {
  .gallery figure,
  .gallery .g-wide,
  .gallery .g-full { grid-column: span 12; }
  .gallery .g-tall img { aspect-ratio: 3 / 2; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

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

/* --- Print ---------------------------------------------------------------- */
@media print {
  .site-header, .nav, .cta-band { display: none !important; }
  body { background: #fff; color: #000; }
}

/* --- Partner groups ------------------------------------------------------- */
.partner-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: clamp(2rem, 4vw, 3.25rem);
}
.partner-groups > * { min-width: 0; }

.partner-group h3 {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bronze);
  padding-bottom: 1rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--line-light);
}
.section--light .partner-group h3 { border-bottom-color: var(--line-light); }

.partner-group ul { list-style: none; margin: 0; padding: 0; }
.partner-group li { margin-bottom: 1.5rem; }
.partner-group li:last-child { margin-bottom: 0; }

.partner-group b {
  display: block;
  font-family: var(--display);
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.3rem;
}
.partner-group span {
  display: block;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--on-light-mute);
  text-wrap: pretty;
}

/* Audio is half the partner list, so it gets a row to itself. */
.partner-group--wide { margin-top: clamp(2rem, 4vw, 3.25rem); }
.partner-group--wide ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: clamp(1.75rem, 3vw, 2.5rem);
}
.partner-group--wide li { margin-bottom: 0; }

/* --- Section backdrops ---------------------------------------------------- */
/* A photograph sitting behind text, tone-mapped by tools/make-backdrop.py into
   a narrow dark band. Because the brightest pixel is already below 0.024
   luminance, no overlay is needed: the bronze eyebrow still holds 4.6:1 and the
   muted body copy 5.5:1. The picture reads as texture, not as an image. */
.has-backdrop {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  --backdrop-edge: var(--ink);
}
/* Sections that sit on the lighter ground fade to their own colour, so the
   backdrop never ends on a band darker than the section around it. */
.section--ink-2.has-backdrop,
.page-hero--plain.has-backdrop { --backdrop-edge: var(--ink-2); }

.backdrop { position: absolute; inset: 0; z-index: -2; }
.backdrop img { width: 100%; height: 100%; object-fit: cover; object-position: center; }

/* Fades the backdrop out at the edges so it never ends on a hard line. */
.has-backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to bottom, var(--backdrop-edge) 0%, transparent 22%,
                    transparent 78%, var(--backdrop-edge) 100%);
}

/* A backdrop bright enough to actually see needs lighter text on it. Bronze at
   #b08d6a caps the image at 0.026 luminance — nearly invisible. Lifting the
   eyebrow to a pale bronze and the body copy a step brighter lets the collage
   run at 0.075, about four times brighter, with everything still above 4.5:1. */
.has-backdrop .eyebrow,
.cta-band .eyebrow { color: #e0cbb0; }
.has-backdrop .lede,
.has-backdrop .svc-grid p,
.has-backdrop p:not([class]),
.cta-band .lede { color: #d2cfca; }
