/* ==========================================================================
   COVENANT COMMERCIAL CONSTRUCTION, V2 design system
   One stylesheet. Architectural drawing language: hairlines, corner ticks,
   measured labels, restrained navy. Edit tokens in :root to retune.
   ========================================================================== */

:root {
  /* Brand */
  --ink:      #101c26;
  --ink-2:    #132330;
  --ink-3:    #17293a;
  --steel:    #37516a;
  --concrete: #5f7488;
  --mist:     #a2b7c6;
  --line:     #e3e5e9;
  --line-d:   rgba(255,255,255,0.1);
  --paper:    #f7f7f5;
  --white:    #ffffff;
  --accent:   #17577a;
  --accent-2: #5ea3c9;
  --accent-dim: rgba(23,87,122,0.35);
  /* Dark brand surfaces (blue/white pass 2026-08-25): surfaces split from text ink */
  --surface:   #0e2e42;
  --surface-2: #113650;
  --surface-3: #16425e;
  --shade-rgb: 11,38,56;
  --ph-a: #143a54;
  --ph-b: #194360;
  --stroke-d: rgba(122,178,214,0.55);

  /* Type */
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-serif: "Cinzel", "Times New Roman", serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Fluid type scale */
  --fs-hero:  clamp(2.6rem, 7.2vw, 5.4rem);
  --fs-h1:    clamp(2.3rem, 5.4vw, 4rem);
  --fs-h2:    clamp(1.9rem, 4vw, 3rem);
  --fs-h3:    clamp(1.15rem, 1.8vw, 1.45rem);
  --fs-lead:  clamp(1.05rem, 1.6vw, 1.3rem);
  --fs-body:  1rem;
  --fs-small: 0.875rem;
  --fs-micro: 0.72rem;

  /* Layout */
  --maxw: 1280px;
  --gutter: clamp(20px, 4.5vw, 72px);
  --sec: clamp(88px, 12vw, 168px);
  --radius: 10px;   /* W22 2026-09-15: controls are rounded; cards, photos and frames stay square */

  /* Motion */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --dur: 0.7s;

  /* Texture: subtle grain for dark surfaces */
  --noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E");
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  color: var(--ink);
  background: var(--paper);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; }
::selection { background: var(--accent); color: var(--white); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.022em;
  margin: 0 0 0.5em;
  text-wrap: balance;
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); letter-spacing: -0.01em; }
p { margin: 0 0 1rem; }

/* ---------- Utilities ---------- */
.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: var(--gutter); }
.section { padding-block: var(--sec); position: relative; }
.section--dark { background: var(--surface); color: var(--white); }
.section--dark::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: var(--noise); opacity: 0.05;
}
.section--dark > * { position: relative; }
.section--white { background: var(--white); border-top: 1px solid var(--line); }
.lead { font-size: var(--fs-lead); color: var(--steel); max-width: 58ch; line-height: 1.6; }
.section--dark .lead { color: rgba(255,255,255,0.72); }
.small { font-size: var(--fs-small); color: var(--concrete); }

/* Measured section label: serif index number + rule + tracked caps */
.sec-label {
  display: flex; align-items: center; gap: 14px;
  margin: 0 0 clamp(20px, 3vw, 36px);
  font-family: var(--font-display);
  font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: 0.32em; text-transform: uppercase;
  color: var(--accent);
}
.sec-label .idx { font-family: var(--font-serif); font-weight: 600; letter-spacing: 0.12em; font-size: 0.8rem; }
.sec-label::after { content: ""; height: 1px; width: 64px; background: var(--accent-dim); }
.section--dark .sec-label { color: var(--accent-2); }

.section-head { max-width: 70ch; margin-bottom: clamp(40px, 6vw, 72px); }
.section-head .lead { margin-top: 1.2rem; }

/* Corner ticks: architectural registration marks on media frames */
.tick { position: relative; }
.tick::before, .tick::after {
  content: ""; position: absolute; width: 18px; height: 18px; pointer-events: none; z-index: 2;
}
.tick::before { top: -1px; left: -1px; border-top: 1px solid var(--accent); border-left: 1px solid var(--accent); }
.tick::after { bottom: -1px; right: -1px; border-bottom: 1px solid var(--accent); border-right: 1px solid var(--accent); }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; gap: 0.7em;
  font-family: var(--font-display); font-weight: 700;
  font-size: 0.8rem; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 1.05em 1.9em;
  border: 1px solid var(--surface); background: var(--surface); color: var(--white);
  border-radius: var(--radius); cursor: pointer;
  transition: background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.btn .arr { display: inline-block; transition: transform .3s var(--ease); }
.btn:hover { background: var(--accent); border-color: var(--accent); color: var(--white); }
.btn:hover .arr { transform: translateX(5px); }
.btn--light { background: var(--white); border-color: var(--white); color: var(--ink); }
.btn--light:hover { background: var(--accent); border-color: var(--accent); color: var(--white); }
.btn--outline { background: transparent; border-color: rgba(255,255,255,0.5); color: var(--white); }
.btn--outline:hover { background: var(--white); border-color: var(--white); color: var(--ink); }
.btn--ghost { background: transparent; border-color: var(--ink); color: var(--ink); }
.btn--ghost:hover { background: var(--surface); color: var(--white); }

/* Inline text link with sliding underline */
.tlink {
  font-family: var(--font-display); font-weight: 700; font-size: 0.8rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink);
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat; background-size: 100% 1px; background-position: 0 100%;
  padding-bottom: 5px; transition: color .2s;
}
.tlink:hover { color: var(--accent); }
.section--dark .tlink { color: var(--white); }
.section--dark .tlink:hover { color: var(--accent-2); }

/* Skip link */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--accent); color: var(--white);
  font-family: var(--font-display); font-weight: 700; font-size: 0.8rem;
  letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.9em 1.5em; border-radius: var(--radius);
}
.skip:focus { left: var(--gutter); }

/* ---------- Header ---------- */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 90;
  transition: background .35s var(--ease), border-color .35s var(--ease), height .35s var(--ease);
  border-bottom: 1px solid transparent;
}
.site-header.scrolled {
  background: rgba(var(--shade-rgb),0.92);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-bottom-color: var(--line-d);
}
.nav { display: flex; align-items: center; justify-content: space-between; height: 84px; transition: height .35s var(--ease); }
.site-header.scrolled .nav { height: 68px; }
.brand { display: inline-flex; align-items: center; }
.brand-img { height: 46px; width: auto; display: block; transition: height .35s var(--ease); }
.site-header.scrolled .brand-img { height: 38px; }
@media (max-width: 480px) { .brand-img { height: 36px; } }

.nav-cta { display: inline-flex; align-items: center; gap: 28px; }
.nav-cta .btn { padding: 0.8em 1.5em; border-color: rgba(255,255,255,0.4); background: transparent; }
.nav-cta .btn:hover { background: var(--accent); border-color: var(--accent); }
@media (max-width: 620px) { .nav-cta .btn { display: none; } }

/* Menu button: label + animated bars */
.menu-btn {
  display: inline-flex; align-items: center; gap: 12px;
  background: none; border: 0; cursor: pointer; color: var(--white);
  font-family: var(--font-display); font-weight: 700; font-size: 0.78rem;
  letter-spacing: 0.22em; text-transform: uppercase; padding: 10px 0;
  border-radius: var(--radius);
}
.menu-btn .bars { position: relative; width: 26px; height: 12px; }
.menu-btn .bars::before, .menu-btn .bars::after {
  content: ""; position: absolute; left: 0; width: 100%; height: 1.5px;
  background: currentColor; transition: transform .35s var(--ease), top .35s var(--ease), bottom .35s var(--ease);
}
.menu-btn .bars::before { top: 0; }
.menu-btn .bars::after { bottom: 0; }
body.nav-open .menu-btn .bars::before { top: 5px; transform: rotate(45deg); }
body.nav-open .menu-btn .bars::after { bottom: 5.5px; transform: rotate(-45deg); }

/* ---------- Full-screen overlay nav ---------- */
.nav-overlay {
  position: fixed; inset: 0; z-index: 80;
  background: var(--surface);
  visibility: hidden; opacity: 0;
  transition: opacity .45s var(--ease), visibility 0s linear .45s;
  overflow-y: auto;
}
.nav-overlay::before {
  content: ""; position: absolute; inset: 0; background-image: var(--noise); opacity: 0.05; pointer-events: none;
}
.nav-overlay::after {
  content: ""; position: absolute; top: 50%; right: -120px; width: 560px; height: 560px;
  transform: translateY(-50%);
  background: url("logo-monogram.png") center / contain no-repeat;
  opacity: 0.05; pointer-events: none;
}
body.nav-open .nav-overlay { visibility: visible; opacity: 1; transition: opacity .45s var(--ease); }
body.nav-open { overflow: hidden; }
.nav-overlay .inner {
  position: relative; min-height: 100%;
  display: flex; flex-direction: column; justify-content: center;
  padding: 120px var(--gutter) 64px;
  max-width: var(--maxw); margin: 0 auto;
}
.nav-overlay ul { list-style: none; margin: 0; padding: 0; }
.nav-overlay li { overflow: hidden; }
.nav-overlay li a {
  display: inline-flex; align-items: baseline; gap: 18px;
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2rem, 6vw, 4.2rem); line-height: 1.18;
  color: var(--white); letter-spacing: -0.02em;
  transform: translateY(110%); transition: transform .6s var(--ease), color .25s;
}
body.nav-open .nav-overlay li a { transform: translateY(0); }
.nav-overlay li:nth-child(1) a { transition-delay: .06s; }
.nav-overlay li:nth-child(2) a { transition-delay: .12s; }
.nav-overlay li:nth-child(3) a { transition-delay: .18s; }
.nav-overlay li:nth-child(4) a { transition-delay: .24s; }
.nav-overlay li:nth-child(5) a { transition-delay: .30s; }
.nav-overlay li:nth-child(6) a { transition-delay: .36s; }
.nav-overlay li:nth-child(7) a { transition-delay: .42s; }
.nav-overlay li:nth-child(8) a { transition-delay: .48s; }
.nav-overlay li a:hover, .nav-overlay li a[aria-current="page"] { color: var(--accent-2); }
.nav-overlay li a .no {
  font-family: var(--font-serif); font-weight: 600; font-size: 0.9rem;
  letter-spacing: 0.2em; color: var(--accent);
}
.nav-overlay .meta {
  margin-top: clamp(40px, 7vh, 80px); padding-top: 28px;
  border-top: 1px solid var(--line-d);
  display: flex; flex-wrap: wrap; gap: 16px 56px;
  color: var(--mist); font-size: var(--fs-small);
}
.nav-overlay .meta a:hover { color: var(--accent-2); }

/* ---------- Hero ---------- */
.hero {
  position: relative; min-height: 100svh;
  display: flex; flex-direction: column; justify-content: flex-end;
  background: var(--surface); color: var(--white); overflow: hidden;
}
.hero__bg {
  position: absolute; inset: -12% 0; z-index: 0;
  will-change: transform;
}
.hero__shade {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(180deg, rgba(var(--shade-rgb),0.78) 0%, rgba(var(--shade-rgb),0.25) 38%, rgba(var(--shade-rgb),0.36) 62%, rgba(var(--shade-rgb),0.92) 100%),
    linear-gradient(90deg, rgba(var(--shade-rgb),0.62) 0%, rgba(var(--shade-rgb),0.05) 60%);
}
.hero__shade::after { content: ""; position: absolute; inset: 0; background-image: var(--noise); opacity: 0.05; }
.hero .wrap { position: relative; z-index: 2; width: 100%; }
.hero__main { padding-top: 150px; padding-bottom: clamp(48px, 7vh, 88px); }

.hero .kicker {
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-micro); letter-spacing: 0.32em; text-transform: uppercase;
  color: rgba(255,255,255,0.85); margin-bottom: clamp(18px, 3vh, 30px);
}
.hero .kicker::before { content: ""; width: 44px; height: 1px; background: var(--accent); }

.hero h1 {
  font-size: var(--fs-hero); font-weight: 800; color: var(--white);
  max-width: 13ch; margin-bottom: clamp(20px, 3.5vh, 34px);
}
.hero h1 .ln { display: block; overflow: hidden; }
.hero h1 .ln > span { display: inline-block; transform: translateY(112%); animation: rise .9s var(--ease) forwards; }
.hero h1 .ln:nth-child(2) > span { animation-delay: .12s; }
.hero h1 .ln:nth-child(3) > span { animation-delay: .24s; }
.hero h1 em { font-style: normal; color: var(--accent-2); }
@keyframes rise { to { transform: translateY(0); } }

.hero .sub {
  font-size: var(--fs-lead); color: rgba(255,255,255,0.85);
  max-width: 46ch; line-height: 1.6; margin-bottom: clamp(26px, 4vh, 40px);
  opacity: 0; animation: fadeUp .8s var(--ease) .4s forwards;
}
.hero .btns { display: flex; flex-wrap: wrap; gap: 14px; opacity: 0; animation: fadeUp .8s var(--ease) .55s forwards; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }

/* Hero footer: stat bar inside the stage */
.hero__bar {
  position: relative; z-index: 2;
  border-top: 1px solid rgba(255,255,255,0.18);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  background: rgba(var(--shade-rgb),0.35);
}
.hero__bar .wrap {
  display: grid; grid-template-columns: repeat(4, 1fr);
}
.hero__bar .cell {
  padding: clamp(18px, 2.6vw, 30px) clamp(8px, 1.5vw, 24px);
  border-right: 1px solid rgba(255,255,255,0.12);
}
.hero__bar .cell:first-child { padding-left: 0; }
.hero__bar .cell:last-child { border-right: 0; }
.hero__bar .num {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.4rem, 2.6vw, 2.2rem); color: var(--white); line-height: 1;
}
.hero__bar .num .u { color: var(--accent-2); }
.hero__bar .lbl {
  font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(255,255,255,0.72); margin-top: 8px; font-family: var(--font-display); font-weight: 600;
}
@media (max-width: 760px) {
  .hero__bar .wrap { grid-template-columns: 1fr 1fr; }
  .hero__bar .cell { border-right: 0; padding-left: 0; }
  .hero__bar .cell:nth-child(odd) { border-right: 1px solid rgba(255,255,255,0.12); }
  .hero__bar .cell:nth-child(even) { padding-left: clamp(12px, 4vw, 24px); }
  .hero__bar .cell:nth-child(-n+2) { border-bottom: 1px solid rgba(255,255,255,0.12); }
}

/* Scroll cue */
.scroll-cue {
  position: absolute; z-index: 3; right: var(--gutter); bottom: 132px;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  color: rgba(255,255,255,0.65);
  font-family: var(--font-display); font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.3em; text-transform: uppercase;
  writing-mode: vertical-rl;
}
.scroll-cue::after { content: ""; width: 1px; height: 48px; background: linear-gradient(var(--accent), transparent); animation: drip 2.2s var(--ease) infinite; }
@keyframes drip { 0% { transform: scaleY(0); transform-origin: top; } 45% { transform: scaleY(1); transform-origin: top; } 55% { transform: scaleY(1); transform-origin: bottom; } 100% { transform: scaleY(0); transform-origin: bottom; } }
@media (max-width: 900px) { .scroll-cue { display: none; } }

/* ---------- Sector ticker ---------- */
.ticker {
  background: var(--surface-2); color: rgba(255,255,255,0.85);
  border-block: 1px solid var(--line-d);
  overflow: hidden; padding-block: 18px; position: relative;
}
.ticker__track {
  display: flex; width: max-content; gap: 0;
  animation: marquee 36s linear infinite;
}
.ticker:hover .ticker__track { animation-play-state: paused; }
.ticker span {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-micro); letter-spacing: 0.3em; text-transform: uppercase;
  padding-inline: 28px; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 28px;
}
.ticker span::after { content: ""; width: 5px; height: 5px; background: var(--accent); transform: rotate(45deg); }
@keyframes marquee { to { transform: translateX(-50%); } }

/* ---------- Manifesto (editorial statement) ---------- */
.manifesto .big {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.6rem, 3.6vw, 2.7rem); line-height: 1.22; letter-spacing: -0.015em;
  max-width: 26ch; margin: 0;
  color: var(--ink); text-wrap: balance;
}
.manifesto .big em { font-style: normal; color: var(--accent); }
.manifesto-grid { display: grid; grid-template-columns: 1.25fr 0.75fr; gap: clamp(40px, 6vw, 96px); align-items: end; }
@media (max-width: 880px) { .manifesto-grid { grid-template-columns: 1fr; } }
.manifesto aside p { color: var(--concrete); }
.manifesto aside .tlink { margin-top: 0.4rem; display: inline-block; }

/* ---------- Split feature ---------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(40px, 6vw, 96px); align-items: center; }
@media (max-width: 880px) { .split { grid-template-columns: 1fr; } }
.media-frame { aspect-ratio: 4/3; overflow: hidden; background: var(--surface-3); }
.media-frame .img {
  width: 100%; height: 100%;
  background: var(--surface-3) center / cover no-repeat;
  transition: transform 1.1s var(--ease);
}
.media-frame:hover .img { transform: scale(1.045); }
.media-frame .ph-label {
  width: 100%; height: 100%; display: grid; place-items: center;
  color: rgba(255,255,255,0.3); font-family: var(--font-display); font-weight: 700;
  letter-spacing: 0.22em; font-size: var(--fs-micro); text-transform: uppercase;
  background: repeating-linear-gradient(135deg, var(--ph-a) 0 20px, var(--ph-b) 20px 40px);
}
.checklist { list-style: none; padding: 0; margin: 1.6rem 0 0; }
.checklist li { position: relative; padding-left: 2em; margin-bottom: 0.9rem; color: var(--steel); }
.checklist li::before {
  content: ""; position: absolute; left: 0; top: 0.42em;
  width: 1em; height: 0.55em;
  border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

/* ---------- Sectors ---------- */
.sector-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line-d); border-left: 1px solid var(--line-d);
}
@media (max-width: 880px) { .sector-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .sector-grid { grid-template-columns: 1fr; } }
.sector {
  position: relative; padding: clamp(26px, 3vw, 44px);
  border-right: 1px solid var(--line-d); border-bottom: 1px solid var(--line-d);
  transition: background .35s var(--ease);
  display: block;
}
.sector:hover { background: rgba(255,255,255,0.035); }
.sector .no {
  font-family: var(--font-serif); font-weight: 600; font-size: 0.8rem;
  letter-spacing: 0.18em; color: var(--accent);
  display: block; margin-bottom: 2.2rem;
}
.sector h3 { color: var(--white); margin-bottom: 0.5rem; }
.sector p { color: var(--mist); font-size: 0.95rem; margin: 0; max-width: 34ch; }
.sector .go {
  position: absolute; top: clamp(22px, 2.6vw, 38px); right: clamp(22px, 2.6vw, 38px);
  color: var(--accent); opacity: 0; transform: translate(-6px, 6px);
  transition: opacity .3s var(--ease), transform .3s var(--ease);
  font-size: 1.1rem;
}
.sector:hover .go { opacity: 1; transform: translate(0, 0); }
.sector--wide { grid-column: 1 / -1; }
.sector--wide p { max-width: 60ch; }

/* ---------- Projects ---------- */
.feature-project {
  display: grid; grid-template-columns: 1.35fr 1fr; gap: 0;
  background: var(--surface); color: var(--white); overflow: hidden;
}
@media (max-width: 880px) { .feature-project { grid-template-columns: 1fr; } }
.feature-project .media { min-height: 380px; overflow: hidden; }
.feature-project .media .img { width: 100%; height: 100%; background: center / cover no-repeat; transition: transform 1.2s var(--ease); }
.feature-project:hover .media .img { transform: scale(1.04); }
.feature-project .info {
  padding: clamp(28px, 4vw, 56px);
  display: flex; flex-direction: column; justify-content: flex-end; gap: 6px;
  border-left: 1px solid var(--line-d); position: relative;
}
.feature-project .info::before {
  content: "FEATURED"; position: absolute; top: clamp(24px, 3vw, 44px); left: clamp(28px, 4vw, 56px);
  font-family: var(--font-display); font-weight: 700; font-size: 0.62rem;
  letter-spacing: 0.32em; color: var(--accent);
}
.feature-project .cat { font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: 0.2em; color: var(--accent-2); font-family: var(--font-display); font-weight: 700; }
.feature-project h2, .feature-project h3 { font-size: clamp(1.5rem, 2.6vw, 2.2rem); color: var(--white); margin: 0.3rem 0 0.4rem; }
.feature-project .meta { color: var(--mist); font-size: var(--fs-small); margin: 0; }

.project-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2vw, 28px); margin-top: clamp(16px, 2vw, 28px); }

/* ---- W23 (2026-09-15): the featured block and the grid ran together ----
   Jacques, 2026-09-15: "the featured, and goddsarc school thing on port run together or
   something". Measured on portfolio.html before the fix: the gap between the bottom of
   .feature-project and the top of .project-grid was 0px at 1280 and -10px at 390, so the
   navy feature card and the first row of navy cards read as one block. The feature now
   carries real air below it, and on portfolio.html an "All Projects" eyebrow sits in that
   air so the two bands are named as well as separated. index.html gets the air only; it
   has a section head of its own above the pair. */
.feature-project { margin-bottom: clamp(30px, 4.6vw, 64px); }
.grid-label { margin-top: 0; margin-bottom: clamp(12px, 1.4vw, 18px); }
.grid-label + .project-grid { margin-top: 0; }

/* ---- W39 (2026-09-16): the FEATURED label sat on the category line on phones ----
   Jacques, 2026-09-16: "the only thing ive seen so far is on the phone on the goddard school
   thing "featured" overlaps with "early childhood education"". Measured before the fix on both
   pages: the label is absolute at top 24px inside .info, and once the block stacks to one
   column under 880px the column is only as tall as its copy, so the category line starts at
   31px and the 16px label ran 9px into it (320 to 760; 7px at 760, 5px at 880). Under 880px
   the label now flows as the first line of the column with its own air below it, so the
   category line clears it at every width from 320 up; above 880px the column is 380px tall
   and the label stays pinned at the top as before. The three title rules below also name the
   h3 again: index.html keeps an <h3> under its section h2, and W33 moved those rules to h2
   for portfolio.html, which left the home page's feature title at the default navy on navy. */
@media (max-width: 880px) {
  .feature-project .info::before { position: static; margin-bottom: 4px; }
}
@media (max-width: 880px) { .project-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .project-grid { grid-template-columns: 1fr; } }
.project { position: relative; background: var(--surface); color: var(--white); overflow: hidden; display: flex; flex-direction: column; }
.project .media { aspect-ratio: 4/3; overflow: hidden; position: relative; }
.project .media .img, .project .media .ph {
  position: absolute; inset: 0; transition: transform 1s var(--ease);
  background: center / cover no-repeat;
}
.project .media .ph { background: repeating-linear-gradient(135deg, var(--ph-a) 0 18px, var(--ph-b) 18px 36px); }
.project .media .ph::after {
  content: "NO PHOTO"; position: absolute; inset: 0; display: grid; place-items: center;
  color: rgba(255,255,255,0.6); font-family: var(--font-display); font-weight: 700;
  letter-spacing: 0.22em; font-size: 0.66rem;
}
.project:hover .media .img, .project:hover .media .ph { transform: scale(1.05); }
.project .body { padding: 20px 22px 22px; border-top: 2px solid var(--accent); }
.project .cat { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.2em; color: var(--accent-2); font-family: var(--font-display); font-weight: 700; }
.project h3 { color: var(--white); margin: 0.35rem 0 0.25rem; font-size: 1.15rem; }
.project .meta { font-size: 0.85rem; color: var(--mist); margin: 0; }

/* Portfolio filters */
.filters { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: clamp(28px, 4vw, 44px); }
.filters button {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro);
  letter-spacing: 0.18em; text-transform: uppercase;
  padding: 0.8em 1.4em; cursor: pointer;
  background: transparent; color: var(--steel);
  border: 1px solid var(--line); border-radius: var(--radius);
  transition: all .25s var(--ease);
}
.filters button:hover { border-color: var(--accent); color: var(--accent); }
.filters button[aria-pressed="true"] { background: var(--surface); border-color: var(--surface); color: var(--white); }
[data-cat].is-hidden { display: none !important; }

/* ---------- Services accordion ---------- */
.svc-list { border-top: 1px solid var(--line); }
.svc { border-bottom: 1px solid var(--line); }
.svc summary {
  list-style: none; cursor: pointer;
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: clamp(18px, 3vw, 44px);
  padding: clamp(22px, 3vw, 34px) 4px;
  transition: padding-left .3s var(--ease);
}
.svc summary::-webkit-details-marker { display: none; }
.svc summary:hover { padding-left: 14px; }
.svc .no { font-family: var(--font-serif); font-weight: 600; font-size: 0.85rem; letter-spacing: 0.15em; color: var(--accent); min-width: 2.4em; }
.svc h3 { margin: 0; font-size: clamp(1.25rem, 2.4vw, 1.8rem); }
.svc .plus { position: relative; width: 16px; height: 16px; flex: none; }
.svc .plus::before, .svc .plus::after { content: ""; position: absolute; background: var(--ink); transition: transform .35s var(--ease); }
.svc .plus::before { top: 50%; left: 0; width: 100%; height: 1.5px; margin-top: -0.75px; }
.svc .plus::after { left: 50%; top: 0; height: 100%; width: 1.5px; margin-left: -0.75px; }
.svc[open] .plus::after { transform: rotate(90deg); }
.svc[open] .plus::before { transform: rotate(180deg); }
.svc .panel { padding: 0 4px clamp(26px, 3.4vw, 40px) calc(2.4em + clamp(18px, 3vw, 44px)); }
@media (max-width: 640px) { .svc .panel { padding-left: 4px; } }
.svc .panel p { color: var(--steel); max-width: 62ch; }
.svc .panel ul { list-style: none; padding: 0; margin: 1rem 0 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px 28px; max-width: 700px; }
.svc .panel li { position: relative; padding-left: 1.4em; color: var(--concrete); font-size: 0.95rem; }
.svc .panel li::before { content: ""; position: absolute; left: 0; top: 0.62em; width: 6px; height: 6px; background: var(--accent); transform: rotate(45deg); }

/* ---------- Process ---------- */
.process { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(20px, 3vw, 40px); counter-reset: step; }
@media (max-width: 880px) { .process { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .process { grid-template-columns: 1fr; } }
.step { position: relative; padding-top: 22px; }
.step::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: var(--line-d); }
.step::after {
  content: ""; position: absolute; top: -2.5px; left: 0; width: 6px; height: 6px;
  background: var(--accent); transform: rotate(45deg);
}
.step .no {
  font-family: var(--font-serif); font-weight: 600; font-size: 2.2rem; line-height: 1;
  color: transparent; -webkit-text-stroke: 1px var(--accent-dim);
  display: block; margin-bottom: 0.9rem;
}
.section--dark .step .no { -webkit-text-stroke: 1px var(--stroke-d); }
.step h3 { color: var(--white); margin-bottom: 0.4rem; }
.step p { color: var(--mist); font-size: 0.95rem; margin: 0; }

/* ---------- Team ---------- */
.team-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 3vw, 36px); }
@media (max-width: 880px) { .team-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .team-grid { grid-template-columns: 1fr; } }
.person .photo {
  aspect-ratio: 4/5; overflow: hidden; position: relative; background: #e9eaec;
  filter: grayscale(1); transition: filter .6s var(--ease);
}
.person:hover .photo { filter: grayscale(0); }
.person .photo .ph-label {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: repeating-linear-gradient(135deg, #e9eaec 0 16px, #f1f2f3 16px 32px);
  color: var(--concrete); font-size: 0.68rem; letter-spacing: 0.22em;
  font-family: var(--font-display); font-weight: 700;
}
.person .photo img { width: 100%; height: 100%; object-fit: cover; }
.person h3 { margin: 1.1rem 0 0.15rem; }
.person .role {
  color: var(--accent); font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-micro); letter-spacing: 0.18em; text-transform: uppercase; margin-bottom: 0.6rem;
}
.person p { color: var(--concrete); font-size: 0.95rem; margin: 0; }

/* ---------- Values (editorial rows) ---------- */
.value-rows { border-top: 1px solid var(--line-d); }
.value-row {
  display: grid; grid-template-columns: auto 1fr 1.2fr; gap: clamp(20px, 4vw, 64px);
  align-items: baseline; padding: clamp(24px, 3.4vw, 40px) 0;
  border-bottom: 1px solid var(--line-d);
}
@media (max-width: 760px) { .value-row { grid-template-columns: 1fr; gap: 10px; } }
.value-row .no { font-family: var(--font-serif); font-weight: 600; font-size: 0.85rem; letter-spacing: 0.15em; color: var(--accent); }
.value-row h3 { color: var(--white); margin: 0; font-size: clamp(1.3rem, 2.4vw, 1.8rem); }
.value-row p { color: var(--mist); margin: 0; max-width: 52ch; }

/* ---------- Quotes ---------- */
.quote-slider { position: relative; max-width: 880px; }
.quote-slide { display: none; }
.quote-slide.active { display: block; animation: fadeUp .6s var(--ease); }
.quote-slide blockquote {
  margin: 0 0 1.4rem;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.4rem, 3vw, 2.1rem); line-height: 1.32; letter-spacing: -0.01em;
  color: var(--white); text-wrap: balance;
}
.quote-slide blockquote::before { content: "\201C"; display: block; font-family: var(--font-serif); font-size: 3.2rem; line-height: 0.5; color: var(--accent); margin-bottom: 1.4rem; }
.quote-slide cite { font-style: normal; color: var(--mist); font-size: var(--fs-small); }
.quote-nav { display: flex; gap: 10px; margin-top: 2rem; align-items: center; }
.quote-nav button {
  width: 40px; height: 40px; border: 1px solid var(--line-d); background: transparent;
  color: var(--white); cursor: pointer; display: grid; place-items: center;
  transition: all .25s var(--ease); border-radius: var(--radius);
}
.quote-nav button:hover { border-color: var(--accent); color: var(--accent); }
.quote-dots { display: flex; gap: 8px; margin-left: 10px; }
.quote-dots .dot { width: 22px; height: 2px; background: var(--line-d); transition: background .3s; }
.quote-dots .dot.active { background: var(--accent); }

/* ---------- FAQ ---------- */
.faq-list { max-width: 820px; border-top: 1px solid var(--line); }
.faq { border-bottom: 1px solid var(--line); }
.faq summary {
  list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 24px;
  padding: 20px 4px; font-family: var(--font-display); font-weight: 700; font-size: 1.05rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }
.faq .plus { position: relative; width: 13px; height: 13px; flex: none; }
.faq .plus::before, .faq .plus::after { content: ""; position: absolute; background: var(--accent); transition: transform .3s var(--ease); }
.faq .plus::before { top: 50%; left: 0; width: 100%; height: 1.5px; margin-top: -0.75px; }
.faq .plus::after { left: 50%; top: 0; height: 100%; width: 1.5px; margin-left: -0.75px; }
.faq[open] .plus::after { transform: rotate(90deg); }
.faq .panel { padding: 0 4px 22px; color: var(--steel); max-width: 64ch; }

/* ---------- CTA band ---------- */
.cta {
  position: relative; background: var(--surface); color: var(--white);
  padding-block: clamp(80px, 11vw, 150px); overflow: hidden; text-align: center;
}
.cta::before { content: ""; position: absolute; inset: 0; background-image: var(--noise); opacity: 0.05; }
.cta::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 640px; height: 640px;
  transform: translate(-50%, -50%);
  background: url("logo-monogram.png") center / contain no-repeat; opacity: 0.045; pointer-events: none;
}
.cta .wrap { position: relative; z-index: 1; }
.cta .sec-label { justify-content: center; }
.cta .sec-label::after { display: none; }
.cta h2 { font-size: clamp(2.2rem, 5.5vw, 4rem); color: var(--white); max-width: 18ch; margin-inline: auto; }
.cta .lead { margin: 0 auto 2.4rem; color: rgba(255,255,255,0.72); }
.cta .btns { display: flex; justify-content: center; flex-wrap: wrap; gap: 14px; }

/* ---------- Page banner (interior) ---------- */
.banner {
  position: relative; background: var(--surface); color: var(--white);
  padding: 180px 0 clamp(64px, 9vw, 110px); overflow: hidden;
}
.banner::before { content: ""; position: absolute; inset: 0; background-image: var(--noise); opacity: 0.05; }
.banner::after {
  content: ""; position: absolute; top: 50%; right: -90px; width: 440px; height: 440px;
  transform: translateY(-50%);
  background: url("logo-monogram.png") center / contain no-repeat; opacity: 0.05; pointer-events: none;
}
.banner .wrap { position: relative; z-index: 1; }
.banner h1 { color: var(--white); max-width: 16ch; }
.banner .lead { color: rgba(255,255,255,0.75); }
.crumbs {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  font-family: var(--font-display); font-weight: 600; font-size: var(--fs-micro);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--mist);
  margin-bottom: clamp(20px, 3vw, 34px);
}
.crumbs a:hover { color: var(--accent-2); }
.crumbs .sep { color: var(--accent); }

/* ---------- Contact ---------- */
.contact-grid { display: grid; grid-template-columns: 1.25fr 0.75fr; gap: clamp(40px, 6vw, 96px); align-items: start; }
@media (max-width: 880px) { .contact-grid { grid-template-columns: 1fr; } }
.form { display: grid; gap: 1.4rem; }
.form .row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; }
@media (max-width: 560px) { .form .row { grid-template-columns: 1fr; } }
.field label {
  display: block; font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--steel); margin-bottom: 0.55rem;
}
.field input, .field select, .field textarea {
  width: 100%; padding: 0.95em 1em; font: inherit; color: var(--ink);
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  transition: border-color .2s, box-shadow .2s;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(23,87,122,0.14);
}
.field textarea { min-height: 150px; resize: vertical; }
.contact-side { border-left: 1px solid var(--line); padding-left: clamp(24px, 3vw, 48px); }
@media (max-width: 880px) { .contact-side { border-left: 0; padding-left: 0; border-top: 1px solid var(--line); padding-top: 32px; } }
.cd { margin-bottom: 1.9rem; }
.cd h4 {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro);
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent); margin: 0 0 0.35rem;
}
.cd p, .cd a { color: var(--steel); margin: 0; font-size: 1.02rem; }
.cd a:hover { color: var(--accent); }

/* ---------- Footer ---------- */
.site-footer { background: var(--surface); color: var(--mist); position: relative; overflow: hidden; }
.site-footer::before { content: ""; position: absolute; inset: 0; background-image: var(--noise); opacity: 0.04; }
.site-footer .top {
  position: relative; display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
  gap: clamp(32px, 4vw, 64px); padding-block: clamp(56px, 7vw, 88px) clamp(40px, 5vw, 64px);
}
@media (max-width: 880px) { .site-footer .top { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .site-footer .top { grid-template-columns: 1fr; } }
.site-footer .brand-img { height: 50px; }
.site-footer .tagline { margin-top: 1.2rem; max-width: 30ch; font-size: var(--fs-small); line-height: 1.7; }
.site-footer h3 {
  color: var(--white); font-size: var(--fs-micro); letter-spacing: 0.24em;
  text-transform: uppercase; margin: 0 0 1.1rem; font-family: var(--font-display); font-weight: 700;
}
.site-footer .col a { display: block; padding: 0.3rem 0; color: var(--mist); transition: color .2s; font-size: var(--fs-small); }
.site-footer .col a:hover { color: var(--accent-2); }
.site-footer address { font-style: normal; font-size: var(--fs-small); line-height: 1.8; }
.site-footer .legal {
  position: relative; border-top: 1px solid var(--line-d);
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px 24px;
  padding-block: 22px 26px; font-size: 0.8rem; color: rgba(255,255,255,0.45);
}

/* ---------- Reveal on scroll ---------- */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.reveal.in { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: .08s; }
.reveal[data-delay="2"] { transition-delay: .16s; }
.reveal[data-delay="3"] { transition-delay: .24s; }
.reveal[data-delay="4"] { transition-delay: .32s; }
.reveal[data-delay="5"] { transition-delay: .40s; }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .hero h1 .ln > span { transform: none; animation: none; }
  .hero .sub, .hero .btns { opacity: 1; animation: none; }
  .ticker__track { animation: none; }
  .scroll-cue::after { animation: none; }
  .hero__bg { transform: none !important; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ---------- Print: clean credibility one-pager ---------- */
@media print {
  .site-header, .nav-overlay, .scroll-cue, .ticker, .cta, .quote-nav, .filters { display: none !important; }
  body { background: #fff; color: #000; }
  .section { padding-block: 24px; }
}


/* ============================================================
   Team profile pass, leadership cards link to full profile
   pages (team-*.html) styled like a builder's resume sheet
   ============================================================ */

/* Person card as a link */
a.person { display: block; color: inherit; }
a.person .view {
  display: inline-block; margin-top: 0.8rem;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent);
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat; background-size: 0% 1px; background-position: 0 100%;
  padding-bottom: 4px; transition: background-size .35s var(--ease);
}
a.person:hover .view { background-size: 100% 1px; }
a.person:hover h3 { color: var(--accent); }
.person h3 { transition: color .25s var(--ease); }

/* Profile layout */
.profile-grid { display: grid; grid-template-columns: 0.85fr 1.35fr; gap: clamp(36px, 5vw, 80px); align-items: start; }
@media (max-width: 880px) { .profile-grid { grid-template-columns: 1fr; } }
.profile-side { position: sticky; top: 100px; }
@media (max-width: 880px) { .profile-side { position: static; } }
.profile-portrait { aspect-ratio: 4/5; overflow: hidden; background: #e9eaec; position: relative; }
.profile-portrait .ph-label {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: repeating-linear-gradient(135deg, #e9eaec 0 16px, #f1f2f3 16px 32px);
  color: var(--concrete); font-size: 0.68rem; letter-spacing: 0.22em;
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
}
.profile-portrait img { width: 100%; height: 100%; object-fit: cover; }

/* Spec-sheet facts panel */
.facts { border: 1px solid var(--line); background: #fafaf8; margin-top: 22px; padding: 6px 22px; }
.facts .row {
  display: grid; grid-template-columns: 118px 1fr; gap: 14px;
  padding: 12px 0; border-bottom: 1px solid var(--line); align-items: baseline;
}
.facts .row:last-child { border-bottom: 0; }
.facts dt {
  font-family: var(--font-display); font-weight: 700; font-size: 0.66rem;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent); margin: 0;
}
.facts dd { margin: 0; color: var(--steel); font-size: 0.92rem; line-height: 1.5; }

.profile-body h2 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); }
.profile-body p { color: var(--steel); max-width: 62ch; }
.profile-body .lead { color: var(--ink); font-weight: 500; }

/* Project experience rows (resume style) */
.exp-rows { border-top: 1px solid var(--line); margin-top: 8px; }
.exp-row {
  display: grid; grid-template-columns: 1.6fr auto auto auto; gap: 10px clamp(16px, 2.5vw, 40px);
  align-items: baseline; padding: 15px 4px;
  border-bottom: 1px solid var(--line);
  transition: background .25s var(--ease), padding-left .25s var(--ease);
}
.exp-row:hover { background: #fafaf8; padding-left: 12px; }
.exp-row .pname { font-family: var(--font-display); font-weight: 700; font-size: 0.98rem; }
.exp-row .pclient { display: block; font-family: var(--font-body); font-weight: 400; font-size: 0.82rem; color: var(--concrete); margin-top: 2px; }
.exp-row .pyear, .exp-row .pval, .exp-row .psize {
  font-size: 0.82rem; color: var(--concrete); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.exp-row .pval { color: var(--accent); font-weight: 600; }
@media (max-width: 640px) {
  .exp-row { grid-template-columns: 1fr auto; }
  .exp-row .psize { display: none; }
}
.exp-note { font-size: 0.8rem; color: var(--concrete); margin-top: 14px; }

/* Back-to-team link */
.backlink {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro);
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--mist);
  margin-bottom: 18px; transition: color .2s;
}
.banner .backlink:hover { color: var(--accent-2); }


/* ============================================================
   Launch pass, conversion, presentation placeholders, fixes
   ============================================================ */

/* Header phone: one-tap conversion path, always visible */
.nav-phone {
  color: rgba(255,255,255,0.88); font-family: var(--font-display); font-weight: 700;
  font-size: 0.82rem; letter-spacing: 0.08em; white-space: nowrap;
  font-variant-numeric: tabular-nums; transition: color .2s;
}
.nav-phone:hover { color: var(--accent-2); }

/* Kicker moved inside the H1 (keyword-bearing, same look as old .kicker) */
.kicker-in-h1 {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-micro); letter-spacing: 0.32em; text-transform: uppercase;
  color: rgba(255,255,255,0.85); margin-bottom: clamp(18px, 3vh, 30px);
}
.kicker-in-h1::before { content: ""; width: 44px; height: 1px; background: var(--accent); flex: none; }

/* Hero background as a real <img> (LCP + image search) */
.hero__bg img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero__bg picture { display: block; width: 100%; height: 100%; }

/* Presentation placeholders: [bracketed] content is highlighted so reviewers
   instantly see what is needed. Highlighting disappears when brackets do. */
mark.fill {
  background: rgba(23,87,122,0.14); color: inherit;
  border-bottom: 1px dashed rgba(23,87,122,0.75);
  padding: 0 0.18em; border-radius: 2px; font: inherit;
}
.section--dark mark.fill, .banner mark.fill, .cta mark.fill, .hero mark.fill,
.site-footer mark.fill, .nav-overlay mark.fill, .stats mark.fill, .hero__bar mark.fill {
  background: rgba(140,196,230,0.28); color: inherit;
}

/* Inert email placeholder (was a broken mailto) */
.mail-pending { color: inherit; }

/* Hairline boundary between stacked dark sections */
.section--dark + .cta { border-top: 1px solid var(--line-d); }

/* Deep links land clear of the fixed header */
.svc, .faq, #sectors, section[id] { scroll-margin-top: 96px; }

/* Experience rows: clean stack on phones */
@media (max-width: 640px) {
  .exp-row { grid-template-columns: 1fr auto; }
  .exp-row .pname { grid-column: 1 / -1; }
}

/* ---- Brand lockup: monogram mark + wordmark (2026-08 branding pass) ---- */
.brand-mark{height:42px;width:auto;display:block;margin-right:13px;transition:height .35s var(--ease);}
.site-header.scrolled .brand-mark{height:36px;}
@media (max-width:480px){.brand-mark{height:34px;margin-right:9px;}}

/* ---- Hero video loop (2026-08-25 blue/white pass): drone footage layer.
   Activates when assets/hero-loop.mp4 exists; the Goddard photo stays as
   poster, LCP image, and reduced-motion / slow-connection fallback. ---- */
.hero__bg { position: absolute; }
.hero__vid {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity 1.2s var(--ease);
}
.hero__vid.playing { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .hero__vid { display: none; } }

/* ============================================================
   Blue/white balance pass (2026-08-25, Jacques: "a little more
   white... not just full deep navy everywhere"). Selected bands
   convert from navy to paper via .section--paper; these are the
   light-context styles for the components that live in them.
   ============================================================ */
.section--paper { background: var(--paper); border-block: 1px solid var(--line); }
.section--paper + .cta { border-top: 0; }

/* Sector grid on paper */
.section--paper .sector-grid { border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
.section--paper .sector { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.section--paper .sector:hover { background: var(--white); }
.section--paper .sector h3 { color: var(--ink); }
.section--paper .sector p { color: var(--concrete); }

/* Process steps on paper */
.section--paper .step::before { background: var(--line); }
.section--paper .step h3 { color: var(--ink); }
.section--paper .step p { color: var(--concrete); }

/* Quote slider on paper */
.section--paper .quote-slide blockquote { color: var(--ink); }
.section--paper .quote-slide cite { color: var(--concrete); }
.section--paper .quote-nav button { border-color: var(--line); color: var(--ink); background: var(--white); }
.section--paper .quote-nav button:hover { border-color: var(--accent); color: var(--accent); }
.section--paper .quote-dots .dot { background: var(--line); }
.section--paper .quote-dots .dot.active { background: var(--accent); }

/* Value rows on paper (available if the About band ever converts) */
.section--paper .value-rows, .section--paper .value-row { border-color: var(--line); }
.section--paper .value-row h3 { color: var(--ink); }
.section--paper .value-row p { color: var(--concrete); }

/* ---- Audit fixes 2026-09-03 (Findings 2026-09-02); appended per handoff section 4 ---- */
/* Index numerals on navy: --accent on --surface is 1.8:1, --accent-2 is 5.1:1 */
.nav-overlay li a .no, .value-row .no, .crumbs .sep { color: var(--accent-2); }
/* Footer legal line: 45% white on navy is 4.05:1 at 0.8rem, 55% is 5.3:1 */
.site-footer .legal { color: rgba(255,255,255,0.55); }
/* Contact detail labels are <h2> now (heading order); same look as the old h4 */
.cd h2 {
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro);
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent); margin: 0 0 0.35rem;
}
/* Experience rows: keep the square-footage column on phones */
@media (max-width: 640px) {
  .exp-row { grid-template-columns: auto auto 1fr; }
  .exp-row .psize { display: inline-block; justify-self: end; }
}

/* ---- Speed pass 2026-09-04 (W3): real <picture> elements where CSS backgrounds were ---- */
.media-frame picture, .feature-project .media picture,
.person .photo picture, .profile-portrait picture { display: block; width: 100%; height: 100%; }
.media-frame img.img, .feature-project .media img.img, .project .media img.img { width: 100%; height: 100%; object-fit: cover; }

/* ---- Capacity and accountability block (ruling R1, 2026-09-08) ---- */
.cred { max-width: 72ch; margin-top: clamp(40px, 6vw, 64px); padding: clamp(22px, 3vw, 32px) clamp(22px, 3.5vw, 40px); background: var(--white); border: 1px solid var(--line); border-top: 2px solid var(--accent); }
.cred h3 { margin: 0 0 0.7rem; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro); letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent); }
.cred p { margin: 0; color: var(--steel); }

/* ---- Public inbox (ruling R2, 2026-09-08): the address is long, let it wrap in narrow columns ---- */
.nav-overlay .meta a[href^="mailto:"], .site-footer .col a[href^="mailto:"], .cd a[href^="mailto:"] { overflow-wrap: anywhere; }

/* ---- Careers (ruling W12, 2026-09-08): role list, hiring line in the closing band, posting body ---- */
.role-list { border-top: 1px solid var(--line); }
.role {
  display: grid; grid-template-columns: 1fr auto; gap: 6px clamp(16px, 3vw, 40px); align-items: center;
  padding: 22px 4px; border-bottom: 1px solid var(--line); color: var(--ink);
  transition: background .25s var(--ease), padding-left .25s var(--ease);
}
.role:hover { background: var(--paper); padding-left: 12px; }
.role__title { grid-column: 1; font-family: var(--font-display); font-weight: 700; font-size: clamp(1.1rem, 1.8vw, 1.35rem); letter-spacing: -0.01em; }
.role__meta { grid-column: 1; color: var(--concrete); font-size: var(--fs-small); }
.role__go {
  grid-column: 2; grid-row: 1 / span 2; white-space: nowrap;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro);
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent);
}
.role__go .arr { display: inline-block; transition: transform .3s var(--ease); }
.role:hover .role__go .arr { transform: translateX(5px); }
@media (max-width: 560px) { .role { grid-template-columns: 1fr; } .role__go { grid-column: 1; grid-row: auto; } }
.cta .hiring { margin: 2rem auto 0; font-size: var(--fs-small); color: rgba(255,255,255,0.72); }
.cta .hiring a { color: var(--white); text-decoration: underline; text-underline-offset: 3px; }
.cta .hiring a:hover { color: var(--accent-2); }
.value-row p a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.value-row p a:hover { color: var(--ink); }
.profile-body h3 { margin: 2.4rem 0 0.9rem; font-size: var(--fs-h3); }
.profile-body .checklist { margin-top: 0.4rem; }
.profile-body .cred { margin-top: 2.4rem; }
.profile-side .facts.facts--top { margin-top: 0; }

/* ---- W9 accessibility sweep (2026-09-08): contrast, focus rings, tap targets. Measured in headless Edge at 1280 and 390. ---- */
/* Section labels on the navy banner and closing band: accent read 1.8:1 on navy, accent-2 reads 5.1:1 */
.banner .sec-label, .cta .sec-label { color: var(--accent-2); }
/* The thank-you checklist sits inside the navy banner: steel read 1.7:1 */
.banner .checklist li { color: rgba(255,255,255,0.78); }
/* Focus rings on navy surfaces: accent-2 (5.1:1) instead of accent (1.8:1); light surfaces keep accent (7.8:1 on white) */
.site-header :focus-visible, .nav-overlay :focus-visible, .hero :focus-visible, .banner :focus-visible,
.cta :focus-visible, .section--dark :focus-visible, .site-footer :focus-visible, .ticker :focus-visible { outline-color: var(--accent-2); }
/* The pressed portfolio filter (navy fill, white text) drew a white ring on the white page: 1.07:1 */
.filters button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Form fields showed only the accent border and a faint shadow on focus; keyboard focus now gets the site ring too */
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Tap targets at 44px on phones and tablets; mouse layouts at 1280 are unchanged */
@media (max-width: 880px) {
  .brand { display: inline-flex; align-items: center; min-height: 44px; }
  .nav-phone { display: inline-block; padding: 11px 0; }
  .menu-btn { min-height: 44px; }
  .nav-overlay li a { padding: 4px 0; }
  .nav-overlay .meta a { display: inline-block; padding: 11px 0; }
  .crumbs a { display: inline-block; padding: 13px 0; }
  .site-footer .col a { padding: 0.66rem 0; }
  .tlink { display: inline-block; padding: 9px 0; }
  .filters button { min-height: 44px; }
  .quote-nav button { width: 44px; height: 44px; }
}
/* At 390 the wordmark, phone number, and Menu button overlapped in the header (pre-existing, seen in the 2026-09-04 captures).
   The Menu label goes screen-reader-only under 480px so the button keeps its name while the bars icon carries the width. */
@media (max-width: 480px) {
  .menu-btn { min-width: 44px; justify-content: center; }
  .menu-btn .lbl { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
}

/* ---- W9 residuals after the first measurement pass (2026-09-08) ---- */
/* Value-row numerals on a paper band (careers.html): accent-2 read 2.6:1 on paper; accent reads 7.3:1 */
.section--paper .value-row .no { color: var(--accent); }
/* The pressed portfolio filter's ring measured white: transition: all was animating outline-color from currentColor on focus */
.filters button { transition-property: background-color, border-color, color; }
@media (max-width: 880px) {
  .nav-phone { padding: 12px 0; }
  .crumbs a { padding: 13px 4px; margin: 0 -4px; }
  .tlink { padding: 12px 0 5px; line-height: 27px; }
  .cta .hiring a { display: inline-block; padding: 12px 0; }
}

/* ---- W10 (2026-09-08): the Martin resume is a real table; rows keep the .exp-row layout ---- */
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.exp-table { display: block; width: 100%; border-collapse: collapse; border-top: 1px solid var(--line); margin-top: 8px; }
.exp-table tbody { display: block; }
.exp-table tbody tr {
  display: grid; grid-template-columns: 1.6fr auto auto auto; gap: 0 clamp(16px, 2.5vw, 40px);
  align-items: baseline; padding: 15px 4px;
  border-bottom: 1px solid var(--line);
  transition: background .25s var(--ease), padding-left .25s var(--ease);
}
.exp-table tbody tr:hover { background: #fafaf8; padding-left: 12px; }
.exp-table th, .exp-table td { padding: 0; text-align: left; font-weight: inherit; }
.exp-table .pname { grid-column: 1; grid-row: 1; font-family: var(--font-display); font-weight: 700; font-size: 0.98rem; color: var(--ink); }
.exp-table .pclient { grid-column: 1; grid-row: 2; font-family: var(--font-body); font-weight: 400; font-size: 0.82rem; color: var(--concrete); margin-top: 2px; }
.exp-table .pyear, .exp-table .pval, .exp-table .psize {
  grid-row: 1; font-size: 0.82rem; color: var(--concrete); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.exp-table .pyear { grid-column: 2; } .exp-table .pval { grid-column: 3; color: var(--accent); font-weight: 600; } .exp-table .psize { grid-column: 4; }
@media (max-width: 640px) {
  .exp-table tbody tr { grid-template-columns: auto auto 1fr; }
  .exp-table .pname { grid-column: 1 / -1; grid-row: 1; }
  .exp-table .pclient { grid-column: 1 / -1; grid-row: 2; }
  .exp-table .pyear { grid-column: 1; grid-row: 3; } .exp-table .pval { grid-column: 2; grid-row: 3; }
  .exp-table .psize { grid-column: 3; grid-row: 3; display: inline-block; justify-self: end; }
  .exp-table .pyear, .exp-table .pval, .exp-table .psize { margin-top: 10px; } /* the old rows had a 10px row gap under the name */
}

/* launch trim 2026-09-09: placeholder blocks carry hidden + data-trim="pending" until Jacques sends the content */
[hidden] { display: none !important; }

/* 2026-09-14 · vertical video frame for the Why Covenant section (phone-shaped, click to play) */
.video-frame { width: min(100%, 360px); aspect-ratio: 9/16; margin: 0 auto; overflow: hidden; background: var(--surface-3); position: relative; }
.video-frame video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---- W15 (2026-09-14): Now Hiring button in the header, beside the logo ----
   Jacques, 2026-09-14: "put at the very top by our logo for the now hiring project
   manager nvaigation button plz". Outlined, light on navy, same idiom as the header's
   Start a Project button at a smaller size. Inline beside the brand from 900px up, with
   the full label from 1120px. Under 900px the header row carries no spare width at all
   (measured on the 09-14 header: 17px between the brand and the CTA cluster at 760px,
   zero at 700px and at 390px), so the button takes its own line directly under the logo,
   where it holds a 44px tap target and clears the phone number, Start a Project, and Menu. */
.header__hiring {
  display: inline-flex; align-items: center;
  margin-left: clamp(14px, 1.8vw, 26px); margin-right: auto;
  padding: 0.7em 1.15em; min-height: 36px;
  font-family: var(--font-display); font-weight: 700; font-size: 0.7rem;
  letter-spacing: 0.13em; text-transform: uppercase; white-space: nowrap;
  color: var(--white); background: transparent;
  border: 1px solid rgba(255,255,255,0.4); border-radius: var(--radius);
  transition: background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
.header__hiring:hover { background: var(--accent); border-color: var(--accent); color: var(--white); }
@media (max-width: 1179px) { .header__hiring-role { display: none; } }
@media (max-width: 959px) {
  .nav {
    display: grid; grid-template-columns: auto 1fr;
    grid-template-areas: "brand cta" "hiring hiring";
    align-items: center; height: auto; padding-block: 15px; row-gap: 10px;
  }
  .site-header.scrolled .nav { height: auto; padding-block: 11px; }
  .brand { grid-area: brand; }
  .nav-cta { grid-area: cta; justify-self: end; }
  .header__hiring { grid-area: hiring; justify-self: start; margin: 0; min-height: 44px; }
  .header__hiring-role { display: inline; }
  .svc, .faq, #sectors, section[id] { scroll-margin-top: 150px; }
}
@media (max-width: 639px) { .header__hiring-role { display: none; } }

/* ---- W16 (2026-09-14): portfolio banner slideshow ----
   Jacques, 2026-09-14: "on the porfolio page behind the title it says the projects
   that anchor the river valley, needs to be rotating project photos slideshow."
   Seven project photos crossfade behind the title. The shade is the hero's idiom at a
   higher floor so white text holds 4.5:1 even where a frame goes bright: worst case,
   over a pure white photo pixel, the h1 measures 7.3:1 and the .lead 5.0:1. The slides
   are absolutely positioned inside the banner, so the banner keeps its height and
   nothing shifts. */
.banner--slides { background: var(--surface); }
.hero__slides { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.hero__slide {
  position: absolute; inset: 0; display: block;
  opacity: 0; transition: opacity 1.2s var(--ease);
}
.hero__slide.is-on { opacity: 1; }
.hero__slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero__slides::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(180deg, rgba(var(--shade-rgb),0.90) 0%, rgba(var(--shade-rgb),0.70) 42%, rgba(var(--shade-rgb),0.86) 100%),
    linear-gradient(90deg, rgba(var(--shade-rgb),0.60) 0%, rgba(var(--shade-rgb),0.22) 72%);
}
.hero__slides::before {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background-image: var(--noise); opacity: 0.05;
}
/* The banner's sec-label is --accent-2 on flat navy, where W9 measured it at 5.1:1.
   Over the slideshow its worst frame measured 3.0:1, so on this one banner the label
   goes white (8.5:1 measured over the same frames). The breadcrumb links keep --mist,
   which measured 5.1:1 over the slideshow, and the hairline rule is decorative. */
.banner--slides .sec-label { color: var(--white); }
@media (prefers-reduced-motion: reduce) { .hero__slide { transition: none; } }

/* ---- W21 (2026-09-15): the six headshots fill the about banner ----
   Jacques, 2026-09-15: "we just fill the hero in the background, with all 6 headshots
   (mine included im apart of covenant) in horizontal form across the hero". This replaces
   the W17 two-by-two collage that sat beside the title. The strip is a background layer
   inside the banner, six equal columns left to right in his order, under a shade that is
   heaviest where the copy sits and lightest on the right so the portraits still read.
   Keyboard focus lifts a portrait above the strip shade, so the portrait takes a veil of
   its own at the same moment and the copy behind it does not brighten. Under 700px the six
   become two rows of three and the shade goes flat, because the copy then runs the full
   width. Contrast measured after the build; the numbers are in the 2026-09-15 report. */
.banner--team { padding-top: 200px; }
.banner--team .wrap { position: relative; z-index: 1; }
.banner--team .banner__copy { width: 46%; margin-left: auto; }
.hero__strip {
  position: absolute; inset: 0; z-index: 0; overflow: hidden;
  display: grid; grid-template-columns: repeat(6, 1fr);
}
.hero__strip::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(var(--shade-rgb),0.86) 0%, rgba(var(--shade-rgb),0.46) 46%, rgba(var(--shade-rgb),0.80) 100%),
    linear-gradient(90deg, rgba(var(--shade-rgb),0.10) 0%, rgba(var(--shade-rgb),0.13) 40%, rgba(var(--shade-rgb),0.80) 52%, rgba(var(--shade-rgb),0.86) 100%);
}
.hero__strip::before {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background-image: var(--noise); opacity: 0.05;
}
.hero__face {
  display: block; position: relative; overflow: hidden; min-width: 0;
  filter: grayscale(1); transition: filter .6s var(--ease);
}
.hero__face::after {
  content: ""; position: absolute; inset: 0;
  background: rgba(var(--shade-rgb), 0); transition: background .3s var(--ease);
}
.hero__face:hover { filter: grayscale(0); }
.hero__face:focus-visible {
  outline: 3px solid var(--white); outline-offset: -3px; z-index: 3; filter: grayscale(0);
}
.hero__face:focus-visible::after { background: rgba(var(--shade-rgb), 0.74); }
/* The banner eyebrow is --accent-2 on flat navy, where W9 measured it at 5.1:1. Over the
   portraits its worst frame measured 2.1:1, so on this banner it goes white, the same call
   W16 made on the portfolio slideshow. The breadcrumb keeps --mist. */
.banner--team .sec-label { color: var(--white); }
.hero__face picture { display: block; width: 100%; height: 100%; }
.hero__face img { width: 100%; height: 100%; object-fit: cover; object-position: center 22%; display: block; }
@media (max-width: 880px) {
  .banner--team .banner__copy { width: 100%; margin-left: 0; }
  .hero__strip::after {
    background: linear-gradient(180deg, rgba(var(--shade-rgb),0.93) 0%, rgba(var(--shade-rgb),0.84) 46%, rgba(var(--shade-rgb),0.91) 100%);
  }
}
@media (max-width: 700px) {
  .hero__strip { grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 1fr); }
}
@media (prefers-reduced-motion: reduce) { .hero__face, .hero__face::after { transition: none; } }

/* ---- W21 (2026-09-15): Justin's card carries the weight of the owner ----
   Jacques, 2026-09-15: "Justin as owner/president so put him as empahsis on the team page
   and cards". His card keeps every rule the other five have and takes a full row of its
   own at the top of the grid, photo beside the copy. The other five stay equal. */
a.person--lead {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  grid-template-rows: auto auto auto 1fr;
  column-gap: clamp(22px, 3.4vw, 48px); align-items: start;
  padding-bottom: clamp(22px, 3vw, 34px); border-bottom: 1px solid var(--line);
  margin-bottom: clamp(8px, 1.2vw, 16px);
}
a.person--lead .photo { grid-column: 1; grid-row: 1 / span 4; }
a.person--lead h3 { grid-column: 2; margin-top: 0; font-size: clamp(1.45rem, 2.6vw, 2rem); }
a.person--lead .role { grid-column: 2; font-size: var(--fs-small); letter-spacing: 0.2em; }
a.person--lead p { grid-column: 2; font-size: 1.02rem; max-width: 62ch; }
a.person--lead .view { grid-column: 2; align-self: start; }
.section--dark a.person--lead { border-bottom-color: var(--line-d); }
@media (max-width: 560px) {
  a.person--lead { grid-template-columns: 1fr; grid-template-rows: none; }
  a.person--lead .photo, a.person--lead h3, a.person--lead .role,
  a.person--lead p, a.person--lead .view { grid-column: 1; grid-row: auto; }
  a.person--lead h3 { margin-top: 1.1rem; }
}

/* ---- W18 (2026-09-14): header at phone width, air between the wordmark and the phone ----
   Ruling R7, his words: "if it needs fix then fold it into the promp". Measured on the
   W17 header: at 390px the phone number ran 16px into the wordmark and at 360px 43px,
   and a second overlap sat just above the old 480px brand step, where the 46px wordmark
   ran 23px into the phone number at 481px. Stylesheet only, no markup change: the brand
   lockup steps down earlier and in smaller steps and the header CTA cluster tightens its
   gap. The W15 button keeps its own row, and the W9 44px tap targets are untouched. */
@media (max-width: 560px) {
  .brand-img { height: 36px; }
  .brand-mark { height: 34px; margin-right: 9px; }
  .nav-cta { gap: 18px; }
}
@media (max-width: 420px) {
  .brand-img { height: 28px; }
  .brand-mark { height: 30px; margin-right: 8px; }
  .nav-cta { gap: 14px; }
}
@media (max-width: 380px) {
  .brand-img { height: 24px; }
  .brand-mark { height: 27px; margin-right: 7px; }
}
/* W25 (2026-09-15): the W18 steps stop at 380px, and the 320px reflow pass found the
   wordmark and the phone number touching again at 320 (0px of air) and nearly touching
   at 340 (4px). One more step, same idiom, stylesheet only. */
@media (max-width: 350px) {
  .brand-img { height: 20px; }
  .brand-mark { height: 24px; margin-right: 6px; }
  .nav-cta { gap: 12px; }
  .nav-phone { font-size: 0.72rem; letter-spacing: 0.04em; min-height: 44px; display: inline-flex; align-items: center; }
}

/* ---- W20 (2026-09-15): project cards are links ----
   Jacques, 2026-09-15: "let the portfolio and projects become clickable, that way it
   then becomes somewhat blog content and more stuff for SEO to scrape as overviews or
   summaries of these projects". The cards keep every rule they had; the article becomes
   an anchor and picks up the .person card's underline-on-hover affordance so the link
   is visible without a second control. */
a.project, a.feature-project { color: inherit; }
.project .view, .feature-project .view {
  display: inline-block; margin-top: 0.7rem;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent-2);
  background-image: linear-gradient(var(--accent-2), var(--accent-2));
  background-repeat: no-repeat; background-size: 0% 1px; background-position: 0 100%;
  padding-bottom: 4px; transition: background-size .35s var(--ease);
}
.feature-project .view { margin-top: 1.1rem; }
a.project:hover .view, a.feature-project:hover .view { background-size: 100% 1px; }
a.project:hover h3, a.feature-project:hover h2, a.feature-project:hover h3 { color: var(--accent-2); }
.project h3, .feature-project h2, .feature-project h3 { transition: color .25s var(--ease); }

/* ---- W25 (2026-09-15): pause and play for anything that moves ----
   WCAG 2.2.2 Level A: motion that runs past five seconds beside other content needs a
   control. One button component serves the ticker, the hero loop and the banner
   slideshow. It sits top right under the header on the hero and the banner, and centred
   at the right end of the ticker band. 40px square, 44 under 640px, which clears the
   24px minimum with room. The fill is the site shade at 0.72, so the white glyph holds
   6.4:1 over the brightest pixel any photo behind it can reach, and the hairline is white
   at 0.75 for the 3:1 that 1.4.11 asks of a control boundary. */
.motion-toggle {
  position: absolute; z-index: 5; top: 100px; right: var(--gutter);
  width: 40px; height: 40px; padding: 0;
  display: grid; place-items: center; cursor: pointer;
  color: var(--white); background: rgba(var(--shade-rgb), 0.72);
  border: 1px solid rgba(255,255,255,0.75); border-radius: var(--radius);
  transition: background .25s var(--ease), border-color .25s var(--ease);
}
.motion-toggle svg { fill: currentColor; display: block; }
.motion-toggle:hover { background: var(--accent); border-color: var(--accent); }
.ticker { position: relative; }
.ticker .motion-toggle { top: 50%; right: 10px; transform: translateY(-50%); width: 36px; height: 36px; }
/* Under 960px the header becomes two rows (W15), so the button clears 148px, the same
   line the deep-link scroll-margin uses in that state. Measured at 320: header 131px. */
@media (max-width: 959px) { .motion-toggle { top: 148px; } }
@media (max-width: 640px) {
  .motion-toggle { width: 44px; height: 44px; }
  .ticker .motion-toggle { width: 36px; height: 36px; }
}

/* WCAG 1.4.10 Reflow, measured at 320 CSS px on 2026-09-15: about.html ran to a 349px
   document because the inbox address in the plain-terms paragraph is one 40 character
   word that wants 329px in a 280px column. Long words in body copy now break rather than
   widen the page. The other 29 pages already passed at 320. */
p, dd, li, blockquote, figcaption { overflow-wrap: break-word; }

/* ---- W26 (2026-09-15): the hero photo becomes the LCP element ----
   Chrome does not count an image that fills the whole viewport as a Largest Contentful
   Paint candidate, so the fetchpriority, width and height, and srcset on the hero <img>
   did nothing and LCP landed on the header logo at 1280 and the eyebrow on phones.
   Measured 2026-09-15: at 88.9% viewport coverage the photo wins, at 98.8% it does not.
   The photo layer (photo and drone loop together) now stops at 84svh plus the 12%
   parallax headroom above the fold, so it covers 84% of any viewport, and a mask fades
   its last 140px into the navy so the edge never shows under the shade. The stat bar
   and the hero's own navy fill the rest, which they already did visually because the
   shade reaches 0.92 at the bottom. */
.hero__bg {
  inset: -12% 0 auto;
  height: calc(84vh + 12%);
  height: calc(84svh + 12%);
  -webkit-mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 140px), transparent 100%);
  mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 140px), transparent 100%);
}
/* The drone loop is a sibling of the photo layer now, not a child, and keeps the old
   full-hero box (inset -12% 0, the same parallax headroom). Once it fades in it covers
   the whole viewport, and Chrome ignores a full-viewport video the way it ignored the
   full-viewport photo, so the loop's late first frame never becomes the LCP element
   (measured: at 84% the loop's frame was counted and LCP moved out to 4.8 to 7.5 s).
   The photo underneath stays the LCP candidate at 84%. site.js moves both layers
   together for the parallax. */
.hero__vid { top: -12%; height: 124%; z-index: 0; will-change: transform; }

/* ---- W27 (2026-09-15): hero copy holds its contrast over every frame ----
   Measured from rendered pixels over twelve frames of the loop and over the still photo
   (glyphs made transparent, line boxes sampled, 5th percentile per frame): the white h1
   lines read 1.8 to 2.6 against a 3:1 bar, the accent line "River Valley." 1.4 to 2.2,
   the sub 2.7 at 320 against 4.5, and even the still photo put white roofs behind the
   h1 at 2.1 to 2.7. The shade was tuned by eye for the still and never held at the 5th
   percentile. Desktop: the horizontal gradient becomes a scrim under the copy column
   (0.73 flat to 44%, down to 0.04 by 80%), so the footage stays clear on the right where
   nothing is written over it. Phones (760px and under, the video's gate): the copy spans
   the full width, and a shade deep enough to hold 4.5:1 over a moving frame buries the
   loop, so phones took the still photo under a flat shade and no loop, the fallback the
   work order's W27 amendment allows on his 09-14 words ("make the drone footage smooth
   and sleek"). The scroll cue lifts from 0.65 to 0.85 white for the same bar.
   W36 (2026-09-16, his ruling R11: "bring the phone loop back just optimize it for
   mobile?"): the loop is back on phones through two 720x1280 sources at the same 760px
   gate, and the phone shade below is the one measured over 24 frames of that loop at 390
   and 320; the values and ratios are in DESIGN.md. */
.hero__shade {
  background:
    linear-gradient(180deg, rgba(var(--shade-rgb),0.78) 0%, rgba(var(--shade-rgb),0.30) 38%, rgba(var(--shade-rgb),0.40) 62%, rgba(var(--shade-rgb),0.92) 100%),
    linear-gradient(90deg, rgba(var(--shade-rgb),0.75) 0%, rgba(var(--shade-rgb),0.73) 44%, rgba(var(--shade-rgb),0.28) 62%, rgba(var(--shade-rgb),0.04) 80%);
}
.scroll-cue { color: rgba(255,255,255,0.85); }
@media (max-width: 760px) {
  .hero__shade {
    background: linear-gradient(180deg, rgba(var(--shade-rgb),0.84) 0%, rgba(var(--shade-rgb),0.80) 36%, rgba(var(--shade-rgb),0.81) 70%, rgba(var(--shade-rgb),0.94) 100%);
  }
}
/* The hero's pause button (44px, top right at 148px under 960px) now exists on phones, and
   at 320 the eyebrow's third line ran under it. Under 640px the eyebrow keeps 48px clear on
   the right, so its text wraps short of the button (measured: no overlap from 320 to 412,
   two lines still at 390). */
@media (max-width: 640px) {
  .hero .kicker-in-h1 { padding-right: 48px; }
}

/* ---- W31 (2026-09-15): focus never parks under the fixed header ----
   The deep-link scroll-margin-top above covers anchors, not keyboard focus (WCAG 2.4.11).
   scroll-padding-top on the root uses the same two numbers, 96px and 150px under 960px
   where the header is two rows, so a control reached by Tab or Shift+Tab is scrolled
   clear of the header. Plus 26px each: a .reveal element is still translated 26px down
   when focus scrolls it into place, and its reveal then lifts it by that much, which
   measured a card at 390 ending 2px under the header on the bare numbers. The overlay's
   focus hold is in site.js (inert on the page). */
html { scroll-padding-top: 122px; }
@media (max-width: 959px) { html { scroll-padding-top: 176px; } }

/* ---- W32 (2026-09-15): contact form corrections in text ----
   WCAG 3.3.1 and 3.3.3: the native bubbles were the whole correction path. The form now
   marks required fields in the label, and on a failed submit site.js renders a summary
   at the top (role="alert", focused, one link per field) and a line under each field
   that failed, with aria-invalid on the field. Errors are brand blue, no red: --accent
   on paper reads 7.3:1. The lone "(optional)" went so optionality is marked one way. */
.field .req { margin-left: 0.6em; font-weight: 400; letter-spacing: 0.06em; color: var(--concrete); }
.form-errors {
  margin: 0 0 1.6rem; padding: 1rem 1.2rem;
  border: 1px solid var(--accent); border-left-width: 4px; border-radius: var(--radius);
  background: var(--paper); color: var(--ink);
}
.form-errors:focus { outline: 2px solid var(--accent); outline-offset: 3px; }
.form-errors__title { font-family: var(--font-display); font-weight: 700; margin: 0 0 0.5rem; }
.form-errors ul { margin: 0; padding-left: 1.2rem; }
.form-errors li { margin: 0.3rem 0; }
.form-errors a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.field-error { margin: 0.45rem 0 0; font-size: var(--fs-small); font-weight: 600; color: var(--accent); }
.field [aria-invalid="true"] { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(23,87,122,0.18); }

/* ---- W34 (2026-09-15): banner label contrast, measured from pixels ----
   `.sec-label` on the flat navy banners is --accent-2, 5.08:1 against the --surface token,
   and 4.30 to 4.35 at the 5th percentile once the noise and the 5% monogram watermark
   composite under it on phones (4.95 at 1280, where the watermark sits clear of it).
   White, the way .banner--slides and .banner--team already set it, measures 10:1 and
   over. The CTA band keeps --accent-2: it has no watermark and measures clear. */
.banner .sec-label { color: var(--white); }

/* ---- W42 (2026-09-16, his ruling R12): the contact form as a toggle ----
   His words: "actually build it as a toggle, like career inquiry or general contact or
   something". Two real radios named role, drawn as one segmented control on the site's
   rounded token: two equal 44px cells, the checked cell filled in accent, the keyboard ring
   drawn inside the cell (white then accent, so it reads on both fills). The radios stay in
   the accessibility tree, clipped to a pixel. A field left alone in a two-column row
   (Project Type once Project Location is parked, Target Start once Budget Range is) takes
   the full row. The resume input keeps the field frame and gets a plain paper button. */
.form-mode { border: 0; margin: 0; padding: 0; min-width: 0; }
.form-mode legend {
  display: block; padding: 0; font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-micro); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--steel); margin-bottom: 0.55rem;
}
.seg {
  position: relative; display: grid; grid-template-columns: 1fr 1fr; max-width: 440px;
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
}
.seg input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.seg label {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 44px; padding: 0.6em 0.8em; cursor: pointer;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--steel);
  transition: background-color .2s, color .2s;
}
.seg label + input + label { border-left: 1px solid var(--line); }
.seg label:hover { color: var(--accent); }
.seg input:checked + label { background: var(--accent); color: var(--white); }
.seg input:focus-visible + label { box-shadow: inset 0 0 0 2px var(--white), inset 0 0 0 4px var(--accent); }
.form .row > .field:only-child { grid-column: 1 / -1; }
.field-hint { margin: 0.45rem 0 0; font-size: var(--fs-small); color: var(--concrete); }
.field input[type="file"] { padding: 0.55em 0.7em; cursor: pointer; }
.field input[type="file"]::file-selector-button {
  font: inherit; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-micro);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0.6em 0.9em; margin-right: 0.9em; cursor: pointer;
}
@media (max-width: 350px) { .seg label { letter-spacing: 0.08em; padding: 0.6em 0.5em; } }

/* ---- W42, item 27 (2026-09-16, his words "27 fix"; the sheet: "At 320 px the wordmark still
   touches the phone number. Monogram only there, or leave it?") ----
   Measured on the W41 header: at the top of the page the W18 and W25 steps hold (25px of air
   at 320), but once the page scrolls 24px the .scrolled rules at lines 186 and 914 outrank
   the steps (three classes against one) and the lockup springs back to a 38px wordmark and a
   36px monogram: the wordmark then runs 42px into the phone number at 320, 37 at 340, 40 at
   360 and 11 at 390. That is the touch the sheet saw. Two rules, stylesheet only: the scrolled
   header keeps the stepped heights on every phone width, and under 340px the header shows the
   monogram alone. The wordmark is clipped to a pixel there, not display none, so its alt still
   names the brand link (the monogram's alt is empty by design). The footer wordmark is untouched. */
@media (max-width: 560px) {
  .site-header.scrolled .brand-img { height: 36px; }
  .site-header.scrolled .brand-mark { height: 34px; }
}
@media (max-width: 420px) {
  .site-header.scrolled .brand-img { height: 28px; }
  .site-header.scrolled .brand-mark { height: 30px; }
}
@media (max-width: 380px) {
  .site-header.scrolled .brand-img { height: 24px; }
  .site-header.scrolled .brand-mark { height: 27px; }
}
@media (max-width: 350px) {
  .site-header.scrolled .brand-img { height: 20px; }
  .site-header.scrolled .brand-mark { height: 24px; }
}
@media (max-width: 339px) {
  .site-header .brand-img, .site-header.scrolled .brand-img { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
  .site-header .brand-mark, .site-header.scrolled .brand-mark { height: 32px; margin-right: 0; }
}

/* ---- Privacy wiring (W43, 2026-09-17) ---- */
/* The footer legal row now carries a Privacy link. The global rule is `a { color: inherit;
   text-decoration: none }`, so before this the link rendered as plain text in the row. White at
   78 percent on --surface is 9.1:1; the row itself sits at 55 percent. */
.site-footer .legal a { color: rgba(255,255,255,0.78); text-decoration: underline; text-underline-offset: 3px; }
.site-footer .legal a:hover { color: var(--accent-2); }

/* privacy.html is the site's first long-form text section: bare <p>, <h3> and <ul> inside
   .section .wrap, which no component class covers, so its lines ran the full 1165px wrap at
   1280 where every other page's body copy caps between 535 and 795. Same 72ch cap as .cred. */
.legal-body > p, .legal-body > ul, .legal-body > h3 { max-width: 72ch; }

/* The same Privacy link in its two places on paper: the line under the contact form's submit
   button and the posting's How to apply block. Accent with an underline, matching
   `.value-row p a`. The posting's own "form on our contact page" link picks this up too; it had
   been rendering as plain body text since W12. These two selectors reach nothing else: they are
   the only `.form .small` and `.cred p` elements on the site that hold a link. */
.form .small a, .cred p a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
