/* ==========================================================================
   CKSF Construction — main stylesheet
   Palette sampled from the CKSF logo. Orange #F8AA41 is only ~2:1 on white,
   so on light backgrounds it is used for rules/fills/marks and NEVER for
   body text; --orange-ink is the accessible text variant.
   ========================================================================== */

:root {
  /* colour */
  --ink:          #0E0E0F;
  --ink-soft:     #1C1C1E;
  --ink-line:     #2E2E31;
  --orange:       #F8AA41;   /* brand, sampled from logo */
  --orange-ink:   #B96D06;   /* accessible orange text on light */
  --orange-deep:  #E08A1C;
  --paper:        #F7F6F4;
  --paper-warm:   #EFEDE8;
  --stone:        #DCD8D1;
  --slate:        #56544F;
  --body:         #1A1A1B;

  /* type */
  --display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --sans:    "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono:    "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* rhythm */
  --gut:      clamp(1.25rem, 4vw, 2.5rem);
  --bay:      clamp(3.5rem, 9vw, 7.5rem);
  --measure:  68ch;
  --maxw:     1440px;

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

/* --------------------------------------------------------------- reset -- */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--body);
  font-family: var(--sans);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a   { color: inherit; }

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

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

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

.skip {
  position: absolute; left: -9999px;
  background: var(--orange); color: var(--ink);
  padding: 0.75rem 1.25rem; z-index: 200;
  font-family: var(--mono); font-size: 0.8rem;
}
.skip:focus { left: 1rem; top: 1rem; }

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gut);
}

/* ------------------------------------------------------- drafting marks -- */
/* The site's signature device: annotation lettering borrowed from the way
   construction drawings are labelled. */

.mono {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.eyebrow {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--orange-ink);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.75rem;
}
.eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--stone);
}
.on-dark .eyebrow { color: var(--orange); }
.on-dark .eyebrow::after { background: var(--ink-line); }

/* stage marker — completed / in progress / in design */
.stage {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--slate);
}
.stage::before {
  content: "";
  width: 9px; height: 9px;
  border: 1.5px solid var(--orange-deep);
  flex: none;
}
.stage[data-stage="complete"]::before { background: var(--orange-deep); }
.stage[data-stage="progress"]::before {
  background: linear-gradient(90deg, var(--orange-deep) 50%, transparent 50%);
}
.stage[data-stage="design"]::before { background: transparent; }

.on-dark .stage { color: #9C9A95; }
.on-dark .stage::before { border-color: var(--orange); }
.on-dark .stage[data-stage="complete"]::before { background: var(--orange); }
.on-dark .stage[data-stage="progress"]::before {
  background: linear-gradient(90deg, var(--orange) 50%, transparent 50%);
}

/* ------------------------------------------------------------- header --- */

.hdr {
  position: absolute; inset: 0 0 auto 0;
  z-index: 100;
  padding-block: 1.5rem;
}
.hdr-in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
}
.hdr.is-solid {
  position: sticky; top: 0;
  background: var(--paper);
  border-bottom: 1px solid var(--stone);
}

.brand { display: flex; align-items: center; gap: 0.85rem; text-decoration: none; }
.brand-mark { width: 66px; height: auto; flex: none; display: block; }
.brand .mark-dark { display: none; }
.hdr.is-solid .brand .mark-light { display: none; }
.hdr.is-solid .brand .mark-dark  { display: block; }
.brand-tx { line-height: 1.1; }
.brand-tx b {
  display: block;
  font-family: var(--display); font-weight: 800;
  font-size: 1.5rem; letter-spacing: 0.01em; text-transform: uppercase;
}
.brand-tx span {
  display: block;
  font-family: var(--mono); font-size: 0.74rem;
  letter-spacing: 0.17em; text-transform: uppercase;
  color: var(--slate);
}
.hdr:not(.is-solid) .brand-tx b { color: #fff; }
.hdr:not(.is-solid) .brand-tx span { color: rgba(255,255,255,0.62); }

.nav { display: flex; align-items: center; gap: clamp(1rem, 2.5vw, 2.25rem); }
.nav a {
  font-family: var(--mono);
  font-size: 0.92rem; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  text-decoration: none;
  padding-block: 0.4rem;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.hdr:not(.is-solid) .nav a { color: rgba(255,255,255,0.86); }
.nav a:hover { border-bottom-color: var(--orange); }
.nav a[aria-current="page"] { border-bottom-color: var(--orange); }

/* Over a photo the header can land on a bright highlight — a soft shadow keeps
   it readable without darkening the image back down. */
.hdr:not(.is-solid) .brand-tx b,
.hdr:not(.is-solid) .brand-tx span,
.hdr:not(.is-solid) .nav a {
  text-shadow: 0 1px 16px rgba(8,8,9,0.8);
}

.nav-btn { display: none; background: none; border: 0; padding: 0.5rem; cursor: pointer; }
.nav-btn span { display: block; width: 24px; height: 2px; background: currentColor; margin: 5px 0; }
.hdr:not(.is-solid) .nav-btn { color: #fff; }

/* --------------------------------------------------------------- hero --- */

.hero {
  position: relative;
  min-height: min(92vh, 900px);
  display: flex; align-items: flex-end;
  background: var(--ink);
  color: #fff;
  overflow: hidden;
}
.hero-slides { position: absolute; inset: 0; }
.hero-slide {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.1s var(--ease);
}
.hero-slide.is-on { opacity: 0.86; }

/* slideshow caption + controls */
.hero-bar {
  position: relative; z-index: 2;
  pointer-events: auto;            /* dots, pause and the project name still click */
  margin-top: 1.25rem;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 1rem 1.5rem; justify-content: space-between;
}
.hero-now { display: flex; align-items: center; gap: 0.9rem; min-height: 20px; }
.hero-now b,
.hero-now .hero-name {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: #fff;
}
.hero-now .hero-name {
  text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,0.35);
  padding-bottom: 2px;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.hero-now .hero-name:hover { color: var(--orange); border-bottom-color: var(--orange); }

.hero-ctl { display: flex; align-items: center; gap: 0.55rem; }
.hero-dot {
  width: 26px; height: 3px; padding: 0;
  border: 0; background: rgba(255,255,255,0.32);
  cursor: pointer; transition: background 0.3s var(--ease);
}
.hero-dot.is-on { background: var(--orange); }
.hero-dot:hover { background: rgba(255,255,255,0.7); }
.hero-pause {
  margin-left: 0.6rem;
  background: none; border: 1px solid rgba(255,255,255,0.35); color: #fff;
  width: 30px; height: 30px; cursor: pointer;
  font-size: 0.7rem; line-height: 1; display: grid; place-items: center;
}
.hero-pause:hover { background: var(--orange); color: var(--ink); border-color: var(--orange); }
.hero::after {
  content: "";
  position: absolute; inset: 0;
  /* The type all sits in the lower ~45%, so the top and middle are left almost
     clear and the shading is concentrated where the words actually are. */
  background: linear-gradient(180deg,
    rgba(14,14,15,0.46) 0%,
    rgba(14,14,15,0.04) 34%,
    rgba(14,14,15,0.30) 56%,
    rgba(14,14,15,0.68) 78%,
    rgba(14,14,15,0.90) 100%);
}
/* Covers the WHOLE hero photo. Stacking alone cannot do this: .hero-in has a
   z-index, so it opens a stacking context and any z-index on the controls
   inside it is trapped there. So .hero-in stays on top (its type must sit
   above the ::after gradient) but stops taking clicks, and only .hero-bar —
   which holds every control in the hero — takes them back.

   Clicks on the headline therefore fall through to this link. The cost is
   that the headline is no longer selectable text; on a hero that is worth it. */
.hero-link { position: absolute; inset: 0; z-index: 3; cursor: pointer; }

.hero-in {
  position: relative; z-index: 4; width: 100%;
  padding-block: clamp(3rem, 8vw, 6rem);
  pointer-events: none;          /* the photo underneath is the link */
}

/* Understated hero. The photography carries the page, so the type stays
   quiet: sentence case, mid weight, no accent colour, modest size. */
.hero h1 {
  font-size: clamp(1.55rem, 3.3vw, 2.85rem);
  font-weight: 600;
  text-transform: none;
  letter-spacing: -0.005em;
  line-height: 1.2;
  color: #fff;
  max-width: 20ch;
}
.hero-sub {
  font-size: clamp(0.95rem, 0.92rem + 0.2vw, 1.05rem);
  color: rgba(255,255,255,0.88);
  max-width: 44ch;
  margin-top: 1.25rem;
}

/* The slideshow runs across images of very different brightness — a wide,
   soft shadow keeps the type readable over all of them without reading as a
   drop shadow. */
.hero h1, .hero-sub { text-shadow: 0 1px 26px rgba(8,8,9,0.78); }

/* drafting annotation strip along the base of the hero */
.hero-strip {
  position: relative; z-index: 2;
  border-top: 1px solid rgba(255,255,255,0.22);
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-top: 1.1rem;
  display: flex; flex-wrap: wrap; gap: 1rem clamp(1.5rem, 4vw, 3.5rem);
}
.hero-strip span {
  font-family: var(--mono); font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(255,255,255,0.7);
}
.hero-strip span b { color: var(--orange); font-weight: 500; }

/* ----------------------------------------------------------- page head -- */
/* Compact dark band on inner pages, keeping the dark/light rhythm of the home
   page. Top padding clears the absolutely-positioned header. */

.phead {
  position: relative;
  overflow: hidden;
  background: var(--ink);
  color: rgba(255,255,255,0.72);
  /* top value clears the absolutely-positioned header, measured at ~94px */
  padding-block: clamp(8rem, 15vw, 11rem) clamp(3rem, 7vw, 5rem);
}

/* optional photographic backdrop, same treatment as the home hero but darker,
   because these heads carry more running text */
.phead-img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0.44;
}
/* harmless without an image: the same near-black over a near-black background */
.phead::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(14,14,15,0.74) 0%, rgba(14,14,15,0.40) 45%, rgba(14,14,15,0.90) 100%);
}
.phead > .wrap { position: relative; z-index: 2; }
.phead h1, .phead > .wrap > p { text-shadow: 0 1px 30px rgba(8,8,9,0.55); }
.phead h1 {
  color: #fff;
  font-size: clamp(2.1rem, 6vw, 4.75rem);
  max-width: 18ch;
}
.phead p {
  margin-top: 1.5rem;
  max-width: 52ch;
  color: rgba(255,255,255,0.72);
  font-size: clamp(1rem, 0.96rem + 0.3vw, 1.15rem);
}
.phead .stage { margin-bottom: 1.5rem; }

.crumb {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: rgba(255,255,255,0.5);
  margin-bottom: 1.75rem;
}
.crumb a { color: var(--orange); text-decoration: none; }
.crumb a:hover { text-decoration: underline; }

/* ------------------------------------------------------------ sections -- */

.bay { padding-block: var(--bay); }
.bay-dark { background: var(--ink); color: rgba(255,255,255,0.78); }
.bay-warm { background: var(--paper-warm); }

.bay-head { margin-bottom: clamp(2.5rem, 6vw, 4rem); }
.bay-head h2 { font-size: clamp(1.85rem, 4.5vw, 3.5rem); max-width: 20ch; }
.bay-dark h2, .bay-dark h3 { color: #fff; }
.bay-lede {
  margin-top: 1.5rem;
  font-size: clamp(1.02rem, 0.98rem + 0.3vw, 1.18rem);
  color: var(--slate);
  max-width: 56ch;
}
.bay-dark .bay-lede { color: rgba(255,255,255,0.7); }

/* -------------------------------------------------------------- filter -- */
/* Hidden until main.js unhides it, so a browser without JS never shows a
   control that cannot work. */

.filter {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.6rem 0.8rem;
  margin-bottom: clamp(2.25rem, 5vw, 3.25rem);
  padding-bottom: 1.4rem;
  border-bottom: 1px solid var(--stone);
}
.filter[hidden] { display: none; }


.filter-lb {
  font-family: var(--mono); font-size: 0.68rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--slate); margin-right: 0.35rem;
}
.filter-btn {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  background: none; border: 1px solid var(--stone); color: var(--slate);
  padding: 0.62rem 1.15rem; cursor: pointer;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.filter-btn:hover { border-color: var(--ink); color: var(--body); }
.filter-btn[aria-pressed="true"] {
  background: var(--ink); border-color: var(--ink); color: #fff;
}

/* screen-reader-only live region for the filter result */
.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;
}

/* ------------------------------------------------------- project rows --- */

/* A hairline between projects, with equal air above and below it. The rule
   does the separating, so the rows themselves carry no extra decoration.
   `.is-first` is set by the filter in main.js — CSS sibling selectors cannot
   find the first *visible* row once arbitrary rows in the middle are hidden. */
.rows { display: grid; gap: 0; }

.row {
  display: grid; gap: clamp(1.25rem, 3vw, 2.5rem); align-items: center;
  border-top: 1px solid var(--stone);
  margin-top: clamp(2.25rem, 5vw, 3.5rem);
  padding-top: clamp(2.25rem, 5vw, 3.5rem);
}
.rows > .row:first-child,
.rows > .row.is-first {
  border-top: 0; margin-top: 0; padding-top: 0;
}
/* beats .row's display:grid when the filter hides a project */
.row[hidden] { display: none; }

@media (min-width: 900px) {
  .row { grid-template-columns: 1.35fr 1fr; }
  /* Alternating rows put the figure second. The column widths have to flip
     with it, otherwise the image lands in the narrow column and every other
     photo renders smaller than the rest. */
  .row:nth-child(even) { grid-template-columns: 1fr 1.35fr; }
  .row:nth-child(even) > .row-fig { order: 2; }
}

.row-fig { position: relative; margin: 0; overflow: hidden; background: var(--paper-warm); }
.row-fig img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  transition: transform 0.7s var(--ease);
}
.row:hover .row-fig img { transform: scale(1.03); }
.row-fig figcaption {
  position: absolute; left: 0; bottom: 0;
  background: var(--ink);
  padding: 0.6rem 0.9rem;
}
.row-fig figcaption .stage { color: rgba(255,255,255,0.9); }
.row-fig figcaption .stage::before { border-color: var(--orange); }

.row-body h3 { font-size: clamp(1.5rem, 3vw, 2.35rem); margin-bottom: 1rem; }
.row-body p { color: var(--slate); }
.bay-dark .row-body p { color: rgba(255,255,255,0.72); }

/* metadata table, set like a drawing's title block */
.meta {
  margin: 1.75rem 0 0;
  border-top: 1px solid var(--stone);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0;
}
.bay-dark .meta { border-top-color: var(--ink-line); }
.meta dt, .meta dd {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--stone);
  margin: 0;
}
.bay-dark .meta dt, .bay-dark .meta dd { border-bottom-color: var(--ink-line); }
.meta dt { color: var(--slate); padding-right: 2rem; }
.meta dd { color: var(--body); font-weight: 500; }
.bay-dark .meta dt { color: rgba(255,255,255,0.5); }
.bay-dark .meta dd { color: #fff; }

/* ------------------------------------------------------- project cards -- */
/* Compact alternative to .rows — three projects side by side instead of three
   full-width bands, so the home page does not run on. */

.pcards { display: grid; gap: clamp(1.75rem, 3vw, 2.5rem); }
/* three cards never divide evenly into two columns, so the 2-up band is kept
   as narrow as the cards will allow before going to a full 3-up row */
@media (min-width: 700px) { .pcards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 920px) { .pcards { grid-template-columns: repeat(3, 1fr); } }

.pcard { display: flex; flex-direction: column; }

.pcard-fig {
  position: relative; margin: 0 0 1.15rem;
  overflow: hidden; background: var(--paper-warm);
}
.pcard-fig img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  transition: transform 0.7s var(--ease);
}
.pcard:hover .pcard-fig img { transform: scale(1.03); }
.pcard-fig figcaption {
  position: absolute; left: 0; bottom: 0;
  background: var(--ink); padding: 0.55rem 0.85rem;
}
.pcard-fig figcaption .stage { color: rgba(255,255,255,0.9); }
.pcard-fig figcaption .stage::before { border-color: var(--orange); }
.pcard-fig figcaption .stage[data-stage="complete"]::before { background: var(--orange); }
.pcard-fig figcaption .stage[data-stage="progress"]::before {
  background: linear-gradient(90deg, var(--orange) 50%, transparent 50%);
}

.pcard h3 { font-size: clamp(1.2rem, 2vw, 1.5rem); margin-bottom: 0.55rem; }

.pcard-meta {
  font-family: var(--mono); font-size: 0.67rem; font-weight: 500;
  letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--slate); margin-bottom: 0.9rem;
}

.pcard p { color: var(--slate); font-size: 0.95rem; margin-bottom: 1.2rem; }
.pcard .arrow-link { margin-top: auto; align-self: flex-start; }

/* Two-up variant for the projects page: larger photos, two to a row, with
   the detail each card no longer carries living on the project page itself. */
.pgrid { display: grid; gap: clamp(1.75rem, 3.5vw, 3rem) clamp(1.5rem, 3vw, 2.5rem); }
@media (min-width: 700px) { .pgrid { grid-template-columns: repeat(2, 1fr); } }
.pgrid .pcard h3 { font-size: clamp(1.35rem, 2.4vw, 1.8rem); }
.pgrid .pcard h3 a { text-decoration: none; }
.pgrid .pcard h3 a:hover { color: var(--orange-ink); }
/* the sector filter hides cards with the hidden attribute, which the
   pcard's own display:flex would otherwise override */
.pcard[hidden] { display: none; }

/* ------------------------------------------------- clickable photos --- */

/* The photo is what people reach for first, so it goes to the project page
   just like the "View project" link beside it. The markup carries
   tabindex="-1": that text link is already in the tab order, and two stops
   to the same page is only noise for anyone on a keyboard. */
.fig-link { display: block; }
.fig-link:focus-visible { outline: 2px solid var(--orange); outline-offset: -4px; }

/* The stage badge sits on top of the photo. Without this it swallows clicks
   and leaves a dead corner in an image that is otherwise all link. */
.row-fig figcaption,
.pcard-fig figcaption { pointer-events: none; }

/* -------------------------------------------------------- plotter pass --- */

/* Project photos draw themselves on the way a plotter lays down a sheet:
   wiped left to right with a thin orange head riding the leading edge. It
   keys off the same .is-in the scroll reveal already sets, so it fires once
   and costs no extra JS. Grids sweep card by card, not all at once. */
@keyframes plot-img  { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes plot-head {
  from { left: 0; opacity: 1; }
  88%  { opacity: 1; }
  to   { left: 100%; opacity: 0; }
}

.is-in .row-fig img,
.is-in .pcard-fig img,
.is-in .pos-fig img { animation: plot-img 0.8s var(--ease) both; }

.pos-fig { position: relative; }   /* row-fig and pcard-fig already are */
.row-fig::after, .pcard-fig::after, .pos-fig::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: 100%;
  width: 2px; background: var(--orange); opacity: 0; pointer-events: none;
}
.is-in .row-fig::after,
.is-in .pcard-fig::after,
.is-in .pos-fig::after { animation: plot-head 0.8s var(--ease) both; }

.pcards.is-in .pcard:nth-child(2) .pcard-fig img,
.pcards.is-in .pcard:nth-child(2) .pcard-fig::after { animation-delay: 0.15s; }
.pcards.is-in .pcard:nth-child(3) .pcard-fig img,
.pcards.is-in .pcard:nth-child(3) .pcard-fig::after { animation-delay: 0.3s; }
.pos-figs.is-in .pos-fig:nth-child(2) img,
.pos-figs.is-in .pos-fig:nth-child(2)::after { animation-delay: 0.15s; }

/* The visible hero slide drifts a few percent across its whole dwell, so the
   room feels occupied rather than photographed. 7s outlasts the 5.2s dwell
   plus the 1.1s crossfade — the movement never visibly stops. */
@keyframes hero-drift { from { transform: scale(1); } to { transform: scale(1.045); } }
.hero-slide.is-on { animation: hero-drift 7s linear both; }

/* Hover invitation on the photo links — mirrors the stage badge on the
   opposite corner and names the same action as the text link beside it.
   Cursor devices only; on touch the tap itself is the affordance. */
@media (hover: hover) and (pointer: fine) {
  .fig-link { position: relative; }
  .fig-link::after {
    content: "View project \2192";
    position: absolute; right: 0; bottom: 0;
    background: var(--ink); color: #fff;
    font-family: var(--mono); font-size: 0.68rem; font-weight: 500;
    letter-spacing: 0.16em; text-transform: uppercase;
    padding: 0.6rem 0.9rem;
    opacity: 0; transform: translateY(6px);
    transition: opacity 0.25s var(--ease), transform 0.25s var(--ease);
  }
  .fig-link:hover::after { opacity: 1; transform: none; }
}

/* Only work in progress moves: the half-filled square breathes like a site
   light. Completed and designed work is done drawing — it holds still. */
@keyframes stage-breathe { 50% { opacity: 0.35; } }
.stage[data-stage="progress"]::before { animation: stage-breathe 2.4s ease-in-out infinite; }

::selection { background: var(--orange); color: var(--ink); }

/* ---------------------------------------------------------- link/button - */

.btn {
  display: inline-flex; align-items: center; gap: 0.7rem;
  font-family: var(--mono); font-size: 0.76rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  text-decoration: none;
  padding: 0.95rem 1.5rem;
  background: var(--ink); color: #fff;
  border: 1px solid var(--ink);
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.btn:hover { background: var(--orange-deep); border-color: var(--orange-deep); color: var(--ink); }
.btn-ghost { background: transparent; color: var(--body); }
.btn-ghost:hover { background: var(--ink); color: #fff; border-color: var(--ink); }
.on-dark .btn-ghost, .bay-dark .btn-ghost { color: #fff; border-color: rgba(255,255,255,0.4); }
.on-dark .btn-ghost:hover, .bay-dark .btn-ghost:hover { background: var(--orange); color: var(--ink); border-color: var(--orange); }

.arrow-link {
  display: inline-flex; align-items: center; gap: 0.6rem;
  font-family: var(--mono); font-size: 0.74rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  text-decoration: none; color: var(--orange-ink);
  border-bottom: 1px solid currentColor;
  padding-bottom: 0.2rem;
}
.bay-dark .arrow-link { color: var(--orange); }
.arrow-link:hover { gap: 1rem; transition: gap 0.2s var(--ease); }

/* ------------------------------------------------------------ services -- */

/* -------------------------------------------------- what we do (home) --- */
/* Text beside a pair of images showing the two ends of the work — a scheme
   still on the drawing board, and a house that got built. They are different
   projects, so each caption names its own; this is not a before and after. */

.pos { display: grid; gap: clamp(2.5rem, 6vw, 4rem); }
@media (min-width: 900px) {
  .pos { grid-template-columns: 1fr 1fr; align-items: center; gap: clamp(3rem, 6vw, 5rem); }
}

.pos-figs { display: grid; gap: clamp(1rem, 2.4vw, 1.6rem); }
.pos-fig { margin: 0; }
.pos-fig img {
  width: 100%; aspect-ratio: 3 / 2; object-fit: cover; display: block;
}
.pos-fig figcaption {
  margin-top: 0.6rem;
  font-family: var(--mono); font-size: 0.68rem;
  letter-spacing: 0.1em; color: var(--slate);
}
.pos-fig figcaption b {
  display: inline-block; margin-right: 0.6rem;
  font-weight: 500; text-transform: uppercase;
  letter-spacing: 0.16em; color: var(--orange-ink);
}

.svc { display: grid; gap: 1px; background: var(--stone); border: 1px solid var(--stone); }
@media (min-width: 760px) { .svc { grid-template-columns: repeat(3, 1fr); } }
/* Home page: the same eight stages, named only. Cells are short and even, so
   they can sit tighter than the described version on /services. */
.flow-mini .svc-item { padding: clamp(1rem, 2.2vw, 1.35rem); }
.flow-mini h3 { font-size: clamp(1rem, 1.7vw, 1.15rem); margin: 0; }
.flow-mini .svc-no { margin-bottom: 0.5rem; }
@media (min-width: 560px) { .flow-mini { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .flow-mini { grid-template-columns: repeat(4, 1fr); } }

/* the 8-stage sequence: forced to even rows so it never ends on a ragged one */
.svc-flow { grid-template-columns: 1fr; }
@media (min-width: 620px)  { .svc-flow { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .svc-flow { grid-template-columns: repeat(4, 1fr); } }

.svc-item { background: var(--paper); padding: clamp(1.75rem, 4vw, 2.75rem); }
.svc-item h3 { font-size: 1.3rem; margin-bottom: 0.9rem; }
.svc-item p { color: var(--slate); font-size: 0.95rem; margin-bottom: 0; }
.svc-no {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.16em;
  color: var(--orange-ink); display: block; margin-bottom: 1.5rem;
}

/* ---------------------------------------------------------------- grid -- */

.grid { display: grid; gap: clamp(1rem, 2.5vw, 1.75rem); }
@media (min-width: 700px)  { .grid-2, .grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }

/* a supporting image sitting inside a text section; --ar sets its crop */
.fig-inline { margin: 0; overflow: hidden; background: var(--paper-warm); }
.fig-inline img {
  width: 100%; height: 100%; display: block;
  object-fit: cover; aspect-ratio: var(--ar, 4 / 3);
}
.fig-cap {
  margin-top: 0.75rem;
  font-family: var(--mono); font-size: 0.66rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--slate);
}

.shot { margin: 0; background: var(--paper-warm); overflow: hidden; }
.shot img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 3 / 2; }
.shot-tall img { aspect-ratio: 3 / 4; }

/* gallery buttons open the lightbox */
button.shot { border: 0; padding: 0; cursor: zoom-in; display: block; width: 100%; }

/* ------------------------------------------------------------ magazine -- */
/* Editorial spread system for project pages. Blocks alternate between
   full-bleed, paired, tripled and offset arrangements. Aspect ratio is passed
   per figure as --ar so orientation drives the layout without a specificity
   fight against the plain .shot rules above. */

/* a gallery is one or more labelled groups (completed / ongoing / rendered) */
.gallery-group + .gallery-group { margin-top: clamp(3.5rem, 9vw, 7rem); }

.mag { display: grid; gap: clamp(3rem, 8vw, 6.5rem); }

.mag-fig { margin: 0; }

.mag .shot { background: none; }
.mag .shot img {
  aspect-ratio: var(--ar, 3 / 2);
  width: 100%; height: 100%;
  object-fit: cover;
}

.mag-cap {
  margin-top: 0.8rem;
  font-family: var(--mono); font-size: 0.66rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--slate);
}
.mag-cap b { color: var(--orange-ink); font-weight: 500; }

/* full-bleed spread — sits outside .wrap, so no 100vw scrollbar hack */
.mag-bleed .shot img { aspect-ratio: auto; height: clamp(340px, 70vh, 720px); }
.mag-bleed .mag-cap {
  max-width: var(--maxw); margin-inline: auto;
  padding-inline: var(--gut);
}

/* full-bleed pair of verticals — the spread treatment for portrait shots.
   Deliberately NOT nested inside .mag-bleed, whose aspect-ratio:auto would
   crop these back into landscape boxes. */
.mag-bleed-duo { display: grid; gap: clamp(0.5rem, 1.4vw, 1.1rem); }
@media (min-width: 640px) { .mag-bleed-duo { grid-template-columns: 1fr 1fr; } }
.mag-bleed-duo .shot img {
  aspect-ratio: auto;
  height: clamp(400px, 80vh, 880px);
}

.mag-duo { display: grid; gap: clamp(1rem, 2.5vw, 1.75rem); }
@media (min-width: 700px) { .mag-duo { grid-template-columns: 1fr 1fr; } }

.mag-trio { display: grid; gap: clamp(0.9rem, 2vw, 1.4rem); }
@media (min-width: 640px) { .mag-trio { grid-template-columns: repeat(3, 1fr); } }

/* one image with its annotation held out in the margin */
.mag-offset { display: grid; gap: clamp(1.25rem, 3vw, 2.5rem); align-items: end; }
@media (min-width: 880px) {
  .mag-offset { grid-template-columns: 1.85fr 1fr; }
  .mag-offset.is-right { grid-template-columns: 1fr 1.85fr; }
  .mag-offset.is-right .mag-fig { order: 2; }
}

.mag-note {
  font-family: var(--mono); font-size: 0.68rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--slate);
  border-top: 1px solid var(--stone); padding-top: 0.9rem;
}
.mag-note b { display: block; color: var(--orange-ink); font-weight: 500; margin-bottom: 0.45rem; }

/* ------------------------------------------------------------ lightbox -- */

.lb {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(10,10,11,0.96);
  display: none; align-items: center; justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
}
.lb[open], .lb.is-open { display: flex; }
.lb img { max-width: 100%; max-height: 86vh; object-fit: contain; }
.lb-close, .lb-prev, .lb-next {
  position: absolute; background: none; border: 1px solid rgba(255,255,255,0.35);
  color: #fff; width: 46px; height: 46px; cursor: pointer;
  font-size: 1.1rem; line-height: 1;
}
.lb-close { top: 1.25rem; right: 1.25rem; }
.lb-prev  { left: 1.25rem;  top: 50%; transform: translateY(-50%); }
.lb-next  { right: 1.25rem; top: 50%; transform: translateY(-50%); }
.lb-close:hover, .lb-prev:hover, .lb-next:hover { background: var(--orange); color: var(--ink); border-color: var(--orange); }
.lb-count {
  position: absolute; bottom: 1.25rem; left: 50%; transform: translateX(-50%);
  font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.16em;
  color: rgba(255,255,255,0.7);
}

/* --------------------------------------------------------------- forms -- */

.contact-grid { display: grid; gap: clamp(2rem, 5vw, 4rem); }
@media (min-width: 900px) { .contact-grid { grid-template-columns: 1fr 1fr; } }

.cline { border-top: 1px solid var(--stone); padding: 1.4rem 0; }
.cline dt {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--slate); margin-bottom: 0.5rem;
}
.cline dd {
  margin: 0;
  font-family: var(--display); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.15rem, 2.5vw, 1.6rem);
  letter-spacing: -0.01em;
}
/* an email address should never be shouted in caps — people have to type it */
.cline dd.email {
  text-transform: none;
  font-size: clamp(1rem, 2.2vw, 1.3rem);
  overflow-wrap: anywhere;
}
.cline dd a { text-decoration: none; border-bottom: 2px solid var(--orange); }
.cline dd a:hover { color: var(--orange-ink); }

/* placeholder marker — content the client still needs to supply */
.todo {
  background: repeating-linear-gradient(45deg, #FFF4E0, #FFF4E0 8px, #FFEAC7 8px, #FFEAC7 16px);
  border-left: 3px solid var(--orange-deep);
  padding: 0.15em 0.45em;
  font-family: var(--mono); font-size: 0.85em; letter-spacing: 0.06em;
  color: #7A4A00;
}

/* -------------------------------------------------------------- footer -- */

.ftr { background: var(--ink); color: rgba(255,255,255,0.62); padding-block: clamp(3rem, 7vw, 5rem) 2rem; }
.ftr h2, .ftr h3 { color: #fff; }
.ftr-brand { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
.ftr-brand h3 { font-size: 1.35rem; margin-bottom: 0.85rem; }
.ftr-brand p { color: rgba(255,255,255,0.62); max-width: 52ch; }

/* label and its links on one line, wrapping only when they must */
.ftr-line {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0.5rem clamp(1rem, 3vw, 2.25rem);
  border-top: 1px solid var(--ink-line);
  padding-block: 1.05rem;
}
.ftr-line .ftr-h { margin: 0; flex: none; min-width: 5.5rem; }
.ftr-line ul {
  display: flex; flex-wrap: wrap;
  gap: 0.5rem clamp(1rem, 3vw, 2.25rem);
  list-style: none; margin: 0; padding: 0;
}
.ftr a { color: rgba(255,255,255,0.78); text-decoration: none; }
.ftr a:hover { color: var(--orange); }
.ftr-h {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--orange); margin-bottom: 1.1rem;
}
/* reset only — layout is set by .ftr-line ul above, which would otherwise be
   overridden by this rule since both have the same specificity */
.ftr ul { list-style: none; margin: 0; padding: 0; }
.ftr-base {
  margin-top: clamp(2.5rem, 6vw, 4rem); padding-top: 1.5rem;
  border-top: 1px solid var(--ink-line);
  display: flex; flex-wrap: wrap; gap: 0.75rem 2rem; justify-content: space-between;
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase;
}

/* ------------------------------------------------------------- motion --- */

.reveal { opacity: 0; transform: translateY(24px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}

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

/* ------------------------------------------------------------- mobile --- */

@media (max-width: 620px) {
  /* the tagline wraps and crowds the burger at this width */
  .brand-tx span { display: none; }
  .brand-tx b { font-size: 1.2rem; }
  .brand-mark { width: 52px; }
}

@media (max-width: 780px) {
  .nav-btn { display: block; }
  .nav {
    position: fixed; inset: 0 0 0 30%;
    background: var(--ink);
    flex-direction: column; justify-content: center; align-items: flex-start;
    gap: 1.5rem; padding: 2rem;
    transform: translateX(100%);
    transition: transform 0.35s var(--ease);
    z-index: 150;
  }
  .nav.is-open { transform: none; }
  .nav a { color: #fff !important; font-size: 0.95rem; }
  body.nav-lock { overflow: hidden; }
}

/* ---------------------------------------------------- build cost tiers -- */
/* Four finish levels side by side. Reuses the .svc cell grid, so the only
   additions are the rate line and the per-tier spec list.
   The base .svc goes to three columns, which would leave the fourth tier alone
   on a row with two dead cells showing through the gap, so the steps here are
   2 then 4 — always a full row. */
.cost { grid-template-columns: 1fr; }
@media (min-width: 620px)  { .cost { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .cost { grid-template-columns: repeat(4, 1fr); } }
.cost .svc-item { display: flex; flex-direction: column; }
.cost-rate {
  margin: 0.35rem 0 1.1rem;
  font-family: var(--display); font-weight: 800;
  font-size: clamp(1.25rem, 2.4vw, 1.7rem); letter-spacing: -0.01em;
}
.cost-rate span {
  display: block; margin-top: 0.25rem;
  font-family: var(--mono); font-weight: 400; font-size: 0.66rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--slate);
}
.cost-spec { margin: auto 0 0; border-top: 1px solid var(--stone); }
.cost-spec > div {
  display: grid; grid-template-columns: 4.6rem 1fr; gap: 0.75rem;
  padding: 0.6rem 0; border-bottom: 1px solid var(--stone);
}
.cost-spec > div:last-child { border-bottom: 0; }
.cost-spec dt {
  font-family: var(--mono); font-size: 0.6rem; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--slate);
  padding-top: 0.15rem;
}
.cost-spec dd { margin: 0; font-size: 0.88rem; }

/* the caveats are not decoration — a per-sqm figure is read as a quote */
.cost-caveat {
  margin-top: clamp(2rem, 4vw, 2.75rem);
  padding-left: 1.15rem; border-left: 3px solid var(--stone);
  font-size: 0.9rem; color: var(--slate); max-width: 62ch;
}
.cost-caveat li { margin-bottom: 0.45rem; }
