/* =============================================================
   Touch Point Direct
   -------------------------------------------------------------
   Brand tokens come straight from branding/branding_guide_complete.md.
   Everything below the token block is an *interface* decision made to
   build a usable site, not an established brand rule -- the guide
   leaves visual language TBD, so these are deliberately kept in one
   place and easy to change.
   ============================================================= */

/* ---------- Fonts ---------- */
/* Two variable fonts, subset to Latin and compressed -- ~200 KB for the
   whole typographic system. Rebuild with tools/build_fonts.py after any
   change to branding/fonts. The retained weight ranges are set there, so
   widen them in that file, not here. */
@font-face {
  font-family: "Montserrat";
  src: url("../fonts/Montserrat-Variable.woff2") format("woff2-variations"),
       url("../fonts/Montserrat-Variable.woff2") format("woff2");
  font-weight: 500 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../fonts/Inter-Variable.woff2") format("woff2-variations"),
       url("../fonts/Inter-Variable.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}

/* ---------- Brand tokens (source of truth: branding guide) ---------- */
:root {
  --brand-orange-dark: #fd5901;
  --brand-orange: #f78104;
  --brand-orange-light: #faab36;
  --brand-teal-light: #249ea0;
  --brand-teal: #008083;
  --brand-teal-dark: #005f60;

  --neutral-0: #ffffff;
  --neutral-50: #f7f9f9;
  --neutral-100: #eef2f2;
  --neutral-200: #dce3e3;
  --neutral-300: #c3cdcd;
  --neutral-400: #98a6a6;
  --neutral-500: #6c7a7a;
  --neutral-600: #526060;
  --neutral-700: #394646;
  --neutral-800: #263232;
  --neutral-900: #172222;

  --font-brand: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Inter", "Helvetica Neue", Arial, sans-serif;

  /* ---------- Semantic aliases ---------- */
  --color-background: var(--neutral-50);
  --color-surface: var(--neutral-0);
  --color-text-primary: var(--neutral-900);
  --color-text-body: var(--neutral-700);
  --color-text-secondary: var(--neutral-600);
  --color-border: var(--neutral-200);
  --color-brand-primary: var(--brand-teal);
  --color-accent: var(--brand-orange);

  /* ---------- Interface scale ---------- */
  --page: 76rem;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --measure: 34rem;
  --radius: 2px;
  --header-h: 6.5rem;
  --rail: 4.5rem;

  --step--1: 0.8125rem;
  --step-0: 1.0625rem;
  --step-1: clamp(1.15rem, 1.4vw, 1.35rem);
  --step-2: clamp(1.35rem, 2vw, 1.75rem);
  --step-3: clamp(1.75rem, 3vw, 2.5rem);
  --step-4: clamp(2.1rem, 4.4vw, 3.4rem);
  --step-5: clamp(2.6rem, 7vw, 5.75rem);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);

  /* Night surfaces: neutral 900 carrying a little teal depth. */
  --night: #101a1a;
  --night-2: #162323;
  --night-line: rgba(196, 214, 214, 0.14);

  /* ---------- Page signatures ----------------------------------------
     Every page carries a pair of brand colours that run through its
     headers, washes, rules and glyphs. Two rules govern which colour
     goes where, and they are worth keeping:

       --ink   text-safe on white. Only the two darker teals clear
               4.5:1 at body size; neither orange does, so orange
               never becomes small type on a light ground.
       --glow  decoration and large display type only.

     --wash-a / --wash-b are the two auras behind dark bands, and
     --tint is the faint page wash. Change a page's mood by editing
     one block below.
     ------------------------------------------------------------------ */
  --ink: var(--brand-teal-dark);
  --glow: var(--brand-teal-light);
  --wash-a: rgba(36, 158, 160, 0.30);
  --wash-b: rgba(247, 129, 4, 0.16);
  --tint: rgba(0, 128, 131, 0.05);
  --ridge-ink: rgba(148, 208, 208, 0.30);
  --ridge-accent: #f78104;
  --glyph-ink: rgba(0, 128, 131, 0.42);
}

/* Teal page: the approach, where the three patterns live. */
body[data-page="approach"] {
  --ink: var(--brand-teal-dark);
  --glow: var(--brand-teal-light);
  --wash-a: rgba(36, 158, 160, 0.34);
  --wash-b: rgba(0, 128, 131, 0.30);
  --tint: rgba(0, 128, 131, 0.055);
}

/* Orange page: the list of services, warmest of the four. */
body[data-page="services"] {
  --ink: var(--brand-teal);
  --glow: var(--brand-orange);
  --wash-a: rgba(247, 129, 4, 0.26);
  --wash-b: rgba(36, 158, 160, 0.28);
  --tint: rgba(247, 129, 4, 0.045);
  --ridge-ink: rgba(250, 200, 150, 0.26);
  --ridge-accent: #faab36;
}

/* Amber page: the biography. Warm, but quieter than services. */
body[data-page="about"] {
  --ink: var(--brand-teal-dark);
  --glow: var(--brand-orange-light);
  --wash-a: rgba(250, 171, 54, 0.22);
  --wash-b: rgba(0, 128, 131, 0.34);
  --tint: rgba(250, 171, 54, 0.16);
  --ridge-ink: rgba(196, 214, 214, 0.24);
  --ridge-accent: #faab36;
}

/* Teal-and-ember page: contact. */
body[data-page="contact"] {
  --ink: var(--brand-teal);
  --glow: var(--brand-orange-dark);
  --wash-a: rgba(36, 158, 160, 0.36);
  --wash-b: rgba(253, 89, 1, 0.20);
  --tint: rgba(0, 128, 131, 0.05);
  --ridge-ink: rgba(148, 208, 208, 0.30);
  --ridge-accent: #fd5901;
}

@media (min-width: 1200px) {
  :root { --gutter: 5.5rem; }
}

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

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--color-background);
  color: var(--color-text-body);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.68;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-brand);
  color: var(--color-text-primary);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.022em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

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

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

.skip-link {
  position: absolute;
  left: 0.5rem;
  top: -4rem;
  z-index: 200;
  background: var(--neutral-900);
  color: #fff;
  padding: 0.7rem 1.1rem;
  font-family: var(--font-brand);
  font-size: var(--step--1);
  text-decoration: none;
  transition: top 0.2s var(--ease);
}
.skip-link:focus { top: 0.5rem; }

.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;
}

/* =============================================================
   Layout primitives
   ============================================================= */
.shell {
  width: min(100% - (var(--gutter) * 2), var(--page));
  margin-inline: auto;
}
.shell--wide { width: min(100% - (var(--gutter) * 2), 88rem); }

.section { padding-block: clamp(4.5rem, 10vw, 9rem); position: relative; }
.section--tight { padding-block: clamp(3rem, 6vw, 5.5rem); }

.section--night {
  background: var(--night);
  color: var(--neutral-300);
}
.section--night h1, .section--night h2, .section--night h3 { color: var(--neutral-0); }

.section--paper { background: var(--color-surface); }

/* The ridge rule: three hairlines instead of one. A small brand tell
   that repeats the fingerprint idea at divider scale. */
.ridge-rule {
  border: 0;
  height: 7px;
  margin: 0;
  background-image:
    linear-gradient(var(--color-border), var(--color-border)),
    linear-gradient(var(--color-border), var(--color-border)),
    linear-gradient(var(--color-border), var(--color-border));
  background-size: 100% 1px, 62% 1px, 34% 1px;
  background-position: 0 0, 0 3px, 0 6px;
  background-repeat: no-repeat;
}
.section--night .ridge-rule {
  background-image:
    linear-gradient(var(--night-line), var(--night-line)),
    linear-gradient(var(--night-line), var(--night-line)),
    linear-gradient(var(--night-line), var(--night-line));
}

/* ---------- Eyebrow / forensic label ---------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-brand);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-brand-primary);
  margin: 0 0 1.4rem;
}
.eyebrow::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--brand-orange);
  box-shadow: 0 0 0 4px rgba(247, 129, 4, 0.16);
  flex: none;
}
.section--night .eyebrow { color: var(--brand-teal-light); }

.tag {
  font-family: var(--font-brand);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.lede {
  font-size: var(--step-1);
  line-height: 1.62;
  color: var(--color-text-body);
  max-width: var(--measure);
}
.section--night .lede { color: var(--neutral-300); }

.prose { max-width: var(--measure); }
.prose p + p { margin-top: 1.15em; }
.prose strong { color: var(--color-text-primary); font-weight: 600; }
.section--night .prose strong { color: var(--neutral-0); }

/* =============================================================
   Buttons and links
   ============================================================= */
.button {
  --btn-bg: var(--brand-orange);
  --btn-fg: var(--neutral-900);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.95rem 1.6rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-brand);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.button::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--brand-orange-dark);
  transform: translateY(101%);
  transition: transform 0.45s var(--ease);
}
.button:hover { transform: translateY(-2px); box-shadow: 0 12px 28px -14px rgba(253, 89, 1, 0.75); }
.button:not(.button--ghost):hover { color: var(--neutral-900); }
.button:hover::after { transform: translateY(0); }
.button .arw { transition: transform 0.4s var(--ease); }
.button:hover .arw { transform: translateX(4px); }

.button--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--color-text-primary);
  border: 1px solid var(--color-border);
}
.button--ghost::after { background: var(--neutral-900); }
.button--ghost:hover { color: #fff; box-shadow: none; }
.section--night .button--ghost {
  --btn-fg: var(--neutral-0);
  border-color: var(--night-line);
}
.section--night .button--ghost::after { background: var(--neutral-0); }
.section--night .button--ghost:hover { color: var(--neutral-900); }

/* Underline that draws itself as a ridge stroke. */
.link {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-brand);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-brand-primary);
  text-decoration: none;
  padding-bottom: 3px;
  background-image: linear-gradient(var(--brand-orange), var(--brand-orange));
  background-size: 0% 2px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size 0.45s var(--ease), color 0.3s var(--ease);
}
.link:hover, .link:focus-visible { background-size: 100% 2px; color: var(--color-text-primary); }
.section--night .link { color: var(--brand-teal-light); }
.section--night .link:hover { color: var(--neutral-0); }
.link .arw { transition: transform 0.4s var(--ease); }
.link:hover .arw { transform: translateX(4px); }

.cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem 2rem;
  margin-top: 2.25rem;
}

/* =============================================================
   Header
   ============================================================= */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  transition: background 0.45s var(--ease), height 0.45s var(--ease),
    box-shadow 0.45s var(--ease), border-color 0.45s var(--ease);
  border-bottom: 1px solid transparent;
}
.site-header.is-scrolled {
  height: 5rem;
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom-color: var(--color-border);
}
/* Over a dark section the bar goes dark too, rather than turning into a
   murky translucent white. */
body.is-night-top .site-header { color: var(--neutral-0); }
body.is-night-top .site-header.is-scrolled {
  background: rgba(16, 26, 26, 0.82);
  border-bottom-color: var(--night-line);
}

.header-inner {
  width: min(100% - (var(--gutter) * 2), 88rem);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

/* The colour logo is only ever shown on a light ground, per the brand
   guide. Over the dark hero it keeps its own white plate, which then
   dissolves into the white header bar once the page is scrolled. */
.logo {
  display: block;
  line-height: 0;
  text-decoration: none;
  padding: 0.9rem 1.35rem;
  margin-left: -1.35rem;
  background: transparent;
  border-radius: var(--radius);
  transition: background 0.45s var(--ease), padding 0.45s var(--ease),
    box-shadow 0.45s var(--ease);
}
.logo img {
  height: clamp(2.2rem, 3.3vw, 3.05rem);
  width: auto;
  transition: height 0.45s var(--ease);
}
.site-header.is-scrolled .logo img { height: 2.15rem; }
.site-header.is-scrolled .logo { padding-block: 0.6rem; }
body.is-night-top .site-header .logo {
  background: var(--neutral-0);
  box-shadow: 0 14px 38px -20px rgba(0, 0, 0, 0.8);
}

/* The mark is the loudest thing in the bar, so the nav steps back a
   little to let it lead. */
@media (max-width: 640px) {
  .logo img { height: 1.95rem; }
  .site-header.is-scrolled .logo img { height: 1.7rem; }
  .logo { padding-inline: 0.9rem; margin-left: -0.9rem; }
}

/* The landing page is where the brand introduces itself, so the mark is
   carried a size larger there and the bar grows to hold it. Every other
   page keeps the size above. */
body[data-page="home"] { --header-h: 7rem; }
body[data-page="home"] .logo img { height: clamp(2.5rem, 3.9vw, 3.6rem); }
body[data-page="home"] .site-header.is-scrolled .logo img { height: 2.4rem; }

@media (max-width: 640px) {
  body[data-page="home"] .logo img { height: 2.2rem; }
  body[data-page="home"] .site-header.is-scrolled .logo img { height: 1.9rem; }
}

.site-nav ul {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 2.4vw, 2.4rem);
  list-style: none;
  margin: 0;
  padding: 0;
}
.site-nav a {
  position: relative;
  font-family: var(--font-brand);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.4rem 0;
  color: inherit;
  opacity: 0.82;
  transition: opacity 0.3s var(--ease);
}
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--brand-orange);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s var(--ease);
}
.site-nav a:hover { opacity: 1; }
.site-nav a:hover::after { transform: scaleX(1); }
.site-nav a[aria-current="page"] { opacity: 1; }
.site-nav a[aria-current="page"]::after { transform: scaleX(1); }

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.6rem;
  background: none;
  border: 1px solid currentColor;
  border-radius: var(--radius);
  color: inherit;
  font-family: var(--font-brand);
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.6rem 0.9rem;
  cursor: pointer;
}
.nav-toggle .bars { position: relative; width: 16px; height: 9px; }
.nav-toggle .bars::before,
.nav-toggle .bars::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 1.5px;
  background: currentColor;
  transition: transform 0.4s var(--ease);
}
.nav-toggle .bars::before { top: 0; }
.nav-toggle .bars::after { bottom: 0; }
.nav-toggle[aria-expanded="true"] .bars::before { transform: translateY(3.75px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .bars::after { transform: translateY(-3.75px) rotate(-45deg); }

@media (max-width: 860px) {
  .nav-toggle { display: inline-flex; }
  .site-nav {
    position: fixed;
    inset: 0;
    background: var(--night);
    color: var(--neutral-0);
    display: grid;
    place-items: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.4s var(--ease), visibility 0.4s;
  }
  .site-nav.is-open { opacity: 1; visibility: visible; }
  .site-nav ul { flex-direction: column; gap: 1.75rem; text-align: center; }
  .site-nav a { font-size: 1.35rem; letter-spacing: 0.04em; }
  .site-nav.is-open li {
    animation: navIn 0.5s var(--ease) backwards;
  }
  .site-nav.is-open li:nth-child(1) { animation-delay: 0.06s; }
  .site-nav.is-open li:nth-child(2) { animation-delay: 0.12s; }
  .site-nav.is-open li:nth-child(3) { animation-delay: 0.18s; }
  .site-nav.is-open li:nth-child(4) { animation-delay: 0.24s; }
}
@keyframes navIn {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

/* ---------- Seasonal banner ---------- */
.banner {
  position: relative;
  z-index: 90;
  margin-top: var(--header-h);
  background: var(--brand-teal-dark);
  color: #fff;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 1.25rem;
  padding: 0.8rem var(--gutter);
  font-size: 0.9375rem;
  text-align: center;
}
.banner p { margin: 0; }
.banner a { color: var(--brand-orange-light); font-weight: 600; }
body:has(.banner) main { --header-offset: 0; }

/* =============================================================
   Hero
   ============================================================= */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  background: var(--night);
  color: var(--neutral-300);
  overflow: hidden;
  padding-block: calc(var(--header-h) + 3rem) clamp(5rem, 12vh, 9rem);
}

/* Depth behind the ridges: a soft teal aurora and an orange ember,
   both sitting well below text contrast. */
.hero::before {
  content: "";
  position: absolute;
  inset: -20% -10%;
  background:
    radial-gradient(46% 52% at 78% 26%, rgba(36, 158, 160, 0.30), transparent 68%),
    radial-gradient(38% 46% at 22% 88%, rgba(247, 129, 4, 0.16), transparent 70%);
  pointer-events: none;
}
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(16, 26, 26, 0.1) 55%, var(--night) 100%);
  pointer-events: none;
}

.ridge-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

.hero-inner {
  position: relative;
  z-index: 2;
  width: min(100% - (var(--gutter) * 2), 88rem);
  margin-inline: auto;
}

.hero-copy { max-width: 46rem; }

.hero h1 {
  font-size: var(--step-5);
  letter-spacing: -0.035em;
  line-height: 0.98;
  color: var(--neutral-0);
  margin-bottom: 1.6rem;
}
.hero h1 .lift {
  display: block;
  overflow: hidden;
  /* Padding keeps the ridge underline inside the clip box. */
  padding-bottom: 0.16em;
  margin-bottom: -0.16em;
}
.hero h1 .lift > span {
  display: block;
  transform: translateY(105%);
  animation: lift 1.05s var(--ease) forwards;
}
.hero h1 .lift:nth-child(2) > span { animation-delay: 0.09s; }
.hero h1 .lift:nth-child(3) > span { animation-delay: 0.18s; }
@keyframes lift { to { transform: none; } }

/* The last word carries a hand-drawn ridge underline. */
.hero h1 .marked { position: relative; white-space: nowrap; }
.hero h1 .marked svg {
  position: absolute;
  left: 0; right: 0;
  bottom: -0.13em;
  width: 100%;
  height: 0.2em;
  overflow: visible;
}
.hero h1 .marked path {
  fill: none;
  stroke: var(--brand-orange);
  /* Constant stroke width, so the non-uniform scale cannot fatten it. */
  vector-effect: non-scaling-stroke;
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: draw 1.1s var(--ease) 0.75s forwards;
}
@keyframes draw { to { stroke-dashoffset: 0; } }

.hero .lede {
  color: var(--neutral-300);
  max-width: 33rem;
  opacity: 0;
  animation: fadeUp 0.9s var(--ease) 0.55s forwards;
}
.hero .eyebrow,
.hero .cta-row {
  opacity: 0;
  animation: fadeUp 0.9s var(--ease) forwards;
}
.hero .eyebrow { animation-delay: 0.15s; }
.hero .cta-row { animation-delay: 0.7s; }
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

/* Interaction hint + scroll cue along the bottom of the hero. */
.hero-foot {
  position: absolute;
  left: 0; right: 0;
  bottom: clamp(1.5rem, 3vh, 2.5rem);
  z-index: 3;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  width: min(100% - (var(--gutter) * 2), 88rem);
  margin-inline: auto;
  pointer-events: none;
}
.hero-hint {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--neutral-400);
  opacity: 0;
  animation: fadeUp 1s var(--ease) 1.6s forwards;
}
.hero-hint .dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--brand-orange);
  flex: none;
  animation: ping 2.6s ease-out infinite;
}
@keyframes ping {
  0% { box-shadow: 0 0 0 0 rgba(247, 129, 4, 0.5); }
  70%, 100% { box-shadow: 0 0 0 14px rgba(247, 129, 4, 0); }
}

.scroll-cue {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--font-brand);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--neutral-400);
  opacity: 0;
  animation: fadeUp 1s var(--ease) 1.75s forwards;
}
.scroll-cue .track {
  width: 1px;
  height: 46px;
  background: var(--night-line);
  position: relative;
  overflow: hidden;
}
.scroll-cue .track::after {
  content: "";
  position: absolute;
  inset: 0 auto auto 0;
  width: 1px; height: 40%;
  background: var(--brand-orange);
  animation: cue 2.2s var(--ease-in-out) infinite;
}
@keyframes cue {
  0% { transform: translateY(-110%); }
  60%, 100% { transform: translateY(260%); }
}

@media (max-width: 760px) {
  .hero::after {
    background: linear-gradient(
      to bottom,
      rgba(16, 26, 26, 0.55) 0%,
      rgba(16, 26, 26, 0.72) 45%,
      var(--night) 100%
    );
  }
}

@media (max-width: 700px) {
  .hero-foot { justify-content: center; }
  .hero-hint { display: none; }
}

/* =============================================================
   The spine — a page-length ridge with a node per section
   ============================================================= */
.spine {
  position: fixed;
  left: 1.75rem;
  top: 50%;
  transform: translateY(-50%);
  z-index: 60;
  display: grid;
  gap: 1.1rem;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s var(--ease), visibility 0.5s;
  pointer-events: none;
}
.spine.is-live { opacity: 1; visibility: visible; pointer-events: auto; }
.spine a {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.85rem;
  text-decoration: none;
  color: var(--color-text-secondary);
}
.spine .node {
  position: relative;
  width: 9px; height: 9px;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--neutral-400);
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease),
    transform 0.4s var(--ease);
}
.spine .node::after {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(100% + 1px);
  width: 1px;
  height: 1.1rem;
  background: var(--neutral-300);
  transform: translateX(-50%);
}
.spine a:last-child .node::after { display: none; }
.spine .label {
  font-family: var(--font-brand);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
.spine:hover .label { opacity: 1; transform: none; }
.spine a.is-active .node {
  background: var(--brand-orange);
  border-color: var(--brand-orange);
  transform: scale(1.35);
}
.spine a.is-active .label { color: var(--color-text-primary); }
.spine a:hover .node { border-color: var(--brand-orange); }

body.is-night-top .spine a { color: var(--neutral-400); }
body.is-night-top .spine .node { border-color: var(--neutral-500); }
body.is-night-top .spine .node::after { background: rgba(196, 214, 214, 0.25); }
body.is-night-top .spine a.is-active .label { color: var(--neutral-0); }

@media (max-width: 1180px) { .spine { display: none; } }

/* Thin scroll progress line under the header. */
.progress {
  position: fixed;
  inset: 0 0 auto;
  height: 2px;
  z-index: 110;
  background: linear-gradient(90deg, var(--brand-teal-dark), var(--brand-teal), var(--brand-orange));
  transform-origin: left;
  transform: scaleX(0);
}

/* =============================================================
   Reveals
   ============================================================= */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.reveal.is-visible { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: 0.09s; }
.reveal[data-delay="2"] { transition-delay: 0.18s; }
.reveal[data-delay="3"] { transition-delay: 0.27s; }

/* Words that rise line by line as the block enters view. */
.rise > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.85s var(--ease), transform 0.85s var(--ease);
}
.rise.is-visible > * { opacity: 1; transform: none; }
.rise.is-visible > *:nth-child(2) { transition-delay: 0.08s; }
.rise.is-visible > *:nth-child(3) { transition-delay: 0.16s; }
.rise.is-visible > *:nth-child(4) { transition-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .rise > * { opacity: 1; transform: none; }
  .hero h1 .lift > span { transform: none; animation: none; }
  .hero .lede, .hero .eyebrow, .hero .cta-row,
  .hero-hint, .scroll-cue { opacity: 1; animation: none; }
  .hero h1 .marked path { stroke-dashoffset: 0; animation: none; }
}

/* =============================================================
   Editorial split
   ============================================================= */
.split {
  display: grid;
  gap: clamp(2rem, 5vw, 5rem);
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  align-items: start;
}
.split--even { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 900px) { .split, .split--even { grid-template-columns: 1fr; } }

.split h2 { font-size: var(--step-4); }
.section-head { max-width: 44rem; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.section-head h2 { font-size: var(--step-4); margin-bottom: 1.1rem; }
.section-head p { color: var(--color-text-secondary); max-width: var(--measure); }
.section--night .section-head p { color: var(--neutral-400); }

/* -------------------------------------------------------------------
   Interior page header (app/templates/_page_head.html)

   A dark band per page, lit by that page's two signature washes, with
   a live ridge field over it and the page name set huge and hollow
   behind the type. The 3px seam at the bottom is the page's colour.
   ------------------------------------------------------------------- */
.page-head {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--night);
  color: var(--neutral-300);
  padding-block: calc(var(--header-h) + clamp(4rem, 9vw, 8rem)) clamp(4rem, 8vw, 6.5rem);
}
.page-head::before {
  content: "";
  position: absolute;
  inset: -30% -12%;
  z-index: -2;
  background:
    radial-gradient(44% 52% at 76% 22%, var(--wash-a), transparent 68%),
    radial-gradient(40% 48% at 12% 92%, var(--wash-b), transparent 72%);
  pointer-events: none;
}
.page-head::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 3px;
  background: linear-gradient(
    to right,
    var(--glow) 0%,
    var(--ink) 38%,
    rgba(196, 214, 214, 0.12) 78%,
    transparent 100%
  );
  pointer-events: none;
}
.page-head .shell { position: relative; z-index: 2; }
.page-head h1 { font-size: var(--step-5); letter-spacing: -0.03em; margin-bottom: 1.4rem; }
.page-head .lede { max-width: 40rem; }
.page-head .ridge-canvas {
  z-index: -1;
  opacity: 0.85;
  -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent 97%);
  mask-image: linear-gradient(to bottom, #000 40%, transparent 97%);
}

/* The page's own name, cut out of the dark rather than printed on it. */
.page-head__ghost {
  position: absolute;
  z-index: -1;
  right: -0.05em;
  bottom: -0.3em;
  margin: 0;
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: clamp(3.5rem, 12.5vw, 11.5rem);
  line-height: 0.78;
  letter-spacing: -0.045em;
  white-space: nowrap;
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(196, 214, 214, 0.15);
  text-stroke: 1.5px rgba(196, 214, 214, 0.15);
  user-select: none;
  pointer-events: none;
  animation: ghost-drift 22s var(--ease-in-out) infinite alternate;
}
@keyframes ghost-drift {
  from { transform: translateX(0); }
  to { transform: translateX(-2.5%); }
}
@media (prefers-reduced-motion: reduce) {
  .page-head__ghost { animation: none; }
}

/* =============================================================
   Touchpoint cards — each carries a live fingerprint pattern
   ============================================================= */
.touchpoints {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  counter-reset: tp;
}
@media (max-width: 900px) { .touchpoints { grid-template-columns: 1fr; } }

.touchpoint {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: clamp(1.75rem, 2.6vw, 2.5rem);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform 0.6s var(--ease), box-shadow 0.6s var(--ease),
    border-color 0.6s var(--ease);
}
.touchpoint::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 3px;
  background: var(--brand-orange);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.6s var(--ease);
}
.touchpoint:hover {
  transform: translateY(-6px);
  border-color: var(--neutral-300);
  box-shadow: 0 26px 50px -34px rgba(23, 34, 34, 0.5);
}
.touchpoint:hover::before { transform: scaleX(1); }

.section--night .touchpoint {
  background: var(--night-2);
  border-color: var(--night-line);
}
.section--night .touchpoint:hover { border-color: rgba(36, 158, 160, 0.5); }

.touchpoint .glyph {
  position: relative;
  width: clamp(5.5rem, 7.5vw, 7.25rem);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
}
.touchpoint .glyph canvas { position: absolute; inset: 0; }

.touchpoint .tp-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
}
.touchpoint .idx {
  font-family: var(--font-brand);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--color-text-secondary);
}
.touchpoint h3 { font-size: var(--step-2); }
.touchpoint .summary {
  font-weight: 500;
  color: var(--color-text-primary);
  margin-bottom: 0.5em;
}
.section--night .touchpoint .summary { color: var(--neutral-0); }
.touchpoint .body { color: var(--color-text-secondary); font-size: 0.9875rem; }
.section--night .touchpoint .body { color: var(--neutral-400); }
/* Large stacked version used on the Approach page. */
.tp-row {
  display: grid;
  grid-template-columns: clamp(9rem, 16vw, 15rem) minmax(0, 1fr);
  gap: clamp(1.75rem, 5vw, 4.5rem);
  align-items: center;
  padding-block: clamp(3rem, 6vw, 5rem);
  border-top: 1px solid var(--color-border);
}
.tp-row:last-of-type { border-bottom: 1px solid var(--color-border); }
.tp-row .glyph {
  position: relative;
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
}
.tp-row .glyph canvas { position: absolute; inset: 0; }
.tp-row .glyph-caption {
  margin-top: 1rem;
  font-family: var(--font-brand);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.7;
  color: var(--color-text-secondary);
}
.tp-row h2 {
  font-size: var(--step-4);
  margin-bottom: 0.6rem;
}
.tp-row .summary {
  font-size: var(--step-1);
  color: var(--color-text-primary);
  font-weight: 500;
  margin-bottom: 0.9rem;
  max-width: var(--measure);
}
.tp-row .body { max-width: var(--measure); color: var(--color-text-body); }
.tp-row .meta {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.2rem;
}
.tp-row .meta .num {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.16em;
  color: var(--brand-teal-dark);
}
.tp-row .meta .rule { flex: 1; height: 1px; background: var(--color-border); max-width: 5rem; }
@media (max-width: 780px) {
  .tp-row { grid-template-columns: 1fr; }
  .tp-row .glyph { width: 9rem; }
}

/* =============================================================
   Services — index list against a live ridge map
   ============================================================= */
.service-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
@media (max-width: 980px) { .service-layout { grid-template-columns: 1fr; } }

.service-map {
  position: sticky;
  top: calc(var(--header-h) + 2rem);
}
.service-map .plate {
  position: relative;
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}
.service-map canvas { position: absolute; inset: 0; }
.service-map .pin {
  position: absolute;
  top: 0; left: 0;
  width: 14px; height: 14px;
  margin: -7px 0 0 -7px;
  border-radius: 50%;
  background: var(--brand-orange);
  box-shadow: 0 0 0 4px rgba(247, 129, 4, 0.2), 0 0 22px 4px rgba(247, 129, 4, 0.35);
  transition: transform 0.75s var(--ease), opacity 0.4s var(--ease);
  opacity: 0;
  pointer-events: none;
}
.service-map.is-active .pin { opacity: 1; }
.service-map .caption {
  margin-top: 1.5rem;
  font-size: 0.875rem;
  color: var(--color-text-secondary);
  max-width: 22rem;
}
.service-map .readout {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-primary);
  min-height: 1.4em;
  margin-bottom: 0.5rem;
}
@media (max-width: 980px) { .service-map { display: none; } }

.service-list { list-style: none; margin: 0; padding: 0; counter-reset: svc; }
.service-item {
  position: relative;
  border-top: 1px solid var(--color-border);
  padding: clamp(1.5rem, 2.6vw, 2.25rem) clamp(0.5rem, 1.5vw, 1.25rem);
  transition: background 0.5s var(--ease), padding-left 0.5s var(--ease);
}
.service-item:last-child { border-bottom: 1px solid var(--color-border); }
.service-item::before {
  content: "";
  position: absolute;
  left: 0; top: -1px; bottom: -1px;
  width: 2px;
  background: var(--brand-orange);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.55s var(--ease);
}
.service-item:hover, .service-item:focus-within {
  background: var(--color-surface);
  padding-left: clamp(1.25rem, 2.5vw, 2rem);
}
.service-item:hover::before, .service-item:focus-within::before { transform: scaleY(1); }
.service-item .row {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  gap: 1rem;
  align-items: baseline;
}
.service-item .num {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  color: var(--color-text-secondary);
  transition: color 0.4s var(--ease);
}
.service-item:hover .num { color: var(--brand-teal-dark); }
.service-item h3 { font-size: var(--step-2); font-weight: 600; letter-spacing: -0.01em; }
.service-item p {
  margin: 0.7rem 0 0;
  color: var(--color-text-secondary);
  max-width: var(--measure);
  font-size: 0.9875rem;
}

/* Compact list used on the home page. */
.service-index {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--color-border);
}
@media (max-width: 720px) { .service-index { grid-template-columns: 1fr; } }
.service-index li { border-bottom: 1px solid var(--color-border); }
.service-index a {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 1.1rem 0.5rem;
  text-decoration: none;
  font-family: var(--font-brand);
  font-weight: 500;
  color: var(--color-text-primary);
  transition: color 0.35s var(--ease), transform 0.5s var(--ease), padding 0.5s var(--ease);
}
.service-index a:hover { color: var(--brand-teal); padding-left: 1.25rem; }
.service-index .n {
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  color: var(--color-text-secondary);
  font-weight: 700;
}

/* =============================================================
   Portrait — an evidence plate, with a pin like the logo's
   ============================================================= */
.portrait {
  position: relative;
  margin: 0;
  max-width: 26rem;
}
.portrait .frame {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--neutral-100);
  border-radius: var(--radius);
}
.portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.02);
  transition: transform 1.2s var(--ease), filter 1.2s var(--ease);
}
.portrait:hover img { transform: scale(1.06); }
/* Ridge etching laid over the photo, teal side only, kept faint. */
.portrait .etch {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  mix-blend-mode: multiply;
  opacity: 0.1;
  -webkit-mask-image: linear-gradient(to top, #000 0%, transparent 62%);
  mask-image: linear-gradient(to top, #000 0%, transparent 62%);
  pointer-events: none;
}
.portrait .corner {
  position: absolute;
  width: 26px; height: 26px;
  border: 2px solid var(--brand-orange);
  pointer-events: none;
}
.portrait .corner.tl { top: -1px; left: -1px; border-right: 0; border-bottom: 0; }
.portrait .corner.br { bottom: -1px; right: -1px; border-left: 0; border-top: 0; }
.portrait figcaption {
  margin-top: 1.1rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-brand);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.portrait figcaption::before {
  content: "";
  width: 1.75rem; height: 1px;
  background: var(--brand-orange);
}

/* =============================================================
   Stat / number display
   ============================================================= */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}
.stat { border-top: 2px solid var(--neutral-900); padding-top: 1.1rem; }
.section--night .stat { border-top-color: var(--brand-teal-light); }
.stat .value {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: var(--step-3);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--color-text-primary);
  display: block;
  margin-bottom: 0.4rem;
}
.section--night .stat .value { color: var(--neutral-0); }
.stat .label {
  font-size: 0.875rem;
  color: var(--color-text-secondary);
  display: block;
}
.section--night .stat .label { color: var(--neutral-400); }

/* =============================================================
   Quote / pull statement
   ============================================================= */
.pull {
  margin: 0;
  max-width: 52rem;
}
.pull blockquote {
  margin: 0;
  font-family: var(--font-brand);
  font-weight: 600;
  font-size: var(--step-3);
  line-height: 1.22;
  letter-spacing: -0.025em;
  color: var(--color-text-primary);
}
.section--night .pull blockquote { color: var(--neutral-0); }
.pull .attrib {
  margin-top: 1.5rem;
  font-size: 0.875rem;
  letter-spacing: 0.05em;
  color: var(--color-text-secondary);
}

/* =============================================================
   Contact
   ============================================================= */
.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
  margin-top: clamp(2rem, 4vw, 3rem);
}
.contact-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  text-decoration: none;
  overflow: hidden;
  transition: transform 0.6s var(--ease), box-shadow 0.6s var(--ease), border-color 0.6s var(--ease);
}
.contact-card::after {
  content: "";
  position: absolute;
  right: -30%;
  bottom: -60%;
  width: 70%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(0, 128, 131, 0.07), transparent 70%);
  transition: transform 0.8s var(--ease);
}
.contact-card:hover {
  transform: translateY(-5px);
  border-color: var(--neutral-300);
  box-shadow: 0 26px 50px -34px rgba(23, 34, 34, 0.45);
}
.contact-card:hover::after { transform: scale(1.5); }
.contact-card .tag { color: var(--color-brand-primary); }
.contact-card .value {
  font-family: var(--font-brand);
  font-weight: 600;
  font-size: var(--step-2);
  letter-spacing: -0.02em;
  color: var(--color-text-primary);
  word-break: break-word;
}
.contact-card .note { font-size: 0.9375rem; color: var(--color-text-secondary); }

/* Contact form (off by default; enable in content/contact.yaml) */
.form { max-width: 34rem; margin-top: clamp(2rem, 4vw, 3rem); display: grid; gap: 1.25rem; }
.field { display: grid; gap: 0.45rem; }
.field label {
  font-family: var(--font-brand);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.field input, .field textarea {
  font-family: var(--font-body);
  font-size: var(--step-0);
  color: var(--color-text-primary);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.85rem 1rem;
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--brand-teal);
  box-shadow: 0 0 0 3px rgba(0, 128, 131, 0.14);
}
.field textarea { min-height: 9rem; resize: vertical; }
.form .hp { position: absolute; left: -9999px; }
.form-status { font-size: 0.9375rem; min-height: 1.5em; }
.form-status[data-state="ok"] { color: var(--brand-teal-dark); }
.form-status[data-state="error"] { color: var(--brand-orange-dark); }

.steps {
  list-style: none;
  margin: clamp(3rem, 6vw, 4.5rem) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  counter-reset: step;
}
.steps li {
  counter-increment: step;
  border-top: 1px solid var(--color-border);
  padding-top: 1.1rem;
}
.steps li::before {
  content: "0" counter(step);
  display: block;
  font-family: var(--font-brand);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--brand-teal-dark);
  margin-bottom: 0.6rem;
}
.steps h3 {
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.45rem;
}
.steps p { font-size: 0.9375rem; color: var(--color-text-secondary); }

/* =============================================================
   Closing band
   ============================================================= */
.close-band { position: relative; overflow: hidden; text-align: left; }
.close-band .close-mark {
  position: absolute;
  right: -6%;
  top: 50%;
  transform: translateY(-50%);
  width: min(52%, 40rem);
  opacity: 0.14;
  pointer-events: none;
}
.close-band h2 { font-size: var(--step-4); max-width: 20ch; margin-bottom: 1.25rem; }
.close-band p { max-width: var(--measure); }
@media (max-width: 820px) { .close-band .close-mark { opacity: 0.08; width: 90%; right: -20%; } }

/* =============================================================
   Footer
   ============================================================= */
.site-footer {
  background: var(--neutral-900);
  color: var(--neutral-400);
  padding-block: clamp(3.5rem, 7vw, 5.5rem) 2.5rem;
}
.footer-inner {
  width: min(100% - (var(--gutter) * 2), var(--page));
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 0.8fr));
  gap: clamp(2rem, 5vw, 4rem);
}
@media (max-width: 820px) { .footer-inner { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-inner { grid-template-columns: 1fr; } }

.footer-mark { width: 3.25rem; margin-bottom: 1.25rem; opacity: 0.9; }
.footer-name {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: 0.02em;
  color: var(--neutral-0);
  margin-bottom: 0.3rem;
}
.footer-tagline {
  font-family: var(--font-brand);
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-teal-light);
  margin-bottom: 1.1rem;
}
.footer-blurb { font-size: 0.9375rem; max-width: 26rem; }
.footer-heading {
  font-family: var(--font-brand);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--neutral-0);
  margin-bottom: 1rem;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.site-footer a {
  color: var(--neutral-300);
  text-decoration: none;
  font-size: 0.9375rem;
  transition: color 0.3s var(--ease);
}
.site-footer a:hover { color: var(--brand-orange-light); }
.site-footer p { margin-bottom: 0.5rem; font-size: 0.9375rem; }
.footer-bottom {
  width: min(100% - (var(--gutter) * 2), var(--page));
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(196, 214, 214, 0.14);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
  font-size: 0.8125rem;
  color: var(--neutral-500);
}

/* =============================================================
   404
   ============================================================= */
.notfound {
  min-height: 72svh;
  display: grid;
  place-items: center;
  text-align: center;
  padding-block: calc(var(--header-h) + 4rem) 5rem;
}
.notfound h1 { font-size: var(--step-4); margin-bottom: 1rem; }
.notfound p { color: var(--color-text-secondary); margin-bottom: 2rem; }

/* =============================================================
   Colour — the interior pages

   The home page carries its drama in the hero. These rules give the
   other four the same weight: tinted grounds instead of flat white,
   a signature colour per page (see "Page signatures" at the top of
   this file), and bands that move between light and dark down the
   page rather than sitting in one register.

   Contrast rule of thumb, again: the teals are safe for text, the
   oranges are for graphics and for display type of 24px and up.
   ============================================================= */

/* ---------- Tinted grounds ---------- */
.section--wash {
  background:
    linear-gradient(180deg, var(--tint), rgba(255, 255, 255, 0) 62%),
    var(--color-surface);
}
.section--warm {
  background:
    radial-gradient(64% 58% at 92% -4%, var(--tint), transparent 64%),
    radial-gradient(52% 46% at 2% 96%, rgba(0, 128, 131, 0.07), transparent 66%),
    linear-gradient(180deg, var(--color-surface), var(--color-background));
}

/* ---------- The approach: three bands, light to dark -------------
   Connect on paper, Interact on a wash, Engage on night. The colours
   cycle every three, so a fourth touch point starts the run again.
   ---------------------------------------------------------------- */
.tp-bands { position: relative; }

.tp-band {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding-block: clamp(1rem, 2vw, 2rem);
}
/* A colour bleeding down the left edge, tying the bands together. */
.tp-band::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: linear-gradient(to bottom, var(--band-ink), transparent 88%);
  pointer-events: none;
}

.tp-band--light {
  --band-ink: var(--brand-teal-light);
  --glyph-ink: rgba(0, 128, 131, 0.44);
  background: var(--color-surface);
}
.tp-band--wash {
  --band-ink: var(--brand-teal);
  --glyph-ink: rgba(0, 95, 96, 0.5);
  background:
    radial-gradient(64% 70% at 6% 50%, rgba(0, 128, 131, 0.09), transparent 62%),
    linear-gradient(180deg, #eef5f5, #f4f9f9);
}
.tp-band--night {
  --band-ink: var(--brand-orange);
  --glyph-ink: rgba(148, 208, 208, 0.46);
  background: var(--night);
  color: var(--neutral-300);
}
.tp-band--night::after {
  content: "";
  position: absolute;
  inset: -25% -10%;
  z-index: -1;
  background:
    radial-gradient(40% 55% at 18% 30%, rgba(36, 158, 160, 0.26), transparent 68%),
    radial-gradient(34% 44% at 88% 88%, rgba(247, 129, 4, 0.14), transparent 70%);
  pointer-events: none;
}

/* The bands do the dividing now, so the row keeps no rules of its own. */
.tp-band .tp-row,
.tp-band .tp-row:last-of-type { border: 0; }

.tp-plate { position: relative; }
/* A soft ring of the band's colour sits behind each print. */
.tp-band .tp-row .glyph {
  background: transparent;
  border-color: transparent;
  box-shadow:
    inset 0 0 0 1px var(--glyph-ring, rgba(0, 128, 131, 0.18)),
    0 0 60px -12px var(--glyph-glow, rgba(0, 128, 131, 0.35));
  transition: box-shadow 0.7s var(--ease);
}
.tp-band--light .tp-row .glyph { --glyph-glow: rgba(36, 158, 160, 0.35); }
.tp-band--wash .tp-row .glyph {
  --glyph-ring: rgba(0, 95, 96, 0.22);
  --glyph-glow: rgba(0, 128, 131, 0.32);
}
.tp-band--night .tp-row .glyph {
  --glyph-ring: rgba(196, 214, 214, 0.16);
  --glyph-glow: rgba(36, 158, 160, 0.4);
}
.tp-row:hover .glyph { box-shadow: inset 0 0 0 1px var(--glyph-ring, rgba(0, 128, 131, 0.3)), 0 0 90px -8px var(--glyph-glow, rgba(0, 128, 131, 0.5)); }

.tp-band .tp-row .meta .num { color: var(--ink); }
.tp-band--night .tp-row .meta .num { color: var(--brand-teal-light); }
.tp-band--night .tp-row .meta .rule { background: var(--night-line); }
.tp-band--night .tp-row .summary { color: var(--neutral-0); }
.tp-band--night .tp-row .body { color: var(--neutral-400); }
.tp-band--night .tp-row .glyph-caption { color: var(--neutral-400); }

/* ---------- Services: a teal-to-orange ramp down the list --------
   Each row's --i is its position, --n the last index, both set in
   services.html. The ramp is what tints the numeral, the edge bar,
   the hover wash, and the pin on the plate.
   ---------------------------------------------------------------- */
.service-item {
  /* --ramp walks the six brand colours in guide order, cool to warm, so
     pointing down the list carries the whole palette across the plate.
     They are named rather than interpolated: mixing teal into orange
     passes through mud, and these are the actual brand values. */
  --ramp: var(--brand-teal-dark);
  /* The numeral is type, so it walks only the two teals that clear
     4.5:1 on a light ground at any size. The warm end of the palette
     stays on the bar, the wash and the plate, which carry no text. */
  --ramp-ink: color-mix(
    in oklab,
    var(--brand-teal-dark),
    var(--brand-teal) calc(var(--i, 0) / var(--n, 1) * 100%)
  );
  border-top-color: rgba(0, 128, 131, 0.14);
}
.service-item:nth-child(6n + 1) { --ramp: var(--brand-teal-dark); }
.service-item:nth-child(6n + 2) { --ramp: var(--brand-teal); }
.service-item:nth-child(6n + 3) { --ramp: var(--brand-teal-light); }
.service-item:nth-child(6n + 4) { --ramp: var(--brand-orange-light); }
.service-item:nth-child(6n + 5) { --ramp: var(--brand-orange); }
.service-item:nth-child(6n + 6) { --ramp: var(--brand-orange-dark); }
.service-item:last-child { border-bottom-color: rgba(0, 128, 131, 0.14); }
.service-item::before { background: var(--ramp); width: 3px; }
.service-item:hover, .service-item:focus-within {
  background: linear-gradient(
    to right,
    color-mix(in srgb, var(--ramp) 9%, transparent),
    transparent 60%
  );
}
/* Set as display type so the warm end of the ramp stays legible. */
.service-item .row { grid-template-columns: 4.5rem minmax(0, 1fr); }
.service-item .num {
  font-size: clamp(1.6rem, 2.5vw, 2.3rem);
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--ramp-ink, var(--brand-teal-dark));
  opacity: 0.8;
  transition: opacity 0.4s var(--ease), transform 0.5s var(--ease);
}
.service-item:hover .num,
.service-item:focus-within .num {
  opacity: 1;
  transform: translateX(2px);
}
@media (max-width: 560px) {
  .service-item .row { grid-template-columns: 3.25rem minmax(0, 1fr); }
  .service-item .num { font-size: 1.5rem; }
}

/* The plate takes the colour of whatever service you are pointing at. */
.service-map { --map-accent: var(--brand-orange); }
.service-map .plate {
  background:
    radial-gradient(70% 70% at 50% 45%, rgba(0, 128, 131, 0.05), transparent 70%),
    var(--color-surface);
  border-color: rgba(0, 128, 131, 0.18);
  box-shadow: 0 0 0 0 transparent;
  transition: box-shadow 0.7s var(--ease), border-color 0.7s var(--ease);
}
.service-map.is-active .plate {
  border-color: color-mix(in srgb, var(--map-accent) 40%, transparent);
  box-shadow:
    0 0 0 6px color-mix(in srgb, var(--map-accent) 10%, transparent),
    0 34px 70px -40px var(--map-accent);
}
.service-map .halo {
  position: absolute;
  inset: 9%;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--map-accent) 45%, transparent);
  opacity: 0;
  transform: scale(0.88);
  transition: opacity 0.5s var(--ease), transform 0.8s var(--ease);
  pointer-events: none;
}
.service-map.is-active .halo { opacity: 1; transform: scale(1); }
.service-map .pin {
  background: var(--map-accent);
  box-shadow:
    0 0 0 4px color-mix(in srgb, var(--map-accent) 22%, transparent),
    0 0 26px 5px color-mix(in srgb, var(--map-accent) 40%, transparent);
}
.service-map.is-active .readout { color: var(--ink); }
.service-map .readout { transition: color 0.4s var(--ease); }

/* ---------- About: the portrait on a lit plate ---------- */
.portrait-stage {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--night);
  padding: clamp(1rem, 2.4vw, 1.75rem);
}
.portrait-stage::before {
  content: "";
  position: absolute;
  inset: -30% -20%;
  z-index: -2;
  background:
    radial-gradient(46% 52% at 82% 12%, var(--wash-a), transparent 68%),
    radial-gradient(42% 50% at 6% 94%, var(--wash-b), transparent 72%);
  pointer-events: none;
}
.portrait-stage .ridge-canvas {
  z-index: -1;
  opacity: 0.7;
  -webkit-mask-image: radial-gradient(72% 72% at 50% 50%, transparent 40%, #000 82%);
  mask-image: radial-gradient(72% 72% at 50% 50%, transparent 40%, #000 82%);
}
.portrait-stage .portrait { margin: 0; }
.portrait-stage .portrait .frame {
  box-shadow: 0 34px 60px -32px rgba(0, 0, 0, 0.85);
}
.portrait-stage .portrait figcaption { color: var(--neutral-400); }
.portrait-stage .portrait figcaption::before { background: var(--brand-orange); }

.section--warm .stat { border-top-color: var(--ink); }
.section--warm .stat .value { color: var(--color-text-primary); }
/* First paragraph of the biography reads as a standfirst. */
.section--warm .prose > p:first-child {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--color-text-primary);
}

/* ---------- About: the pull quote as a full band ---------- */
.pull-band {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(115deg, var(--brand-teal-dark) 0%, #0c1b1c 72%);
}
.pull-band::before {
  content: "";
  position: absolute;
  inset: -40% -10%;
  z-index: -1;
  background: radial-gradient(38% 60% at 82% 30%, rgba(250, 171, 54, 0.20), transparent 70%);
  pointer-events: none;
}
.pull-band .pull-mark {
  position: absolute;
  right: -4%;
  top: 50%;
  transform: translateY(-50%);
  width: min(30%, 22rem);
  opacity: 0.1;
  pointer-events: none;
}
.pull-band .pull { position: relative; }
.pull-band .pull blockquote { font-size: var(--step-4); color: var(--neutral-0); }
.pull-band .pull blockquote::before {
  content: "";
  display: block;
  width: 3.5rem;
  height: 3px;
  margin-bottom: 1.75rem;
  background: var(--brand-orange);
}
.pull-band .pull .attrib { color: var(--neutral-200); }
@media (max-width: 820px) { .pull-band .pull-mark { width: 70%; right: -22%; opacity: 0.07; } }

/* ---------- Contact: two solid panels ---------- */
.contact-grid { --panel-h: clamp(11rem, 20vw, 14rem); }
.contact-card {
  min-height: var(--panel-h);
  justify-content: flex-end;
  isolation: isolate;
  border-color: transparent;
}
.contact-card::after { display: none; }
.contact-card .mark {
  position: absolute;
  z-index: -1;
  right: -14%;
  bottom: -34%;
  width: 62%;
  opacity: 0.1;
  transition: transform 0.9s var(--ease), opacity 0.9s var(--ease);
  pointer-events: none;
}
.contact-card:hover .mark { transform: translate(-6%, -8%) scale(1.12); opacity: 0.16; }
/* A hairline of the page colour draws itself across the top on hover. */
.contact-card::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 3px;
  background: var(--brand-orange);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.65s var(--ease);
}
.contact-card:hover::before, .contact-card:focus-visible::before { transform: scaleX(1); }

.contact-card--teal {
  background: linear-gradient(140deg, var(--brand-teal-dark), var(--brand-teal) 82%);
}
.contact-card--teal .tag,
.contact-card--teal .value,
.contact-card--teal .note { color: var(--neutral-0); }
.contact-card--teal .note { font-weight: 500; }

.contact-card--night {
  background: linear-gradient(140deg, var(--night-2), var(--night) 78%);
  border-color: var(--night-line);
}
.contact-card--night .tag { color: var(--brand-teal-light); }
.contact-card--night .value { color: var(--brand-orange-light); }
.contact-card--night .note { color: var(--neutral-300); }
.contact-card--night .mark { opacity: 0.055; }
.contact-card--night:hover .mark { opacity: 0.09; }
.contact-card--night::before { background: var(--brand-orange-light); }

.contact-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 34px 60px -34px rgba(16, 26, 26, 0.7);
}

/* ---------- Contact: the steps take the same ramp ---------- */
.steps li {
  /* Named brand colours rather than a mix, for the same reason as the
     service list. Orange dark is the only warm value that carries type,
     and only at the display size the numeral is set in below. */
  --ramp: var(--brand-teal-dark);
  border-top: 2px solid var(--ramp);
  padding-top: 1.25rem;
}
.steps li:nth-child(3n + 1) { --ramp: var(--brand-teal-dark); }
.steps li:nth-child(3n + 2) { --ramp: var(--brand-teal); }
.steps li:nth-child(3n + 3) { --ramp: var(--brand-orange-dark); }
.steps li::before {
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--brand-teal-dark);
  margin-bottom: 0.85rem;
}
/* Same rule as the service list: the rule above each step carries the
   warm colour, the numeral under it stays teal. */
.steps li:nth-child(3n + 2)::before { color: var(--brand-teal); }

/* ---------- Closing bands get the page's own light ---------- */
.close-band { isolation: isolate; }
.close-band::before {
  content: "";
  position: absolute;
  inset: -35% -12%;
  z-index: -1;
  background:
    radial-gradient(40% 55% at 16% 26%, var(--wash-a), transparent 68%),
    radial-gradient(34% 46% at 92% 86%, var(--wash-b), transparent 72%);
  pointer-events: none;
}

/* Glyph ink follows the surface it is drawn on. main.js reads this
   value off the host element, so setting it in CSS is all it takes. */
.section--night .touchpoint { --glyph-ink: rgba(140, 200, 200, 0.42); }

/* The three cards on the home page carry the same colours the three
   bands on the approach page do, so the pages read as one idea. */
.section--night .touchpoint:nth-child(3n + 1) {
  --card-ink: var(--brand-teal-light);
  --glyph-ink: rgba(36, 158, 160, 0.52);
}
.section--night .touchpoint:nth-child(3n + 2) {
  --card-ink: var(--brand-orange-light);
  --glyph-ink: rgba(250, 171, 54, 0.42);
  --ridge-accent: #faab36;
}
.section--night .touchpoint:nth-child(3n + 3) {
  --card-ink: var(--brand-teal-light);
  --glyph-ink: rgba(180, 220, 220, 0.5);
}
.touchpoint::before { background: var(--card-ink, var(--brand-orange)); }

/* "Connect", "Interact", "Engage" are the three words the whole section
   is about, so they carry the accent instead of sitting in plain white.
   Orange light on the night ground is 9.2:1, so it is safe at any size. */
.section--night .touchpoint h3 { color: var(--brand-orange-light); }
.section--night .touchpoint:hover {
  border-color: color-mix(in srgb, var(--card-ink, var(--brand-teal-light)) 45%, transparent);
}

/* The print changes sides band to band, so the eye zig-zags down the
   page instead of running along one edge. */
.tp-band .tp-row {
  grid-template-columns: clamp(10rem, 19vw, 18rem) minmax(0, 1fr);
}
.tp-band:nth-of-type(even) .tp-row {
  grid-template-columns: minmax(0, 1fr) clamp(10rem, 19vw, 18rem);
}
.tp-band:nth-of-type(even) .tp-plate { grid-column: 2; grid-row: 1; }
.tp-band:nth-of-type(even) .tp-row > div:not(.tp-plate) { grid-column: 1; grid-row: 1; }

@media (max-width: 780px) {
  .tp-band .tp-row,
  .tp-band:nth-of-type(even) .tp-row { grid-template-columns: 1fr; }
  .tp-band:nth-of-type(even) .tp-plate,
  .tp-band:nth-of-type(even) .tp-row > div:not(.tp-plate) {
    grid-column: 1;
    grid-row: auto;
  }
  .tp-band .tp-row .glyph { width: 9rem; }
}
