/* Artifex Heritage — Website styles
   Extends the foundation tokens; introduces site-specific editorial patterns. */

@import url("./colors_and_type.css?v=1779360100000");
@import url("https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,500;1,400&family=Libre+Caslon+Text:ital,wght@0,400;1,400&family=Lora:ital,wght@0,400;1,400&family=Manrope:wght@400;500;700&family=IBM+Plex+Sans:wght@400;500;700&display=swap");

:root {
  /* Tweakable tokens — overridden at runtime via <style id="ah-tweaks"> */
  --tw-display: "Tid Display", "Times New Roman", serif;
  --tw-body: "Inter", "Suisse Int'l", system-ui, sans-serif;
  --tw-hero-size: 108px;
  --tw-grid-cols: 4;
  /* ----------------------------------------------------------
     TEXT INK — single source of truth for every text colour.
     Both families (Inter body, Tid Display) and all sizes resolve
     here. body sets this as the inherited default; any selector
     that previously diverged (#111) now points at this token.
     The only sanctioned non-ink text colour is the #ffffff / cream
     accent used on dark backgrounds. Do not introduce new literals.
     ---------------------------------------------------------- */
  /* INK — brand text & line colour. Single source of truth; every page
     (including the homepage) resolves to this token. */
  --color-ink: #090401;
  --text-ink: var(--color-ink);
  /* ----------------------------------------------------------
     BACKGROUND — brand background colour. Single source of truth for the
     paper / section ground: body, .ah-map-section, .ah-affil,
     .ah-heritage-band, .ah-mdrawer, and the Service Area map (land base +
     cut-out overlay labels, which MUST track the section ground). White
     (#ffffff) and the land base (#ebe7dc) are separate, intentional values.
     ---------------------------------------------------------- */
  --color-background: #f2ecdd;
  --ah-header-height: 41px;
  /* Canonical hero height — applied to .ah-svc-head (image heroes) and
     .ah-process-hero (text-only heroes) so the hero-terminator (image top
     or rule) sits at the same Y on every page. */
  --ah-hero-height: 200px;
  /* HOMEPAGE hero band — content-driven height. Unlike --ah-hero-height
     (a fixed band shared by secondary heroes), this is set at runtime by
     Home.jsx to: locked top gap + headline (one or two lines) + 8px image
     clearance. It drives the frame height, the image descent/text-rise
     travel distance, and the rest-image background-size — all from one
     value, so the band shrinks/grows with the headline and the image follows
     it. Default ~desktop value for the pre-font-load frame. */
  --ah-hero-band: 200px;
  /* Locked top gap: header divider line → headline line-box top on the
     homepage hero. Held constant at every viewport width so no empty space
     accumulates above the headline when it shrinks/wraps. */
  --ah-hero-topgap: 0px;
  /* ----------------------------------------------------------
     HERO a/b VERTICAL SPACING RULE
     `a` (--hero-space-above) — distance from the bottom edge of the nav
       bar to the cap-height of a hero headline's first line.
     `b` (--hero-space-below) — distance from the baseline of the headline's
       last line to the brown 1px edge-to-edge line.
     Rule: b = 2 × a. Applies to every hero EXCEPT the homepage hero
       (‘The building is the document.’), which is explicitly exempt
       via the `data-hero-rule="exempt"` flag on its `.ah-hero` root and
       reverts to the older overlap-descenders treatment. See the
       comment on `.ah-hero-frame` below.
     Do NOT remove these tokens — secondary-page heroes consume them.
     ---------------------------------------------------------- */
  --hero-space-above: 65.36px;
  --hero-space-below: calc(var(--hero-space-above) * 2);
  /* ============================================================
     CANONICAL TYPE SCALE — SINGLE SOURCE OF TRUTH
     Four sanctioned text roles. Any component that fills one of
     these roles must reference the token rather than declaring its
     own px value. These are the ONLY sanctioned sizes for text in
     these roles. Treat 100 / 40 / 24 / 16 as the DESKTOP scale.

       Role     | Family      | Style  | Size  | Token
       ---------|-------------|--------|-------|----------------
       Hero     | Tid Display | Roman  | 100px | --type-hero
       Dek      | Tid Display | Italic | 40px  | --type-dek
       Statement| Tid Display | Italic | 64px  | --type-statement
       Subtitle | Tid Display | Roman  | 24px  | --type-subtitle
       Body     | Inter       | Roman  | 16px  | --type-body
     ============================================================ */
  --type-hero: 100px;
  --type-dek: 40px;
  /* Statement register — a single oversized italic cut shared by the homepage
     intro dek and the Service Area credo line. Deliberate pair; does NOT touch
     the standard 40px --type-dek used by every other dek on the site. */
  --type-statement: 64px;
  --type-subtitle: 24px;
  --type-body: 16px;
  /* Nav — primary nav labels. Distinct role that currently shares the Body
     value (16px) but is kept independent so the two can diverge later. */
  --type-nav: 16px;
  /* Service Area hero top buffer — rule above → heading box-top (margin).
     Separate from the Affiliations buffer below; editing one must not move
     the other. */
  --space-hero-buffer: 120px;
  /* Standard heading-to-body vertical gap. The site convention for a Tid
     Display subtitle (24px) sitting directly above Inter body (16px) is a
     14px box-margin (see .ah-service-body h3 { margin: 0 0 14px } and
     .ah-plate-title). Other documented pairings use 10px (.ah-jcard-title)
     and 18px (.ah-team-name); 14px is the most common, so it is the standard.
     This token is the single source of truth for that gap so future panels
     inherit it. */
  --space-heading-body: 14px;
  /* Affiliations hero top buffer — specified to the CAP-TOP (visible top of
     the "A"), measured from the Service Area section's settled bottom edge.
     Applied on .ah-affil with the display face's line-box-top→cap-top inset
     subtracted, so the visible cap-top lands exactly this far below the rule.
     Tuned to 134.5px so the resting gap from the last accordion rule to the
     "Affiliations" cap-top equals the "Selected Works" gap (the distance from
     the bottom of its preceding paragraph to its cap-top, measured 134.5px).
     With the column bottom-aligned and pre-sized to the tallest open state,
     the last rule is pinned at the section's bottom edge, so the buffer alone
     sets this gap and it holds in every accordion state. */
  /* Reusable section-boundary gap token. The reference is the homepage
     "Selected Works" gap: the glyph-bottom of the intro paragraph ending
     "in long service." to the cap-top of "Selected Works" = 134.5px. Any
     section boundary that wants to match that rhythm sources this token. */
  --section-gap: 134.5px;
  --space-affil-buffer: var(--section-gap);
  /* Line-box-top → cap-top inset of the 100px/1.05 display heading (measured,
     font-metric constant). Lets a buffer be specified to the visible cap-top. */
  --display-cap-inset: 14.16px;
  /* ----------------------------------------------------------
     HERO HEADLINE SIZE
     Single source of truth for every hero headline's font-size on
     every page — homepage, page-heads, service subpages, journal
     article, etc. Selectors that consume this token: .ah-hero-line,
     .ah-pagehead-title, .ah-process-hero__title, .ah-affil-hero__title,
     .ah-map-head__title, .ah-work-head__title, .ah-svc-title,
     .ah-about-hero__title, .ah-article-title.
     Derives from the canonical --type-hero token (value-identical,
     100px) so the Hero role has one root. Do not add per-hero
     font-size overrides; raise --type-hero if a different size is
     needed system-wide.
     ---------------------------------------------------------- */
  --hero-display-size: var(--type-hero);
  /* RESPONSIVE hero headline / dek sizes for the SECONDARY (non-homepage)
     heroes. Above the breakpoint they sit at the canonical token (so desktop
     is unchanged); below it they scale down with the viewport to a floor so
     they never overflow on narrow screens. The homepage hero is sized
     separately by JS (fit-to-width, clamped 56–240px) and does NOT use these.
     Consumed by: .ah-svc-title, .ah-process-hero__title, .ah-pagehead-title,
     .ah-article-title, .ah-about-hero__title (titles) and .ah-svc-tagline
     (dek). */
  --hero-fluid: clamp(48px, 8vw, var(--hero-display-size));
  --dek-fluid: clamp(22px, 3.2vw, var(--type-dek));
  /* Redirect the design-system font tokens through the tweak tokens
     so every existing var(--font-display)/var(--font-body) picks up
     the user's choice automatically. */
  --font-display: var(--tw-display);
  --font-body: var(--tw-body);

  /* ----------------------------------------------------------
     CONTENT GUTTER — single source of truth for the left edge
     of every section hero and primary content block.

     All section heroes and primary content blocks align to
     --content-gutter-left. Do not override this value per section.
     If a section needs different alignment, raise the question
     rather than introducing a one-off value.

     The reference is a single fixed 24px gutter from each
     viewport edge — identical at every resolution (desktop,
     tablet, phone). All hero and text blocks, and the content
     image grids, align their left edge to this 24px line and
     stay within the matching 24px line on the right.
     ---------------------------------------------------------- */
  --content-gutter-left: 24px;
  --content-gutter-right: 24px;

  /* ----------------------------------------------------------
     SECTION RHYTHM is not tokenised — each homepage band owns its
     own top buffer (120 / 80 / 56 across desktop / tablet / phone).
     See .ah-work-head, .ah-affil, .ah-map-section > .ah-statement.
     ---------------------------------------------------------- */
}

/* ============================================================
   HOMEPAGE GROUND — paints the body ground from the brand background
   token. The homepage no longer carries a per-page colour trial; it
   inherits the canonical :root tokens (#090401 ink / #f2ecdd ground)
   like every other page, so the brand colours have a single source of
   truth. Landmass fills and nav background stay #ffffff.
   ============================================================ */
body.home {
  background: var(--color-background);
}

@media (max-width: 1023px) {
  :root {
    /* Gutter is an absolute 24px at EVERY width — it does not grow
       on narrow screens. */
    --content-gutter-left: 24px;
    --content-gutter-right: 24px;
  }
}

* {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
  padding: 0;
  overflow-x: clip;
}
body {
  background: var(--color-background);
  color: var(--text-ink);
  font-family: var(--font-body);
  font-size: var(--type-body);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

/* --------- NAV --------- */
.ah-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: #ffffff;
  border-bottom: 1px solid var(--color-ink);
}
.ah-nav-inner {
  position: relative;
  display: flex;
  align-items: center;
  height: 40px;
  /* Left edge of the first nav item (Selected Works) sits on the standard
     24px page gutter, matching the body content and section heroes. Right
     padding unchanged (wordmark is absolutely centred; right gutter behaviour
     is intentionally independent). */
  padding: 0 14px 0 24px;
  max-width: none;
  margin: 0;
}
.ah-nav-links {
  display: flex;
  gap: 22px;
  justify-content: flex-start;
  align-items: center;
}
/* Wordmark is absolutely centred to the header rather than living in a
   symmetric 1fr/auto/1fr grid column. This decouples it from the links'
   width, so it keeps its natural single-line width and never gets squeezed
   into a wrap by the (16px) nav labels. */
.ah-nav-brand {
  position: absolute;
  left: 50%;
  top: 50%;
  /* +2px optical nudge: both the wordmark and the nav links are geometrically
     centred at band-mid, but Tid Display sets its baseline ~2px higher within
     the shared line box than Inter (the nav-link face). All-caps glyphs rest
     on that higher baseline, so the wordmark reads high. Dropping it 2px puts
     it on the nav links' baseline so the row reads level. */
  transform: translate(-50%, calc(-50% + 2px));
  display: flex;
  align-items: center;
}
.ah-nav-search {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 18px;
}
.ah-search-btn {
  appearance: none;
  background: #ededed;
  border: 0;
  padding: 0 22px;
  border-radius: 0;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 400;
  color: var(--color-ink);
  letter-spacing: 0.3px;
  cursor: pointer;
  min-width: 150px;
  height: 32px;
}
.ah-search-btn span {
  color: var(--color-ink);
}
.ah-search-btn:hover {
  background: #e6e6e6;
}
.ah-search-btn svg {
  display: block;
  color: var(--color-ink);
  width: 14px;
  height: 14px;
  stroke-width: 1.6;
}
.ah-nav-contact {
  font-size: 14px;
  color: var(--color-ink) !important;
  text-decoration: none;
  letter-spacing: 0.3px;
  white-space: nowrap;
}
.ah-wordmark {
  display: flex;
  align-items: center;
  text-decoration: none;
}
.ah-wordmark-img {
  display: block;
  height: 28px;
  width: auto;
}
.ah-wordmark:hover {
  opacity: 0.75;
}
/* legacy alias kept until all callers migrate */
.ah-nav-center {
  display: flex;
  gap: 22px;
  justify-content: flex-start;
  align-items: center;
}

/* ---- Search drawer ---- */
.ah-search-overlay {
  position: fixed;
  inset: 0;
  z-index: 998;
  background: rgba(0, 0, 0, 0);
  pointer-events: none;
  transition: background 320ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ah-search-overlay.is-open {
  background: rgba(0, 0, 0, 0.18);
  pointer-events: auto;
}
.ah-search-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  width: min(420px, 92vw);
  background: #fff;
  color: var(--color-ink);
  border-left: 1px solid var(--color-ink);
  box-shadow: -20px 0 60px rgba(0, 0, 0, 0.06);
  transform: translateX(100%);
  transition: transform 380ms cubic-bezier(0.2, 0.8, 0.2, 1);
  display: flex;
  flex-direction: column;
}
.ah-search-drawer.is-open {
  transform: translateX(0);
}
.ah-search-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 22px;
  border-bottom: 1px solid var(--color-ink);
  height: 48px;
}
.ah-search-title {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.2px;
  color: var(--color-ink);
}
.ah-search-close {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  font-size: 22px;
  line-height: 1;
  color: var(--color-ink);
  padding: 0 4px;
}
.ah-search-close:hover {
  opacity: 0.5;
}
.ah-search-body {
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 28px;
}
.ah-search-field {
  display: block;
  position: relative;
  border: 1px solid var(--color-ink);
  background: #fafaf8;
  padding: 8px 12px 8px;
}
.ah-search-field-label {
  display: block;
  font-size: 10px;
  letter-spacing: 0.2px;
  color: var(--color-ink);
  margin-bottom: 2px;
  font-family: var(--font-body);
}
.ah-search-field input {
  width: 100%;
  border: 0;
  background: transparent;
  outline: none;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--color-ink);
  padding: 0;
}
.ah-search-field input::placeholder {
  color: var(--color-ink);
}
.ah-search-trending-head {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-ink);
  margin-bottom: 14px;
}
.ah-search-trending ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ah-search-trending a {
  font-family: var(--font-body);
  font-size: 13.5px;
  color: var(--color-ink);
  text-decoration: none;
  transition: opacity 200ms ease;
}
.ah-search-trending a:hover {
  opacity: 0.55;
}
.ah-nav-item {
  position: static;
}
.ah-nav-item .ah-nav-link {
  display: inline-block;
}

/* Wide panel beneath the header (Svenskt Tenn pattern) */
.ah-nav-panel {
  position: absolute;
  left: 0;
  right: 0;
  /* Sit BELOW the nav's 1px border-bottom rather than overlapping it.
     Containing-block-percentages exclude the border, so plain top:100% would
     place us at the top of the rule and cover it; +1px clears the rule. */
  top: calc(100% + 1px);
  background: #ffffff;
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height 320ms cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity 220ms ease, border-color 320ms ease;
  pointer-events: none;
  z-index: 60;
}
.ah-nav-panel.is-open {
  /* Unified dropdown height — driven by the longest text list (5-item Services).
     Every dropdown adopts the same outer dimensions; only the content varies. */
  max-height: 320px;
  opacity: 1;
  pointer-events: auto;
  /* Shadow cast only downward against the page; negative spread prevents
     any of the blur rendering upward behind the header. */
  box-shadow: 0 12px 16px -8px rgba(9, 4, 1, 0.08);
}
.ah-nav-panel-inner {
  max-width: none;
  margin: 0;
  padding: 0;
  /* Fixed height driven by the tallest text list (5 items). Shorter lists
     vertically centre inside; the image column fills the same height. */
  height: 245px;
  min-height: 245px;
  display: flex;
  flex-direction: row;
  align-items: stretch;
}

/* Image column — flush to the panel's top, right and bottom edges. Left
   edge floats. Height = panel height (align-self: stretch); width derives
   from height via aspect-ratio: 4 / 3. */
.ah-nav-img-stack {
  position: relative;
  margin-left: auto;
  align-self: stretch;
  aspect-ratio: 4 / 3;
  background: #eadfd0; /* warm pale-stone fill matches the about-page placeholder */
  flex: 0 0 auto;
}
.ah-nav-img-link {
  position: absolute;
  inset: 0;
  display: block;
  opacity: 0;
  text-decoration: none;
  /* Default: gain-active path — wait 200ms (for the previous slot to finish
     fading out), then fade in over 200ms. */
  transition: opacity 200ms ease-out 200ms;
}
.ah-nav-img-link:not(.is-active) {
  /* Lose-active path — fade out immediately over 200ms, no delay. */
  transition: opacity 200ms ease-out 0ms;
}
.ah-nav-img-link.is-active {
  opacity: 1;
}
.ah-nav-img-link image-slot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* Hide the image-slot's empty-state caption / icon while leaving the click
   region intact for upload. The stone background of .ah-nav-img-stack
   shows through. */
.ah-nav-img-link image-slot::part(empty) {
  opacity: 0;
}
.ah-nav-panel-list {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  /* Leftmost dropdown item begins on the same 24px gutter as the nav row. */
  padding: 14px 14px 16px 24px;
  gap: 4px;
  flex: 1 1 auto;
  min-width: 0;
}
.ah-nav-panel-link {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 24px;
  line-height: 1.32;
  letter-spacing: -0.005em;
  color: var(--color-ink);
  text-decoration: none;
  padding: 4px 0;
  transition: opacity 160ms ease, transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ah-nav-panel-link:hover {
  opacity: 0.55;
}

.ah-nav-link {
  font-size: var(--type-nav);
  color: var(--color-ink) !important;
  text-decoration: none;
  letter-spacing: 0.3px;
  position: relative;
  /* 8px keeps the link box at 39.2px — within the 40px band so the grid
     row doesn't grow and align-items:center balances the row at 20px. */
  padding: 8px 0;
  display: inline-block;
  z-index: 70;
  opacity: 1 !important;
}
.ah-nav-link::after {
  content: none;
}
.ah-nav-link:hover::after,
.ah-nav-item:hover .ah-nav-link--label::after,
.ah-nav-item.is-open .ah-nav-link--label::after {
  content: none;
}
.ah-nav-link--label {
  cursor: default;
}

/* Contact nav button — invert to black-on-white pill on hover instead of underline. */
.ah-nav-cta {
  /* 5px vertical → box 33.2px, inset within the 40px band (~3.4px clearance
     top/bottom). Horizontal padding 11px (trimmed 3px/side from the original
     14px to narrow the box by 6px total). margin-left cancels the flex gap by
     the same 11px so the button's left padding doesn't widen the optical
     text-to-text gap before "Contact" — keeps the rhythm even. */
  padding: 5px 11px;
  margin-left: -11px;
  border-radius: 0;
  background: transparent;
  color: var(--color-ink) !important;
  /* Instant hover — no fade in either direction (scoped to the Contact
     button only; other nav items don't share this transition). */
  transition: none;
}
.ah-nav-cta::after {
  display: none !important;
}
.ah-nav-cta:hover {
  background: var(--color-ink);
  color: #fff !important;
}

.ah-nav-right {
  display: flex;
  gap: 20px;
  align-items: center;
  justify-content: flex-end;
}
.ah-nav-util {
  font-size: 11px;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--color-ink);
  text-decoration: none;
}
.ah-nav-util:hover {
  opacity: 0.6;
}

/* --------- MOBILE NAV — collapsed header + right-edge drawer (≤768px) --------- */
/* Three-line menu icon at the right edge of the header, inset 24px from the
   viewport (the site gutter). 44px square tap target; lines are simple 1.5px
   rules in #090401 with square caps. Hidden above the 768px breakpoint. */
.ah-burger {
  display: none;
  position: absolute;
  right: 24px;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  z-index: 2;
}
.ah-burger-glyph {
  position: relative;
  display: block;
  width: 20px;
  height: 14px;
}
.ah-burger-glyph i {
  position: absolute;
  left: 0;
  width: 20px;
  height: 1.5px;
  background: var(--color-ink);
  border-radius: 0; /* square caps, no rounded ends */
  transition: none; /* state change is instant — no morph */
}
.ah-burger-glyph i:nth-child(1) {
  top: 0;
}
.ah-burger-glyph i:nth-child(2) {
  top: 6.25px;
}
.ah-burger-glyph i:nth-child(3) {
  top: 12.5px;
}
/* Open state — a simple X of the same weight, swapped instantly. */
.ah-burger-glyph[data-open="true"] i:nth-child(1) {
  top: 6.25px;
  transform: rotate(45deg);
}
.ah-burger-glyph[data-open="true"] i:nth-child(2) {
  opacity: 0;
}
.ah-burger-glyph[data-open="true"] i:nth-child(3) {
  top: 6.25px;
  transform: rotate(-45deg);
}

/* Invisible click-catcher — closes on outside tap. No dimming scrim. Starts
   at the header's bottom edge so the header stays visible + interactive. */
.ah-mdrawer-scrim {
  position: fixed;
  top: var(--ah-drawer-top, 41px);
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1000;
  background: transparent;
  opacity: 0;
  pointer-events: none;
}
.ah-mdrawer-scrim.is-open {
  opacity: 1;
  pointer-events: auto;
}

/* The panel sits BENEATH the header: its top edge pins to the header's bottom
   edge, running to the bottom of the viewport. 420px wide (full-width below
   480px). A single 1px rule along its left edge; flat var(--color-background) ground. The
   slide-in motion timing/easing is unchanged. */
.ah-mdrawer {
  position: fixed;
  top: var(--ah-drawer-top, 41px);
  right: 0;
  bottom: 0;
  z-index: 1001;
  width: 420px;
  max-width: 100vw;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  padding: 0 24px; /* 24px gutter both sides */
  background: var(--color-background);
  border-left: 1px solid var(--color-ink);
  overflow: hidden; /* root never scrolls — keeps the X
                                          aligned to the burger regardless of
                                          any scrollbar (which lives on the
                                          inner wrapper). */
  transform: translateX(100%);
  visibility: hidden;
  /* Closing — accelerate out over 0.45s (expo ease-in). */
  transition: transform 0.45s cubic-bezier(0.7, 0, 0.84, 0),
    visibility 0s linear 0.45s;
}
.ah-mdrawer.is-open {
  transform: translateX(0);
  visibility: visible;
  /* Opening — weighted, decisive expo ease-out over 0.6s, no overshoot. */
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1),
    visibility 0s linear 0s;
}
/* Inner scroll region — holds the nav + foot; any scrollbar lives here, not on
   the panel root, so the absolutely-placed X stays on the burger's centre. */
.ah-mdrawer-scroll {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

/* Close control — the X. Absolutely placed so its horizontal centre is on the
   exact same right:24px line as the header burger (same width, same container
   right edge → same centre), sitting directly beneath the burger. Same 1.5px
   weight + #090401 + 44px tap target as the burger (inherited from .ah-burger). */
.ah-mdrawer .ah-burger--close {
  display: flex;
  position: absolute;
  top: 8px;
  right: 24px;
  transform: none;
  z-index: 2;
}

.ah-mdrawer-nav {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  padding: 64px 0 0; /* clear the absolutely-placed X */
}
/* Top-level rows — Inter, matched exactly to the desktop header nav link
   (var(--type-nav) = 16px, weight 400, #090401, 0.3px tracking, Title Case).
   No marker glyph on parents with children. */
.ah-mdrawer-parent {
  display: block;
  width: 100%;
  margin: 0;
  background: transparent;
  border: 0;
  padding: 13px 0;
  cursor: pointer;
  text-align: left;
  text-decoration: none;
  font-family: var(--font-body);
  font-size: var(--type-nav);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0.3px;
  color: var(--color-ink);
}

/* Accordion shell — animates open in height (0fr→1fr grid track), pushing the
   items below down rather than overlapping. Weighted, inertia-driven easing. */
.ah-mdrawer-childwrap {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.ah-mdrawer-children {
  overflow: hidden;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0 0 0 18px; /* indent only — no vertical padding so
                                          the track collapses fully to 0 */
}
/* Child links — same Inter size as the parent, indented. Fade in with a very
   short stagger once their accordion opens. */
.ah-mdrawer-child {
  display: block;
  font-family: var(--font-body);
  font-size: var(--type-nav);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.3px;
  color: var(--color-ink);
  text-decoration: none;
  padding: 8px 0;
  opacity: 0;
  transition: opacity 0.35s ease-out;
}
.ah-mdrawer-child:nth-child(1) {
  transition-delay: 0.08s;
}
.ah-mdrawer-child:nth-child(2) {
  transition-delay: 0.13s;
}
.ah-mdrawer-child:nth-child(3) {
  transition-delay: 0.18s;
}
.ah-mdrawer-child:nth-child(4) {
  transition-delay: 0.23s;
}
.ah-mdrawer-child:nth-child(5) {
  transition-delay: 0.28s;
}

/* Open the accordion: touch (JS .is-active) always; pointer hover + keyboard
   focus only on hover-capable devices. */
.ah-mdrawer-group.is-active > .ah-mdrawer-childwrap {
  grid-template-rows: 1fr;
}
.ah-mdrawer-group.is-active .ah-mdrawer-child {
  opacity: 1;
}
@media (hover: hover) and (pointer: fine) {
  .ah-mdrawer-group:hover > .ah-mdrawer-childwrap,
  .ah-mdrawer-group:focus-within > .ah-mdrawer-childwrap {
    grid-template-rows: 1fr;
  }
  .ah-mdrawer-group:hover .ah-mdrawer-child,
  .ah-mdrawer-group:focus-within .ah-mdrawer-child {
    opacity: 1;
  }
}

/* Hover dimming (pointer devices only): the hovered top-level item holds 100%,
   every other top-level item drops to 40%, with a brief 150ms ease-out fade.
   Leaving the nav list restores all. */
@media (hover: hover) and (pointer: fine) {
  .ah-mdrawer-parent {
    transition: opacity 0.15s ease-out;
  }
  .ah-mdrawer-nav:hover .ah-mdrawer-parent {
    opacity: 0.4;
  }
  .ah-mdrawer-group:hover .ah-mdrawer-parent {
    opacity: 1;
  }
}

/* Foot — contact email + secondary links, Inter 16px, pinned to the bottom. */
.ah-mdrawer-foot {
  flex: 0 0 auto;
  margin-top: auto;
  padding: 24px 0 32px;
  border-top: 1px solid rgba(9, 4, 1, 0.18);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.ah-mdrawer-foot a {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.4;
  color: var(--color-ink);
  text-decoration: none;
}
.ah-mdrawer-foot a:hover {
  opacity: 0.6;
}
.ah-mdrawer-foot-links {
  display: flex;
  gap: 24px;
}

/* Top-level items + foot rest hidden and fade up with a short stagger once the
   panel is open. Transition-driven so the resting open-state is a genuine
   opacity:1 — never left stuck invisible. */
.ah-mdrawer-group,
.ah-mdrawer-foot {
  opacity: 0;
  transform: translateY(14px);
}
.ah-mdrawer.is-open .ah-mdrawer-group,
.ah-mdrawer.is-open .ah-mdrawer-foot {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.ah-mdrawer.is-open .ah-mdrawer-group:nth-child(1) {
  transition-delay: 0.26s;
}
.ah-mdrawer.is-open .ah-mdrawer-group:nth-child(2) {
  transition-delay: 0.32s;
}
.ah-mdrawer.is-open .ah-mdrawer-group:nth-child(3) {
  transition-delay: 0.38s;
}
.ah-mdrawer.is-open .ah-mdrawer-group:nth-child(4) {
  transition-delay: 0.44s;
}
.ah-mdrawer.is-open .ah-mdrawer-foot {
  transition-delay: 0.5s;
}

@media (prefers-reduced-motion: reduce) {
  .ah-mdrawer,
  .ah-mdrawer.is-open {
    transition: transform 0.01s linear, visibility 0s;
  }
  .ah-mdrawer-group,
  .ah-mdrawer-foot {
    opacity: 1;
    transform: none;
  }
  .ah-mdrawer.is-open .ah-mdrawer-group,
  .ah-mdrawer.is-open .ah-mdrawer-foot {
    transition: none;
  }
  .ah-mdrawer-childwrap,
  .ah-mdrawer-child {
    transition: none;
  }
}

.ah-icon-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--color-ink);
  background: #fff;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: opacity 200ms ease;
}
.ah-icon-btn svg {
  width: 16px;
  height: 16px;
  stroke: var(--color-ink);
  fill: none;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ah-icon-btn:hover {
  opacity: 0.6;
}

/* --------- PAGE SHELL --------- */
.ah-page {
  max-width: none;
  margin: 0;
  padding: 0 var(--content-gutter-right) 0 var(--content-gutter-left);
}
.ah-page--narrow {
  max-width: 1120px;
  margin: 0 auto;
}

/* Cream-paper background for category index pages (Residential, etc.) */
/* Lenis smooth-scroll — required CSS hooks */
html.lenis,
html.lenis body {
  height: auto;
}
.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}
.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}
.lenis.lenis-stopped {
  overflow: hidden;
}
.lenis.lenis-smooth iframe {
  pointer-events: none;
}

.ah-bg-cream,
.ah-bg-mist,
.ah-bg-paper,
.ah-bg-sage {
  background: var(--color-background);
  min-height: calc(100vh - 80px);
}

.ah-section {
  padding: 120px 0;
}
.ah-section--tight {
  padding: 72px 0;
}
.ah-rule {
  height: 1px;
  background: rgba(0, 0, 0, 0.1);
  border: 0;
  margin: 0;
}

/* --------- TYPOGRAPHY PRIMITIVES --------- */
.ah-eyebrow {
  font-size: 11px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-ink);
  font-weight: 400;
}
.ah-eyebrow--mute {
  color: var(--color-ink);
}

.ah-display {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(56px, 8.2vw, 128px);
  line-height: 1.02;
  letter-spacing: -0.01em;
  margin: 0;
}
.ah-h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(44px, 5vw, 72px);
  line-height: 1.08;
  letter-spacing: -0.005em;
  margin: 0;
}
.ah-h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(32px, 3.4vw, 48px);
  line-height: 1.14;
  margin: 0;
}
.ah-h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--type-subtitle);
  line-height: 1.22;
  margin: 0;
}

.ah-sup {
  display: none;
}
.ah-sup-keep {
  font-family: var(--font-display);
  font-size: 0.42em;
  vertical-align: super;
  font-feature-settings: "sups" 1;
  margin-left: 0.18em;
  font-weight: 400;
  color: var(--color-ink);
}

.ah-lede {
  font-size: 17px;
  line-height: 1.52;
  max-width: 54ch;
  color: var(--text-ink);
}
.ah-prose p {
  font-size: 16px;
  line-height: 1.62;
  max-width: 62ch;
  margin: 0 0 1.1em;
}
.ah-prose--news p {
  font-size: 16px;
  line-height: 1.6;
}
.ah-prose p:last-child {
  margin-bottom: 0;
}
.ah-prose em {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.06em;
}

.ah-caption {
  font-size: 13px;
  color: var(--color-ink);
  line-height: 1.5;
}
.ah-meta {
  font-size: 13px;
  color: var(--color-ink);
  letter-spacing: 0.1px;
}

.ah-dateline {
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-ink);
}

/* --------- HERO (home) --------- */
/* Shared viewport-fill hero. Use .ah-fullvh-hero on any hero container that
   must occupy exactly the viewport beneath the sticky header. Headline
   content is flex:none at natural height; the gradient/figure child grows
   to absorb the remaining height down to the fold. svh measures the SMALLEST
   viewport state (mobile browser chrome visible) — the state on initial load —
   so the photo terminates exactly at the fold and the next section sits just
   below it. The header height is subtracted because the sticky nav occupies
   that much flow space above the hero. */
.ah-fullvh-hero {
  display: flex;
  flex-direction: column;
  height: calc(100svh - var(--ah-header-height));
}
.ah-fullvh-hero > .ah-fullvh-hero__body {
  flex: 1 1 0%;
  min-height: 0;
  width: 100%;
}

.ah-hero {
  display: flex;
  flex-direction: column;
  /* The hero BORDER-BOX is extended up to the very top of the viewport (y=0)
     so the descending image can cover the sticky header at the start without
     ever escaping the box: a single overflow:hidden then clips BOTH the header
     region at the top and the figure's surplus at the bottom.
       • margin-top: -header-height  → pulls the border-box top from the header
         line up to y=0 (net flow space is unchanged: the +header-height of
         height below is cancelled by this negative margin, so nothing shifts).
       • height: 100svh              → border-box bottom stays at the viewport
         floor (same as before).
       • padding-top: header-height  → keeps the flex content (the lettering
         band + figure) starting at the header line, so the headline does NOT
         move. */
  margin: calc(-1 * var(--ah-header-height))
    calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
  height: 100svh;
  padding: var(--ah-header-height) 0 0 0;
  overflow: hidden;
}
.ah-hero-figure {
  width: 100%;
  margin-left: 0;
  margin-right: 0;
  /* Tall enough to cover the WHOLE viewport (top edge to bottom edge) through
     the entire 0.5s hold + 1.2s descent: covered height (the full viewport,
     since the start top is y=0) plus the descent travel, with spare. The
     surplus overflows the hero box and is clipped by its overflow:hidden, so
     it is never visible. The visible REST crop is unchanged — the .ah-img
     gradient below is pinned to the rest height via background-size, so only
     the off-screen extent grows. */
  flex: none;
  height: calc(100svh + var(--ah-hero-band));
  min-height: 0;
  position: relative;
  overflow: hidden;
  z-index: 2; /* rest state: above the static lettering band, below the sticky
                 header (z 50). The keyframes lift it to 200 during the descent
                 so it covers the header, then it returns here on settle so the
                 sticky nav sits above it again on subsequent scroll. */
  /* The hero baseline→image gap is now produced by the band
     (.ah-hero-frame padding-bottom), matching the Windows hero mechanism,
     so the image no longer rides up under the descenders. */
  margin-top: 0;
  font-size: var(--tw-hero-size, 108px);
  background: #eadfd0;
  /* Reveal movement: the figure begins shifted up so its TOP EDGE sits at the
     very top of the viewport (y=0), covering the whole screen above its rest
     position INCLUDING the sticky header/nav (the keyframes raise z-index to
     200 so it paints over the header). Combined with its over-tall height it
     covers the full viewport — top edge to bottom edge — with no page content
     showing at either edge. On load it HOLDS that covering position for 0.5s
     (the animation-delay), then the IMAGE ELEMENT ITSELF translates downward
     to its rest position over 1.2s, uncovering the header first and then the
     lettering top-down. Nothing else moves — not the page, not the text, not a
     mask. Easing is GSAP's expo.inOut, sampled into a native CSS linear()
     function (no JS/GSAP runtime needed, pure-CSS replay-on-reload preserved).
     Over 3.0s it reads as a gentle slow start (~4.7% travel by 33% time),
     acceleration through the middle (50% at half time, ~94.6% by 66% time),
     then a long exponential, asymptotic crawl that eases the final approach
     into rest pixel by pixel over roughly the last second. Once settled the
     z-index returns to 2 so the sticky header sits above it again. Replays
     every load — no JS, no session gating. */
  transform: translateY(
    calc(-1 * (var(--ah-header-height) + var(--ah-hero-band)))
  );
  animation: ah-hero-img-descend 3000ms 0ms
    linear(
      0 0%,
      0.0006 1.7%,
      0.0008 3.3%,
      0.001 5%,
      0.0012 6.7%,
      0.0015 8.3%,
      0.002 10%,
      0.0025 11.7%,
      0.0031 13.3%,
      0.0039 15%,
      0.0049 16.7%,
      0.0062 18.3%,
      0.0078 20%,
      0.0099 21.7%,
      0.0123 23.3%,
      0.0156 25%,
      0.0198 26.7%,
      0.0247 28.3%,
      0.0313 30%,
      0.0396 31.7%,
      0.0494 33.3%,
      0.0625 35%,
      0.0791 36.7%,
      0.0988 38.3%,
      0.125 40%,
      0.1582 41.7%,
      0.1975 43.3%,
      0.25 45%,
      0.2872 46%,
      0.3164 46.7%,
      0.3789 48%,
      0.395 48.3%,
      0.5 50%,
      0.605 51.7%,
      0.6211 52%,
      0.6836 53.3%,
      0.7128 54%,
      0.75 55%,
      0.8025 56.7%,
      0.8418 58.3%,
      0.875 60%,
      0.9012 61.7%,
      0.9209 63.3%,
      0.9375 65%,
      0.9456 66%,
      0.9506 66.7%,
      0.9604 68.3%,
      0.9688 70%,
      0.9753 71.7%,
      0.9763 72%,
      0.9802 73.3%,
      0.9844 75%,
      0.9877 76.7%,
      0.9901 78.3%,
      0.9922 80%,
      0.9938 81.7%,
      0.9951 83.3%,
      0.9961 85%,
      0.9969 86.7%,
      0.9974 88%,
      0.9975 88.3%,
      0.998 90%,
      0.9985 91.7%,
      0.9988 93.3%,
      0.9989 94%,
      0.999 95%,
      0.9992 96.7%,
      0.9994 98.3%,
      1 100%
    )
    both;
}
@keyframes ah-hero-img-descend {
  from {
    transform: translateY(
      calc(-1 * (var(--ah-header-height) + var(--ah-hero-band)))
    );
    z-index: 200;
  }
  99% {
    z-index: 200;
  }
  to {
    transform: translateY(0);
    z-index: 2;
  }
}
.ah-hero-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Hero cover image: pin the gradient framing to the REST height regardless of
   the figure's (now taller) box, so extending the figure downward to cover the
   viewport floor during the descent does NOT restretch/reframe the settled
   image. Below the gradient, continue its dark end colour (#5d4827) seamlessly
   so the clipped surplus matches the image's bottom edge. */
.ah-hero-figure .ah-img {
  background-size: 100%
    calc(100svh - var(--ah-header-height) - var(--ah-hero-band));
  background-repeat: no-repeat;
  background-position: top;
  background-color: #5d4827;
}
.ah-hero-figure--delay {
  animation-delay: 1600ms;
}
/* Homepage hero — the hero-baseline → image-top gap is now produced by the
   SAME mechanism every secondary hero uses: a fixed-height headline band of
   --ah-hero-height with 24px top padding, the headline sitting at the top,
   and the figure (flex:1) filling the rest. This is identical to .ah-svc-head
   on the Windows/service heroes, so the gap is driven by the shared
   --ah-hero-height token rather than a homepage-specific offset. Horizontal
   padding stays 0 so the headline keeps the homepage's 14px reference gutter
   (inherited from the .ah-page shell) instead of svc-head's 24px inset. */
.ah-hero-frame {
  display: block;
  flex: none;
  height: var(--ah-hero-band);
  padding: var(--ah-hero-topgap) var(--content-gutter-right) 0
    var(--content-gutter-left);
  box-sizing: border-box;
}
.ah-hero-meta {
  text-align: right;
  opacity: 0;
  animation: ah-fadein 900ms 1400ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.ah-hero-rule {
  width: 120px;
  height: 1px;
  background: var(--color-ink);
  margin-top: 24px;
  margin-left: auto;
  transform-origin: right;
  transform: scaleX(0);
  animation: ah-rule-draw 1200ms 1600ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.ah-hero-intro {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  padding-top: 24px;
  opacity: 0;
  animation: ah-fadein 900ms 1300ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.ah-hero-intro--columns {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr; /* equal halves about the page centre line */
  gap: 0; /* override .ah-hero-intro's 56px so the rule lands on the boundary */
  align-items: start; /* top-align link with paragraph's first line */
  padding-top: 32px;
}
/* Vertical hairline at the exact page centre (50% of the symmetric content
   box = 50% of the viewport, since .ah-page has equal 24px gutters). Height
   tracks the taller column (the paragraph block), top:32px → bottom:0. */
.ah-hero-intro--columns::after {
  content: "";
  position: absolute;
  top: 32px;
  bottom: 0;
  left: 50%;
  width: 1px;
  background: var(--color-ink);
}
/* LEFT column — a single all-caps link pinned right, against the rule. */
.ah-intro-aside {
  grid-column: 1;
  text-align: right;
  padding-right: 24px; /* inset from the rule */
}
.ah-intro-link {
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 0.08em; /* the caps breathe at the smaller size */
  white-space: nowrap;
}
/* Link sits beneath its paragraph, left-aligned to the paragraph edge,
   24px below the last line (margin-top collapses with the p's bottom margin
   to a single 24px gap). text-align:left overrides the prose's justify. */
.ah-prose-linkrow {
  margin-top: 24px;
  display: flex;
  justify-content: flex-end;
}
/* RIGHT column — the standfirst paragraph, justified, drop cap intact.
   Right edge meets the content's 24px gutter (the .ah-page shell). */
.ah-prose--news {
  --ah-dropcap-lh: 1.6;
  grid-column: 2;
  padding-left: 24px; /* inset from the rule, mirrors the aside */
  box-sizing: border-box;
  text-align: justify;
  hyphens: auto;
}
.ah-prose--news p {
  margin: 0 0 1em;
  max-width: none;
}
@media (max-width: 768px) {
  .ah-hero-intro--columns {
    grid-template-columns: 1fr;
  }
  .ah-hero-intro--columns::after {
    display: none;
  }
  .ah-intro-aside {
    grid-column: 1;
    text-align: left;
    padding-right: 0;
    margin-bottom: 24px;
  }
  .ah-prose--news {
    grid-column: 1;
    padding-left: 0;
    text-align: left;
    hyphens: manual;
  }
}

/* Four-column grid for the homepage's running body paragraphs — the firm
   intro standfirst, the credo section, and the Process section paragraphs,
   all of which carry .ah-credo-spread. The two-column spread becomes four
   equal columns across the same content width; the centre rule (::after at
   50%) still falls on the col 2|3 boundary. The paragraph moves from column 2
   (50%→100%) to column THREE (50%→75%): its left edge and left rule are
   unchanged (column 3 also starts at 50%), only its right edge pulls in to
   75%, with column 4 left empty. Left-aligned, ragged right, no hyphenation.
   Desktop only (mobile already stacks to one column). */
@media (min-width: 1000px) {
  .ah-hero-intro--columns.ah-credo-spread {
    grid-template-columns: repeat(4, 1fr);
  }
  .ah-credo-spread .ah-prose--news {
    grid-column: 3;
    text-align: left;
    -webkit-hyphens: none;
    hyphens: none;
  }
}

/* ============================================================
   Drop cap — ONE shared rule used everywhere.
   Aligns by GLYPH metrics, not the font box.

   The cap (a real <span class="ah-dropcap"> inside .ah-drop,
   wrapped by JS on mount) uses text-box-trim so its float box
   equals the visible letterform — cap-top to baseline of the
   glyph, with no invisible leading.

   We do NOT trim the paragraph itself: text-box-trim: trim-start
   only affects the first line, which in a multi-column flow
   would push column 1's first line up by a half-leading while
   column 2's first wrapped line keeps its full leading — the
   two columns then no longer share a baseline. Instead we leave
   the paragraph alone (all columns sit on the same line grid)
   and nudge ONLY the cap's float down by the body half-leading
   + asc-cap offset so its glyph cap-top lands on line 1's body
   cap-top regardless of where the paragraph wraps.

   Sizing: visible cap spans line 1 cap-top → line 3 baseline.
   With cap-height ratio C (≈0.7 for both Inter body and Tid
   Display), visible-height = (2L + C) × body-fs, and cap-fs =
   (2L + C) / C em (body em). The body line-height L
   (--ah-dropcap-lh) remains the single source of derivation.

   Fallback paths:
   - No JS (span never wrapped): :first-letter gets the
     line-height-derived approximation, gated with :not(:has) so
     it never collides with the real-element path.
   - No text-box-trim support: same line-height approximation on
     the span.
   ============================================================ */

/* Span path — modern + JS-wrapped */
.ah-drop .ah-dropcap {
  font-family: var(--font-display);
  font-weight: 400;
  float: left;
  font-size: calc((5 * var(--ah-dropcap-lh, 1.6) + 1) / 2 * 1em);
  line-height: 1;
  padding-top: calc(
    (var(--ah-dropcap-lh, 1.6) - 1) / (5 * var(--ah-dropcap-lh, 1.6) + 1) * 1em
  );
  margin: 0 0.1em 0 0;
  color: inherit;
}

@supports (text-box-trim: trim-both) {
  .ah-drop .ah-dropcap {
    text-box-trim: trim-both;
    text-box-edge: cap alphabetic;
    /* Visible cap = (2L + 0.7) × body-fs; cap-fs = (2L + 0.7) / 0.7 em */
    font-size: calc((2 * var(--ah-dropcap-lh, 1.6) + 0.7) / 0.7 * 1em);
    padding-top: 0;
    /* Push cap down so its glyph cap-top sits at line 1's body cap-top.
       Offset in cap-em = (body half-leading + asc-cap) / cap-fs-body-em.
       half-leading = (L - 1)/2 body-em; asc-cap ≈ 0.19 body-em for Inter.
       Cap-fs = (2L + 0.7)/0.7 body-em. Simplified to cap-em:
       (0.35*(L-1) + 0.133) / (2L + 0.7). */
    margin-top: calc(
      (0.35 * (var(--ah-dropcap-lh, 1.6) - 1) + 0.26) /
        (2 * var(--ah-dropcap-lh, 1.6) + 0.7) * 1em
    );
  }
}

/* No-JS fallback path — :first-letter only when span is NOT present. */
.ah-drop:not(:has(.ah-dropcap))::first-letter {
  font-family: var(--font-display);
  font-weight: 400;
  float: left;
  font-size: calc((5 * var(--ah-dropcap-lh, 1.6) + 1) / 2 * 1em);
  line-height: 1;
  padding-top: calc(
    (var(--ah-dropcap-lh, 1.6) - 1) / (5 * var(--ah-dropcap-lh, 1.6) + 1) * 1em
  );
  margin: 0 0.1em 0 0;
  color: inherit;
}

@media (max-width: 768px) {
  /* Single-column phone view: drop cap reads as too heavy. Disable. */
  .ah-drop .ah-dropcap,
  .ah-drop:not(:has(.ah-dropcap))::first-letter {
    font-size: 1em;
    float: none;
    padding: 0;
    margin: 0;
    text-box-trim: none;
  }
}

/* Co-ordinated arrival: the headline rises up from beneath the photo,
   and the photo simultaneously drops down to meet it at the shared seam. */
.ah-hero-mask {
  overflow: hidden;
  padding-bottom: 0;
  font-size: var(--tw-hero-size, 108px);
  line-height: 0.85;
  /* After the rise animation completes, drop the clip so descenders
     can extend down across the seam, matching the reference. */
  animation: ah-mask-unclip 0ms 1500ms forwards;
}
@keyframes ah-mask-unclip {
  to {
    overflow: visible;
  }
}
.ah-hero-mask .ah-hero-line {
  font-size: var(--hero-display-size);
}

/* Guardrail: any element wrapping a display heading with overflow:hidden
   (used for slide-in/rise reveals) must reserve room for descenders. */
[class*="-mask"]:has(
    .ah-display,
    .ah-hero-line,
    .ah-h1,
    .ah-h2,
    .ah-pagehead-title
  ) {
  padding-bottom: 0.22em;
}
.ah-display,
.ah-h1,
.ah-h2,
.ah-pagehead-title,
.ah-hero-line {
  /* line-height already > 1, but ensure the layout box reserves descender room */
  padding-bottom: 0.04em;
}
.ah-hero-line--rise {
  display: block;
  transform: translateY(100%);
  animation: ah-rise 1100ms 200ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
@keyframes ah-rise {
  from {
    transform: translateY(100%);
  }
  to {
    transform: translateY(0);
  }
}
.ah-hero-figure--drop {
  transform: translateY(-12%);
  animation: ah-drop 1100ms 200ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
@keyframes ah-drop {
  from {
    transform: translateY(-12%);
  }
  to {
    transform: translateY(0);
  }
}
.ah-hero-line {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--hero-display-size);
  line-height: 1.02;
  letter-spacing: -0.012em;
  margin: 0;
  white-space: nowrap;
  /* Note: homepage hero is exempt from the a/b rule; no `text-box-trim`
     here so the original descender guardrails keep doing their job. */
}
.ah-hero-line em {
  font-style: normal;
}

/* --------- HOMEPAGE HERO — STAGGERED BUILD ANIMATION ---------
   Replacement for the single-mask rise: each headline line sits in its
   own overflow:hidden row and animates independently. Single-shot on
   load — no loop, no timer. The H1 owns the layout height (two block
   rows + descender padding) so the .ah-hero-figure below it does not
   shift at any point during the animation; the brown 1px image-top
   stays put from t=0. Pure CSS @keyframes; consistent with the rest
   of this site's motion. */
.ah-hero-build {
  display: block;
  margin: 0;
  font-family: var(--font-display);
  /* font-weight comes from the inline style on the h1 (= 500) to
     match the prior hero exactly; do not override here. */
  font-size: var(--hero-display-size);
  /* 1.05 to match .ah-svc-title exactly, so the homepage hero baseline →
     image gap is pixel-identical to the Windows/service heroes. */
  line-height: 1.05;
  letter-spacing: -0.012em;
}
.ah-hero-build-row {
  /* No overflow clip — the headline's descenders ('g','p','y','J') must
     render in full. The entrance below is a short fade-rise that needs no
     mask, so nothing crops the glyphs. */
  display: block;
  overflow: visible;
  white-space: nowrap;
}
.ah-hero-build-row + .ah-hero-build-row {
  /* Descender room on the bottom row only, so 'p', 'g', etc. on the
     last baseline aren't clipped after the rise settles. Equivalent
     to the old hero-mask guardrail (0.22em) but scoped to the row
     that needs it, so the overall H1 height is still bounded. */
  padding-bottom: 0.22em;
}
.ah-hero-build-line {
  display: block;
  /* Centre the text within the headline's content box. In the normal range
     the JS sizes the line to fill the width exactly, so centred == flush; only
     when clamped at the 240px ceiling (ultra-wide) or wrapped at the 56px floor
     (very narrow) does this distribute the spare width into equal left/right
     margins, per the equal-margins rule. */
  text-align: center;
  /* MIRROR of the hero image's descent: the IDENTICAL 3.0s timeline and
     expo.inOut easing, with NO opening hold, but travelling UP instead of down.
     The image moves DOWN by D = var(--ah-header-height) + var(--ah-hero-band)
     to its rest; the text starts that same distance D BELOW its resting
     position and rises up by D to rest — in lockstep with the image (both begin
     immediately on load, accelerate together, and settle together). Translation
     ONLY; full opacity throughout (no fade). The line stays behind the figure
     (z-index), so the descending image passes over it as both move. Final
     resting transform is translateY(0); the JS 8px-clearance offset lives on
     the H1, so fit-to-width sizing and clearance are unchanged at rest. The
     opacity fades 0% → 100% on the SAME keyframes, so it shares the exact
     timeline and expo.inOut easing as the travel — position and opacity move
     together as one entrance. */
  transform: translateY(calc(var(--ah-header-height) + var(--ah-hero-band)));
  opacity: 0;
  animation: ah-hero-text-rise 3000ms 0ms
    linear(
      0 0%,
      0.0006 1.7%,
      0.0008 3.3%,
      0.001 5%,
      0.0012 6.7%,
      0.0015 8.3%,
      0.002 10%,
      0.0025 11.7%,
      0.0031 13.3%,
      0.0039 15%,
      0.0049 16.7%,
      0.0062 18.3%,
      0.0078 20%,
      0.0099 21.7%,
      0.0123 23.3%,
      0.0156 25%,
      0.0198 26.7%,
      0.0247 28.3%,
      0.0313 30%,
      0.0396 31.7%,
      0.0494 33.3%,
      0.0625 35%,
      0.0791 36.7%,
      0.0988 38.3%,
      0.125 40%,
      0.1582 41.7%,
      0.1975 43.3%,
      0.25 45%,
      0.2872 46%,
      0.3164 46.7%,
      0.3789 48%,
      0.395 48.3%,
      0.5 50%,
      0.605 51.7%,
      0.6211 52%,
      0.6836 53.3%,
      0.7128 54%,
      0.75 55%,
      0.8025 56.7%,
      0.8418 58.3%,
      0.875 60%,
      0.9012 61.7%,
      0.9209 63.3%,
      0.9375 65%,
      0.9456 66%,
      0.9506 66.7%,
      0.9604 68.3%,
      0.9688 70%,
      0.9753 71.7%,
      0.9763 72%,
      0.9802 73.3%,
      0.9844 75%,
      0.9877 76.7%,
      0.9901 78.3%,
      0.9922 80%,
      0.9938 81.7%,
      0.9951 83.3%,
      0.9961 85%,
      0.9969 86.7%,
      0.9974 88%,
      0.9975 88.3%,
      0.998 90%,
      0.9985 91.7%,
      0.9988 93.3%,
      0.9989 94%,
      0.999 95%,
      0.9992 96.7%,
      0.9994 98.3%,
      1 100%
    )
    both;
}
@keyframes ah-hero-text-rise {
  from {
    transform: translateY(calc(var(--ah-header-height) + var(--ah-hero-band)));
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  /* Skip the descent entirely — image at rest, lettering already visible. */
  .ah-hero-figure {
    transform: none;
    animation: none;
  }
  /* Skip the text entrance — final resting position, full opacity. */
  .ah-hero-build-line {
    transform: none;
    opacity: 1;
    animation: none;
  }
}

/* Homepage hero DEK — sits directly UNDER the gold hero image. Dek role:
   Tid Display italic at --type-dek (40px). Left-aligned to the page margin
   (inherits .ah-page's --content-gutter-left, so it lines up with the
   hero's left edge). Top gap from the image and bottom gap to the intro
   section are both 32px (the established hero→intro rhythm). */
.ah-hero-dek {
  margin: 32px 0 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--type-dek);
  line-height: 1.15;
  letter-spacing: -0.003em;
  color: var(--color-ink);
  text-align: left;
}

/* Statement-scale dek — the homepage intro dek, paired in size with the
   Service Area credo line via the shared --type-statement (64px) token.
   Only the size lifts; gutter, italic, colour, and position are inherited
   from .ah-hero-dek. Every other dek on the site stays at --type-dek (40px). */
.ah-hero-dek--statement {
  font-size: 54px;
  line-height: 1.08;
  letter-spacing: -0.005em;
}
@media (max-width: 768px) {
  /* Pair the statement dek with the credo's narrow-width size. */
  .ah-hero-dek--statement {
    font-size: 34px;
  }
}

/* letter arrival */
.ah-hero-letters {
  display: inline-block;
}
.ah-letter {
  display: inline-block;
  opacity: 0;
  transform: translateY(20px);
  animation: ah-letter-in 900ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.ah-hero-letters.is-italic .ah-letter {
  font-style: italic;
}
@keyframes ah-letter-in {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes ah-rule-draw {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/* --------- SELECTED WORK GRID --------- */
.ah-work-head {
  display: block;
  padding: 0;
  /* Breathing room above the enlarged title — the section-rhythm
     top buffer (120 / 80 / 56 across desktop / tablet / phone;
     overrides below), mirroring .ah-affil's top rhythm. */
  margin-top: 120px;
  /* Gap from hero title to the project grid below — mirrors the
     .ah-affil hero-to-marquee 72px rhythm. */
  margin-bottom: 72px;
}
.ah-work-head__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--hero-display-size);
  line-height: 1.05;
  letter-spacing: -0.005em;
  margin: 0;
  padding-bottom: 0.06em;
  font-style: normal;
  color: var(--color-ink);
  max-width: none;
}
.ah-work-head .ah-h2 {
  max-width: 18ch;
}
@media (max-width: 1023px) {
  .ah-work-head {
    padding: 0;
    margin-top: 80px;
    margin-bottom: 56px;
  }
}
@media (max-width: 720px) {
  .ah-work-head {
    padding: 0;
    margin-top: 56px;
    margin-bottom: 40px;
  }
}

.ah-grid-4 {
  display: grid;
  grid-template-columns: repeat(var(--tw-grid-cols, 4), 1fr);
  column-gap: 0;
  row-gap: 56px;
  /* Sits within the shared 24px text frame (no edge bleed) so the
     image grid aligns to the same left/right gutters as the text. */
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}

/* --------- HOMEPAGE SELECTED WORKS: FULL-BLEED IMAGES ---------
   The Selected Works grid on the homepage runs its project images
   edge-to-edge, overriding the site-wide 24px page gutter for these
   images only. Captions/titles keep the standard 24px gutter at the
   page edges (outer-column captions realign to the gutter; inner
   captions keep their 14px column rhythm). Scoped via the --bleed
   modifier so the shared .ah-grid-4 on category pages stays guttered. */
.ah-grid-4--bleed {
  /* width:auto (not the base 100%) so the negative left/right margins
     expand the box on BOTH edges out to the viewport, rather than just
     shifting a fixed-width box leftward. */
  width: auto;
  margin-left: calc(-1 * var(--content-gutter-left));
  margin-right: calc(-1 * var(--content-gutter-right));
}
/* 4-up (desktop): col 1 + col 4 are the page-edge columns. */
.ah-grid-4--bleed > .ah-tile:nth-child(4n + 1) .ah-tile-caption {
  padding-left: var(--content-gutter-left);
}
.ah-grid-4--bleed > .ah-tile:nth-child(4n) .ah-tile-caption {
  padding-right: var(--content-gutter-right);
}

/* Category index (Residential / Ecclesiastical / Institutional) */
.ah-cat-title {
  font-family: var(--font-display);
  font-size: clamp(72px, 11vw, 168px);
  line-height: 0.95;
  margin: 0;
  font-weight: 400;
  letter-spacing: -0.012em;
}
.ah-cat-count {
  font-family: var(--font-display);
  font-size: 0.28em;
  font-weight: 400;
  margin-left: 0.18em;
  vertical-align: 0.85em;
  letter-spacing: 0;
}
.ah-cat-kicker {
  font-family: var(--font-display);
  font-size: 30px;
  margin-top: 80px;
  color: var(--color-ink);
}
.ah-cat-kicker em {
  font-style: italic;
}
.ah-cat-count--sm {
  font-size: 0.55em;
  vertical-align: 0.85em;
  margin-left: 0.25em;
}
.ah-grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 0;
  row-gap: 56px;
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}
.ah-grid-2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: 0;
  row-gap: 56px;
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}

/* Project tile (editorial) */
.ah-tile,
.ah-tile:hover,
.ah-tile:focus {
  display: block;
  text-decoration: none !important;
  color: var(--color-ink);
  cursor: pointer;
  transition: opacity 240ms ease;
}
.ah-tile-figure {
  width: 100%;
  aspect-ratio: 4/5;
  overflow: hidden;
  position: relative;
}
.ah-tile-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 900ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ah-tile:hover .ah-tile-figure img {
  transform: scale(1.015);
}

.ah-tile-caption {
  margin-top: 14px;
  padding: 0 14px;
}
.ah-tile-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 18px;
  line-height: 1.35;
  font-style: italic;
  max-width: 28ch;
}
.ah-tile-sub {
  font-size: 12.5px;
  color: var(--color-ink);
  margin-top: 4px;
  letter-spacing: 0.05px;
}
.ah-tile-disc {
  font-size: 12.5px;
  color: var(--color-ink);
  margin-top: 2px;
}

/* Editorial chip row — serif with superscripts */
.ah-catchips {
  display: flex;
  gap: 40px;
  flex-wrap: wrap;
  align-items: baseline;
  margin-top: 24px;
}
.ah-catchip {
  font-family: var(--font-display);
  font-size: 32px;
  line-height: 1.2;
  cursor: pointer;
  background: transparent;
  border: 0;
  padding: 0;
  color: var(--color-ink);
  letter-spacing: -0.003em;
  transition: opacity 200ms ease;
}
.ah-catchip .ah-sup {
  font-size: 0.38em;
  color: var(--color-ink);
}
.ah-catchip {
  color: var(--color-ink);
  font-weight: 400;
}
.ah-catchip.is-active {
  font-style: normal;
  font-weight: 700;
}
.ah-catchip:hover {
  opacity: 0.55;
}

/* --------- PULL QUOTE --------- */
.ah-pull {
  padding: 96px 0;
  display: grid;
  grid-template-columns: 1fr 8fr 1fr;
  gap: 24px;
}
.ah-pull-body {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 3vw, var(--type-dek));
  line-height: 1.22;
  color: var(--color-ink);
  letter-spacing: -0.003em;
}
.ah-pull-body em {
  font-style: italic;
}
.ah-pull-attrib {
  margin-top: 32px;
  font-size: 12.5px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-ink);
}
.ah-pull-attrib a {
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* --------- ABOUT NOTE --------- */
.ah-note {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 64px;
  padding: 96px var(--content-gutter-right) 96px var(--content-gutter-left);
  margin: 0 calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
  border-top: 1px solid var(--color-ink);
}
.ah-note-label {
  font-size: 11px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-ink);
}
.ah-note-body p {
  font-family: var(--font-display);
  font-size: clamp(22px, 2vw, 28px);
  line-height: 1.4;
  margin: 0 0 0.7em;
}
.ah-note-body p:last-child {
  margin-bottom: 0;
}
.ah-note-body em {
  font-style: italic;
}

/* --------- SEAL ROW (about mark) --------- */
.ah-bg-paper [data-screen-label="About — Artifex"] .ah-sealrow,
[data-screen-label="About — Artifex"] .ah-sealrow {
  border-top: 0;
}
.ah-sealrow {
  padding: 120px var(--content-gutter-right) 96px var(--content-gutter-left);
  margin: 0 calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
  text-align: center;
  border-top: 1px solid var(--color-ink);
}
.ah-sealmark {
  width: 112px;
  height: 112px;
  border-radius: 50%;
  border: 1px solid var(--color-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 32px;
}
.ah-sealmark-inner {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 24px;
  letter-spacing: 2px;
  color: var(--color-ink);
}
.ah-sealrow-body {
  font-family: var(--font-display);
  font-size: clamp(22px, 2vw, 30px);
  line-height: 1.35;
  max-width: 46ch;
  margin: 0 auto;
  color: var(--color-ink);
}
.ah-sealrow-body em {
  font-style: italic;
}
.ah-sealrow-email {
  display: inline-block;
  margin-top: 28px;
  font-size: 12px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-ink);
  padding-bottom: 4px;
  border-bottom: 1px solid var(--color-ink);
}
.ah-sealrow-email:hover {
  opacity: 0.6;
}

/* --------- FOOTER --------- */
.ah-footer {
  padding: 72px var(--content-gutter-right) 0 var(--content-gutter-left);
  max-width: none;
  margin: 0;
  border-top: 1px solid var(--color-ink);
  background: transparent;
}

/* Wide regime (>= 900px): three columns in one evenly distributed row.
   minmax(0, 1fr) keeps the three tracks equal and lets them shrink fluidly
   toward the breakpoint instead of overflowing (no fixed-px column widths or
   flank margins). The gap scales with the viewport but is clamped so it never
   collapses or blows out. Outer margins come from the page's 24px gutter via
   .ah-footer padding. */
.ah-footer-inner {
  --footer-head-to-body: 33px; /* head → body offset; ~1.5× head size */
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
  column-gap: clamp(40px, 6vw, 96px);
  width: 100%;
}

/* Each column is a centred block within its equal track. Heads, lists and the
   brand paragraph all centre on the track's midline. */
.ah-footer-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  max-width: 100%;
  text-align: center;
}

/* Brand block: balanced, centred measure constrained to its track. */
.ah-footer-col--brand .ah-footer-body p {
  text-wrap: balance;
}

/* Copyright bar — a standalone, full-width centred bar pinned to the bottom
   of the footer at every width, below all three columns. Not fixed to the
   viewport; it is the last flow child of .ah-footer. */
.ah-footer-copy {
  width: 100%;
  margin-top: 96px;
  padding-bottom: 88px;
  text-align: center;
  font-size: 10px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--color-ink);
}

/* Single shared spec for ALL footer column heads — wordmark included. */
.ah-footer-head {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 24px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-ink);
  margin: 0 0 var(--footer-head-to-body, 33px);
  /* Left padding = trailing letter-spacing (0.08em) so the tracked glyphs sit
     optically dead-centre over the list rather than offset by the trailing space. */
  padding: 0 0 0 0.08em;
  line-height: 1;
}

.ah-footer-logo {
  display: block;
  height: 100px;
  width: auto;
  margin: 0 auto 15px;
}
.ah-footer-col--brand .ah-footer-body {
  font-size: 16px;
}

.ah-footer-body {
  font-size: 16px;
  line-height: 1.6;
  color: var(--color-ink);
  align-self: center;
}
.ah-footer-body p {
  margin: 0 0 14px;
  max-width: none;
}
.ah-footer-body p:last-child {
  margin-bottom: 0;
}
.ah-footer-body ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.ah-footer-body li {
  margin-bottom: 9px;
}
.ah-footer-body a {
  color: var(--color-ink);
  text-decoration: none;
}
.ah-footer-body a:hover {
  opacity: 0.6;
}
.ah-footer-body > :first-child {
  margin-top: 0;
}

.ah-footer-util {
  display: flex;
  justify-content: space-between;
  margin: 56px calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
  padding: 24px var(--content-gutter-right) 0 var(--content-gutter-left);
  font-size: 11px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--color-ink);
}
.ah-footer-util a {
  color: var(--color-ink);
  text-decoration: none;
}

/* Narrow regime (< 900px): single centred stack, in DOM order
   (Information \u2192 Artifex Heritage \u2192 Contact). The copyright bar remains the
   footer's last flow child, so it stays centred at the very bottom below the
   Contact column. Normal flow only \u2014 no absolute / diagonal positioning. */
@media (max-width: 899px) {
  .ah-footer-inner {
    grid-template-columns: 1fr;
    row-gap: 40px;
    justify-items: center;
    column-gap: 0;
  }
}

/* --------- PROJECT PLATE (PDP chassis) --------- */
.ah-plate {
  padding: 48px 0 96px;
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: 72px;
  align-items: start;
}
.ah-plate-media {
}
.ah-plate-main {
  width: 100%;
  aspect-ratio: 4/5;
  overflow: hidden;
}
.ah-plate-main img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ah-plate-thumbs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-top: 12px;
}
.ah-plate-thumb {
  aspect-ratio: 1/1;
  cursor: pointer;
  overflow: hidden;
  border: 1px solid transparent;
  transition: opacity 200ms ease;
}
.ah-plate-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ah-plate-thumb.is-active {
  border-color: var(--color-ink);
}
.ah-plate-thumb:hover {
  opacity: 0.7;
}

.ah-plate-info {
  padding-top: 24px;
  display: flex;
  flex-direction: column;
}
.ah-plate-eyebrow {
  font-size: 11px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-ink);
  margin-bottom: 18px;
}
.ah-plate-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(32px, 3.4vw, 52px);
  line-height: 1.1;
  margin: 0 0 14px;
}
.ah-plate-dateline {
  font-size: 13px;
  color: var(--color-ink);
  letter-spacing: 0.05px;
  margin-bottom: 28px;
}
.ah-plate-body {
  font-size: 16px;
  line-height: 1.6;
  margin-bottom: 32px;
}
.ah-plate-body p {
  margin: 0 0 1em;
}
.ah-plate-body p:last-child {
  margin-bottom: 0;
}

.ah-acc {
  border-top: 1px solid var(--color-ink);
}
.ah-acc:last-of-type {
  border-bottom: 1px solid var(--color-ink);
}
.ah-acc-head {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  font: 700 13px/1.4 var(--font-body);
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--color-ink);
}
.ah-acc-head-left {
  display: flex;
  gap: 14px;
  align-items: baseline;
}
.ah-acc-mark {
  font-weight: 400;
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: 15px;
}
.ah-acc-plus {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 18px;
}
.ah-acc-body {
  font-size: var(--type-body);
  line-height: 1.6;
  padding: 4px 0 20px;
  max-width: 56ch;
}

.ah-plate-cta {
  margin-top: 36px;
}
.ah-plate-cta button {
  width: 100%;
  background: var(--color-ink);
  color: #fff;
  border: 0;
  border-radius: 0;
  padding: 18px 20px;
  font: 700 13px/1.4 var(--font-body);
  letter-spacing: 1.4px;
  text-transform: uppercase;
  cursor: pointer;
  transition: opacity 200ms ease;
}
.ah-plate-cta button:hover {
  opacity: 0.85;
}

/* --------- PROJECT PLATE — ESSAY SEGMENTS --------- */
.ah-plate-essay {
  padding: 64px 0 0;
}
.ah-plate-essay .ah-rule {
  margin-bottom: 64px;
}
.ah-plate-essay-body {
  --ah-dropcap-lh: 1.7;
  max-width: 62ch;
  margin: 0 auto;
  font-size: var(--type-body);
  line-height: 1.7;
}
.ah-plate-essay-body p {
  margin: 0 0 1.2em;
}

.ah-plate-gallery {
  padding: 80px 0 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}
.ah-plate-gallery figure {
  margin: 0;
}
.ah-plate-gallery figure img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
}
.ah-plate-gallery figcaption {
  font-size: 12.5px;
  color: var(--color-ink);
  margin-top: 10px;
  line-height: 1.5;
  max-width: 50ch;
}
.ah-plate-gallery--wide figure:first-child {
  grid-column: 1 / -1;
}
.ah-plate-gallery--wide figure:first-child img {
  aspect-ratio: 16/9;
}

/* --------- MAGAZINE ARTICLE LAYOUT ---------
   Reusable hero with two text zones wrapped around a 3:4 portrait image:
     • Zone A (2-col text) sits in the LEFT half of the hero, below the
       headline + kicker + rule. Its 1fr row in the left sub-grid stretches
       Zone A to fill the remaining height beside the image — so Zone B
       begins cleanly below the image regardless of viewport size.
     • Zone B (4-col text) is a separate full-width section below the hero.
   Reading order: bodyA → bodyB. Split point lives at the call site
   (MagazineArticle props in About.jsx). See src/MagazineArticle.jsx. */
.ah-mag {
  display: block;
}
.ah-mag-hero {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 56px;
  align-items: stretch;
  padding: 48px 0 0;
}
.ah-mag-hero__left {
  display: grid;
  /* headline | kicker | rule | Zone A (fills remaining height) */
  grid-template-rows: auto auto auto 1fr;
  min-width: 0;
}
.ah-mag-headline {
  font-family: var(--font-display);
  font-weight: 400;
  /* 44px → 100px ceiling.
     Pixel-valued endpoints rather than rem because this site's root
     font-size is 15px (not the default 16px), so an `rem`-based ceiling
     of 6.25rem would resolve to 93.75px and never reach the intended
     100px. Preferred slope `30px + 7vw` hits 100px at exactly 1000px
     viewport, so any standard desktop renders the ceiling cleanly. */
  font-size: clamp(44px, 30px + 7vw, var(--type-hero));
  line-height: 0.98;
  letter-spacing: -0.005em;
  color: var(--color-ink);
  margin: 0;
  text-wrap: balance;
}
.ah-mag-headline em {
  font-style: italic;
}
.ah-mag-kicker {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 24px;
  line-height: 1.4;
  color: var(--color-ink);
  margin: 28px 0 0;
  max-width: none;
}
.ah-mag-hero__rule {
  border: 0;
  border-top: 1px solid var(--color-ink);
  margin: 32px 0 24px;
  width: 100%;
  height: 0;
}
.ah-mag-zone-a {
  --ah-dropcap-lh: 1.65;
  /* The 1fr grid row above gives this element a definite height,
     so column-fill: balance distributes content evenly across the 2 cols. */
  min-height: 0;
  column-count: 2;
  column-gap: 28px;
  column-rule: 0;
  column-fill: balance;
  font-family: var(--font-body);
  font-size: var(--type-body);
  line-height: 1.65;
  color: var(--color-ink);
  text-align: justify;
  hyphens: auto;
  padding-bottom: 8px;
}
.ah-mag-hero__right {
  align-self: start;
  display: flex;
  flex-direction: column;
}
.ah-mag-hero__img {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  background: #ffffff;
  overflow: hidden;
}
.ah-mag-caption {
  font-family: var(--font-body);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--color-ink);
  margin-top: 12px;
  max-width: 48ch;
}
.ah-mag-zone-b {
  --ah-dropcap-lh: 1.65;
  column-count: 4;
  column-gap: 28px;
  column-rule: 0;
  column-fill: balance;
  font-family: var(--font-body);
  font-size: var(--type-body);
  line-height: 1.65;
  color: var(--color-ink);
  text-align: justify;
  hyphens: auto;
  margin-top: 48px;
  padding-bottom: 96px;
}

/* Shared body typography (Zone A + Zone B) */
.ah-mag-zone-a p,
.ah-mag-zone-b p {
  margin: 0 0 1em;
}
.ah-mag-zone-a p:last-child,
.ah-mag-zone-b p:last-child {
  margin-bottom: 0;
}
.ah-mag-zone-a em,
.ah-mag-zone-b em {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.06em;
}
.ah-mag-zone-a strong,
.ah-mag-zone-b strong {
  font-weight: 700;
}
.ah-mag-zone-a h3,
.ah-mag-zone-b h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--type-subtitle);
  line-height: 1.2;
  color: var(--color-ink);
  margin: 1.6em 0 0.5em;
  /* Never orphan a subhead at the foot of a column */
  break-after: avoid;
  break-inside: avoid;
  page-break-after: avoid;
  page-break-inside: avoid;
}
.ah-mag-zone-a h3:first-child,
.ah-mag-zone-b h3:first-child {
  margin-top: 0;
}

.ah-mag-pull {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--type-dek);
  line-height: 1.35;
  color: var(--color-ink);
  margin: 16px auto 64px;
  max-width: 32ch;
  padding: 0;
  border: 0;
  text-align: center;
}
@media (max-width: 1023px) {
  /* At and below tablet: hero stacks — headline + kicker + rule first,
     then a constrained-width portrait below. Zone A becomes a single
     column at its natural height (no longer height-constrained to the
     image); Zone B drops to 2 columns. */
  .ah-mag-hero {
    grid-template-columns: 1fr;
    gap: 40px;
    padding: 40px 0 0;
    align-items: start;
  }
  .ah-mag-hero__left {
    display: block;
    grid-row: 1;
  }
  .ah-mag-hero__right {
    grid-row: 2;
    align-self: stretch;
  }
  .ah-mag-hero__img {
    /* Cap the stacked portrait so it reads as an editorial inset rather
       than a full-bleed page break at tablet widths. */
    max-width: 480px;
    margin: 0 auto;
  }
  .ah-mag-hero__rule {
    margin: 28px 0 20px;
  }
  .ah-mag-zone-a {
    column-count: 1;
    padding-bottom: 0;
    font-size: 14.5px;
  }
  .ah-mag-zone-b {
    column-count: 2;
    font-size: 14.5px;
  }
}
@media (max-width: 768px) {
  /* Phone: Zone B collapses to 1 column; image stays constrained. */
  .ah-mag-hero {
    padding: 32px 0 0;
    gap: 32px;
  }
  .ah-mag-hero__img {
    max-width: 360px;
  }
  .ah-mag-kicker {
    font-size: 22px;
    margin-top: 20px;
    max-width: none;
  }
  .ah-mag-zone-a {
    font-size: 15px;
    line-height: 1.6;
  }
  .ah-mag-zone-b {
    column-count: 1;
    padding: 0 0 72px;
    font-size: 15px;
    line-height: 1.6;
    margin-top: 40px;
  }
  .ah-mag-zone-a h3,
  .ah-mag-zone-b h3 {
    font-size: 22px;
  }
}

/* --------- JOURNAL --------- */
.ah-journal-head {
  padding: 64px var(--content-gutter-right) 56px var(--content-gutter-left);
  margin: 0 calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  border-bottom: 1px solid var(--color-ink);
}
.ah-journal-head .ah-lede {
  font-size: 19px;
  line-height: 1.45;
  max-width: 42ch;
}

.ah-streams {
  display: flex;
  gap: 56px;
  flex-wrap: wrap;
  margin: 40px 0 56px;
  align-items: baseline;
}

.ah-jcard {
  display: block;
  text-decoration: none;
  color: var(--color-ink);
  cursor: pointer;
}
.ah-jcard-figure {
  width: 100%;
  aspect-ratio: 4/3;
  overflow: hidden;
}
.ah-jcard-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 900ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ah-jcard:hover .ah-jcard-figure img {
  transform: scale(1.015);
}
.ah-jcard-eyebrow {
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--color-ink);
  margin: 18px 0 10px;
}
.ah-jcard-title {
  font-family: var(--font-display);
  font-size: var(--type-subtitle);
  line-height: 1.2;
  margin: 0 0 10px;
}
.ah-jcard-title em {
  font-style: italic;
}
.ah-jcard-meta {
  font-size: 12.5px;
  color: var(--color-ink);
}

/* Journal article */
.ah-article {
  max-width: 720px;
  margin: 0 auto;
  padding: 64px 0 96px;
}
.ah-article-lede {
  font-size: 19px;
  line-height: 1.55;
  color: var(--color-ink);
  margin: 28px 0 48px;
  max-width: 52ch;
}
.ah-article-body {
  --ah-dropcap-lh: 1.72;
  font-size: var(--type-body);
  line-height: 1.72;
  color: var(--color-ink);
}
.ah-article-body p {
  margin: 0 0 1.3em;
}
.ah-article-body h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 28px;
  margin: 1.6em 0 0.4em;
}
.ah-article-body blockquote {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.36;
  margin: 1.6em 0;
  padding: 0 0 0 32px;
  border-left: 1px solid var(--color-ink);
  font-style: italic;
  max-width: 40ch;
}
.ah-article-body figure {
  margin: 2.4em -80px;
}
.ah-article-body figure img {
  width: 100%;
  aspect-ratio: 16/10;
  object-fit: cover;
}
.ah-article-body figure figcaption {
  font-size: 12.5px;
  color: var(--color-ink);
  margin-top: 10px;
  line-height: 1.5;
}
.ah-article-header {
  border-bottom: 1px solid var(--color-ink);
  padding: 0 var(--content-gutter-right) 32px var(--content-gutter-left);
  margin: 0 calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
}
.ah-article-title {
  font-family: var(--font-display);
  font-size: var(--hero-fluid);
  line-height: 1.08;
  margin: 18px 0 0;
  max-width: 18ch;
}

/* --------- SERVICES --------- */
.ah-service-head {
  padding: 64px 0 56px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
}
.ah-service-body {
  padding: 56px 0 96px;
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 96px;
}
.ah-service-body h3 {
  font-family: var(--font-display);
  font-size: var(--type-subtitle);
  margin: 0 0 14px;
  font-weight: 400;
}
.ah-service-body .ah-prose {
  max-width: 60ch;
}

.ah-deflist {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 24px 48px;
  margin-top: 40px;
  padding-top: 40px;
  border-top: 1px solid var(--color-ink);
}
.ah-deflist dt {
  font-size: 11px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-ink);
  padding-top: 6px;
}
.ah-deflist dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--type-subtitle);
  line-height: 1.35;
  color: var(--color-ink);
}
.ah-deflist dd em {
  font-style: italic;
}

/* --------- TEAM --------- */
.ah-team {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 96px;
  padding: 48px 0 96px;
}
.ah-team-person {
}
.ah-team-portrait {
  width: 100%;
  aspect-ratio: 4/5;
  overflow: hidden;
  filter: grayscale(0.2);
  background: #eadfd0;
}
.ah-team-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Team — stacked sticky-text rows (svenskttenn pattern) */
.ah-team-stack {
  padding: 0;
  margin: 0 calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
}
.ah-team-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  border-top: 1px solid var(--color-ink);
}
.ah-team-row:last-child {
  border-bottom: 1px solid var(--color-ink);
}
.ah-team-row-figure {
  background: #eadfd0;
  position: sticky;
  top: 40px;
  height: calc(100vh - 40px);
  align-self: start;
}
.ah-team-row-figure .ah-img {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
}
.ah-team-row-text {
  display: flex;
  align-items: flex-start;
  min-height: 160vh;
}
.ah-team-row-text-inner {
  padding: 120px 64px;
  max-width: 56ch;
}
/* Reverse stacking for second row: text on left, image on right */
.ah-team-row--img-right .ah-team-row-figure {
  order: 2;
}
.ah-team-row--img-right .ah-team-row-text {
  order: 1;
  justify-content: flex-end;
}
.ah-team-row--img-right .ah-team-row-text-inner {
  padding-left: var(--content-gutter-left);
  padding-right: 64px;
}
.ah-team-row--img-left .ah-team-row-text-inner {
  padding-right: var(--content-gutter-right);
  padding-left: 64px;
}
@media (max-width: 768px) {
  .ah-team-stack {
    margin: 0 calc(-1 * var(--content-gutter-right)) 0
      calc(-1 * var(--content-gutter-left));
  }
  .ah-team-row {
    grid-template-columns: 1fr;
  }
  .ah-team-row-figure {
    min-height: 60vh;
    order: 0 !important;
  }
  .ah-team-row-text {
    order: 1 !important;
  }
  .ah-team-row-text-inner {
    position: static;
    padding: 48px 32px !important;
    max-width: none;
  }
}
.ah-team-eyebrow {
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--color-ink);
  margin-top: 28px;
}
.ah-team-name {
  font-family: var(--font-display);
  font-size: 40px;
  line-height: 1.1;
  margin: 10px 0 18px;
  font-weight: 400;
}
.ah-team-bio {
  font-size: var(--type-body);
  line-height: 1.65;
  max-width: 48ch;
}
.ah-team-bio p {
  margin: 0 0 1em;
}
/* Work — alternating 2-column layout (svenskttenn) */
.ah-work-stagger {
  margin: 0;
}
.ah-work-row2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  gap: 0;
  overflow: visible;
}
.ah-work-row2-figure {
  width: 100%;
  aspect-ratio: 2 / 3;
  background: #eadfd0;
  overflow: hidden;
}
.ah-work-row2-figure .ah-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 2 / 3;
}
.ah-work-row2-text {
  padding: 24px 64px 80px;
  max-width: 52ch;
  position: sticky;
  top: 12vh;
  align-self: start;
}
/* Row A: text on the left, image on the right */
.ah-work-row2--img-right .ah-work-row2-figure {
  order: 2;
}
.ah-work-row2--img-right .ah-work-row2-text {
  order: 1;
  padding-left: var(--content-gutter-left);
}
/* Row B: image on the left, text on the right */
.ah-work-row2--img-left .ah-work-row2-figure {
  order: 1;
}
.ah-work-row2--img-left .ah-work-row2-text {
  order: 2;
  padding-right: var(--content-gutter-right);
}

/* CHANGE 1 — eyebrow removed from the DOM; the title is now the topmost
   element of the text block. Give it the eyebrow's old top gap (28px) so
   the title sits where the eyebrow's top edge used to be and the text
   block's overall vertical position is unchanged. */
.ah-work-row2-text .ah-team-name {
  margin-top: 28px;
}

/* CHANGE 2 — mirror the left-text blocks across the centreline. The
   right-text blocks (img-left) hug the centreline with a 64px inner
   gutter from their left padding. Align the left-text blocks (img-right)
   to the END of their grid cell so their right edge meets the centreline,
   leaving the same 64px gutter (their padding-right) — same column width,
   text stays left-aligned, only the horizontal position shifts rightward. */
.ah-work-row2--img-right .ah-work-row2-text {
  justify-self: end;
  text-align: left;
}

/* CHANGE 3 — in-session file-browse picker on each figure block. */
.ah-work-figure {
  position: relative;
  cursor: pointer;
}
.ah-work-figure-input {
  display: none;
}
.ah-work-figure-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 2 / 3;
  display: block;
}
.ah-work-figure-browse {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: var(--tracking-button-sm, 0.6px);
  text-transform: uppercase;
  color: rgba(9, 4, 1, 0.5);
  pointer-events: none;
  transition: opacity 150ms ease;
}
/* Empty: the browse cue is always visible. Filled: hide it unless hover,
   and lay a quiet warm wash behind so the label stays legible. */
.ah-work-figure.is-filled .ah-work-figure-browse {
  opacity: 0;
}
.ah-work-figure.is-filled:hover .ah-work-figure-browse {
  opacity: 1;
  color: rgba(9, 4, 1, 0.7);
}
.ah-work-figure.is-filled:hover::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(245, 242, 236, 0.5);
  pointer-events: none;
}
@media (max-width: 900px) {
  .ah-work-stagger {
    margin: 0;
  }
  .ah-work-row2 {
    grid-template-columns: 1fr;
  }
  .ah-work-row2-figure {
    order: 0 !important;
    aspect-ratio: 2 / 3;
  }
  .ah-work-row2-text {
    order: 1 !important;
    padding: 32px 32px 56px !important;
    max-width: none;
    position: static;
    top: auto;
  }
}

.ah-work-row-subtitle {
  font-family: var(--font-display);
  line-height: 1.3;
  color: var(--color-ink);
}
/* CHANGE 2/3/4 — subtitle sized to 24px (specificity raised so it beats
   .ah-prose p { font-size: 16px }); a 1px rule sits between the subtitle
   and the body paragraph, aligned to the paragraph's content box with
   balanced 16px spacing; the body paragraph is justified with automatic
   hyphenation. */
.ah-team-bio .ah-work-row-subtitle {
  font-size: 24px;
  margin-bottom: 0;
}
.ah-work-row-rule {
  border: 0;
  border-top: 1px solid var(--color-ink);
  height: 0;
  width: 100%;
  margin: var(--s-16) 0;
}
.ah-work-row-para {
  text-align: justify;
  -webkit-hyphens: auto;
  hyphens: auto;
}
.ah-team-creds {
  margin-top: 28px;
  border-top: 1px solid var(--color-ink);
  padding-top: 20px;
}
.ah-team-creds dl {
  display: grid;
  grid-template-columns: 140px 1fr;
  gap: 10px 24px;
  margin: 0;
}
.ah-team-creds dt {
  font-size: 11px;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--color-ink);
}
.ah-team-creds dd {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
}

/* --------- CONTACT --------- */
.ah-contact {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 96px;
  padding: 64px 0 96px;
}
.ah-contact-meta {
  font-size: 16px;
  line-height: 1.7;
}
.ah-contact-meta dt {
  font-size: 11px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-ink);
  margin-top: 24px;
}
.ah-contact-meta dd {
  margin: 6px 0 0;
}
.ah-contact-meta dd a {
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* --- contact card grid --- */
/* Viewport-fill: the screen wrapper (top of page through the Newsletter card)
   is locked to an EXACT viewport height so the footer that follows in normal
   flow begins precisely at the bottom edge of the viewport on load — flush,
   visible but not scrolled past. The sticky nav occupies var(--ah-header-height)
   of flow above this wrapper, so that amount is subtracted: wrapper-top sits at
   the header height, wrapper-bottom (= footer top rule) lands at exactly 100svh
   down = the fold. svh measures the SMALLEST viewport state (mobile chrome
   visible), so the rule lands at the true bottom edge once chrome is accounted
   for. Because the boxes are short, content is well under this height and the
   leftover space falls below the Newsletter card — that gap is the breathing
   room. Short/landscape phones (content taller than the viewport) are the
   accepted exception. */
.ah-contact-screen {
  height: calc(100svh - var(--ah-header-height));
}
.ah-contact-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 21px;
  padding: 0 10px 24px;
  margin: 0 auto;
  max-width: 1150px;
  width: 100%;
}
.ah-contact-card {
  border: 1px solid var(--color-ink);
  background: var(--color-background);
  /* Office & Press lock to 7:4. */
  aspect-ratio: 7 / 4;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Newsletter sits on its own row, spanning the full width of Office + Press + gap.
   Content-driven height; the inner grid handles the editorial left/right split. */
.ah-contact-card--newsletter {
  grid-column: 1 / -1;
  aspect-ratio: auto;
  align-items: stretch;
}
.ah-contact-card-inner {
  padding: 40px 32px;
  text-align: center;
  width: 100%;
  max-width: 360px;
  margin: 0 auto;
}
.ah-contact-card-title {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 16px;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  margin: 0 0 24px;
  color: var(--color-ink);
}
.ah-contact-card-blurb {
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 0.2px;
  color: var(--color-ink);
  line-height: 1.7;
  margin: 0 0 18px;
}
.ah-contact-card-line {
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-ink);
  line-height: 1.7;
  margin: 0;
}
.ah-contact-card-line a {
  color: var(--color-ink);
  text-decoration: none;
}
.ah-contact-card-line a:hover {
  opacity: 0.6;
}

.ah-contact-card--newsletter .ah-contact-card-inner {
  max-width: none;
  width: 100%;
  text-align: left;
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: 40px;
  align-items: center;
  /* Match the apparent interior breathing room of Office/Press cards above
     (whose 360px max-width + auto margin creates ~120-160px of visual inset).
     Vertical padding is generous but content-driven height. */
  padding: 56px clamp(56px, 7vw, 112px);
}
.ah-news-intro {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.ah-news-intro .ah-contact-card-title {
  margin: 0;
}
.ah-news-intro .ah-contact-card-blurb {
  margin: 0;
}
.ah-news-body {
  min-width: 0;
}

.ah-news-form {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 0;
  text-align: left;
}
.ah-news-fields {
  border: 1px solid var(--color-ink);
  background: #ffffff;
}
.ah-news-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.ah-news-row + .ah-news-row {
  border-top: 1px solid var(--color-ink);
}
.ah-news-row--email {
  grid-template-columns: 1fr 56px;
}
.ah-news-input {
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--color-ink);
  background: transparent;
  border: 0;
  border-right: 1px solid var(--color-ink);
  padding: 18px 18px;
  outline: none;
  width: 100%;
  min-width: 0;
  transition: none;
}
.ah-news-row > .ah-news-input:last-child {
  border-right: 0;
}
.ah-news-input::placeholder {
  color: var(--color-ink);
  opacity: 1;
  text-transform: uppercase;
  letter-spacing: 1.6px;
  transition: none;
}
/* Focused text cell inverts; caret follows. Inversion is the focus indicator. */
.ah-news-input:focus {
  background-color: var(--color-ink);
  color: var(--color-background);
  caret-color: var(--color-background);
  outline: none;
}
.ah-news-input:focus::placeholder {
  color: var(--color-background);
}
.ah-news-submit {
  background: transparent;
  border: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--color-ink);
  padding: 0 14px;
  transition: none;
}
.ah-news-submit:hover,
.ah-news-submit:focus-visible {
  background-color: var(--color-ink);
  color: var(--color-background);
}
.ah-news-done {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 14px;
  color: var(--color-ink);
  text-align: center;
  text-transform: uppercase;
  margin: 0;
}
/* Success shell: keep the form box border + footprint, centre the message both ways. */
.ah-news-fields--done {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 106px;
}
.ah-news-consent {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  font-family: var(--font-body);
  font-size: 10.5px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--color-ink);
  line-height: 1.5;
  cursor: pointer;
}
.ah-news-consent input {
  margin-top: 0;
  accent-color: var(--color-ink);
}
.ah-news-consent a {
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.ah-contact-foot {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--color-ink);
  text-align: center;
  margin: 0 auto;
  max-width: 52ch;
  line-height: 1.6;
}

/* Tablet — keep the two-up + full-width composition; tighten gutters. */
@media (max-width: 1023px) {
  .ah-contact-grid {
    gap: 14px;
    padding: 0 10px 16px;
  }
  .ah-contact-card-inner {
    padding: 28px 20px;
    max-width: none;
  }
  .ah-contact-card--newsletter .ah-contact-card-inner {
    gap: 28px;
    grid-template-columns: 5fr 7fr;
    padding: 40px 48px;
  }
}

/* Mobile — stack all three vertically. Office & Press hold 7:4; Newsletter
   reverts to its original stacked internal layout, content-driven height. */
@media (max-width: 640px) {
  .ah-contact-grid {
    grid-template-columns: 1fr;
    gap: 16px;
    padding: 0 10px 16px;
  }
  .ah-contact-card {
    aspect-ratio: 7 / 4;
  }
  .ah-contact-card--newsletter {
    aspect-ratio: auto;
    grid-column: auto;
  }
  .ah-contact-card-inner {
    padding: 32px 24px;
  }
  .ah-contact-card--newsletter .ah-contact-card-inner {
    display: block;
    text-align: center;
  }
  .ah-news-intro {
    margin-bottom: 18px;
  }
}

.ah-form {
  display: grid;
  gap: 0;
}
.ah-field {
  position: relative;
  padding: 22px 0 8px;
  border-bottom: 1px solid var(--color-ink);
}
.ah-field label {
  position: absolute;
  top: 6px;
  left: 0;
  font-size: 11px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-ink);
  transition: all 200ms ease;
}
.ah-field.is-empty label {
  top: 28px;
  font-size: 15px;
  text-transform: none;
  letter-spacing: 0;
  color: var(--color-ink);
}
.ah-field input,
.ah-field textarea {
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  font: 400 15px/1.5 var(--font-body);
  color: var(--color-ink);
  padding: 6px 0;
  resize: none;
}
.ah-field textarea {
  min-height: 90px;
}
.ah-form button[type="submit"] {
  margin-top: 24px;
  background: var(--color-ink);
  color: #fff;
  border: 0;
  border-radius: 0;
  padding: 18px;
  font: 700 13px/1.4 var(--font-body);
  letter-spacing: 1.4px;
  text-transform: uppercase;
  cursor: pointer;
}
.ah-form button:hover {
  opacity: 0.85;
}

/* --------- IMAGE TREATMENT (warm neutral placeholders) --------- */
.ah-img {
  width: 100%;
  height: 100%;
  background: var(
    --img-bg,
    linear-gradient(160deg, #efe8dc, #b7a890 70%, #7d6b50)
  );
  display: block;
}
.ah-img--warm {
  --img-bg: linear-gradient(160deg, #f1ead8 0%, #c6b394 55%, #8a7554 100%);
}
.ah-img--cool {
  --img-bg: linear-gradient(170deg, #e8e4d8 0%, #a59a84 60%, #6b5e47 100%);
}
.ah-img--oak {
  --img-bg: linear-gradient(180deg, #d9c6a3 0%, #9a7f55 55%, #5d4827 100%);
}
.ah-img--pine {
  --img-bg: linear-gradient(180deg, #efe3c9 0%, #c3a779 55%, #7a5f37 100%);
}
.ah-img--stone {
  --img-bg: linear-gradient(180deg, #ebe6db 0%, #a9a397 60%, #6b665b 100%);
}
.ah-img--brass {
  --img-bg: linear-gradient(160deg, #e9d7a8 0%, #b08e48 55%, #715923 100%);
}
.ah-img--ink {
  --img-bg: linear-gradient(170deg, #2d2722 0%, #1a1714 100%);
}
.ah-img--linen {
  --img-bg: linear-gradient(170deg, #f5efe2 0%, #d5cbb0 60%, #9b916f 100%);
}
.ah-img--sage {
  --img-bg: linear-gradient(170deg, #d6d6c5 0%, #8e9479 55%, #4e5544 100%);
}
.ah-img--sand {
  --img-bg: linear-gradient(180deg, #f1e6cf 0%, #d6bc8a 55%, #9d7e4e 100%);
}

/* image noise + warm fade-in animation */
.ah-img {
  position: relative;
  overflow: hidden;
  opacity: 0;
  animation: ah-fadein 900ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.ah-img::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(0, 0, 0, 0.08) 1px, transparent 1px),
    radial-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px);
  background-size: 3px 3px, 5px 5px;
  background-position: 0 0, 1px 1px;
  mix-blend-mode: overlay;
  opacity: 0.55;
  pointer-events: none;
}
@keyframes ah-fadein {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* --------- HOME HERO ENTRANCE --------- */
.ah-enter {
  opacity: 0;
  transform: translateY(12px);
  animation: ah-enter 1100ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.ah-enter-1 {
  animation-delay: 120ms;
}
.ah-enter-2 {
  animation-delay: 320ms;
}
.ah-enter-3 {
  animation-delay: 520ms;
}
.ah-enter-4 {
  animation-delay: 720ms;
}
@keyframes ah-enter {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --------- LINKS (body inline) --------- */
.ah-tlink {
  color: var(--color-ink);
  text-decoration: none;
  border-bottom: 1px solid var(--color-ink);
  padding-bottom: 1px;
}
.ah-tlink:hover {
  opacity: 0.6;
}

.ah-arrowlink {
  font-size: 12px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.ah-arrowlink::after {
  content: "";
  display: inline-block;
  width: 24px;
  height: 1px;
  background: var(--color-ink);
  transition: width 420ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ah-arrowlink:hover::after {
  width: 36px;
}

/* --------- PAGE HEADER (section titles) --------- */
.ah-pagehead {
  padding: 64px var(--content-gutter-right) 48px var(--content-gutter-left);
  margin: 0 calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  border-bottom: 1px solid var(--color-ink);
  align-items: end;
}
.ah-pagehead--flush {
  padding-top: 56px;
  border-bottom: 0;
}
.ah-pagehead--stack {
  grid-template-columns: 1fr;
}
.ah-pagehead-title {
  font-family: var(--font-display);
  font-size: var(--hero-fluid);
  line-height: 1.04;
  margin: 0;
  font-weight: 400;
  letter-spacing: -0.008em;
}
.ah-pagehead-title em {
  font-style: italic;
}
.ah-pagehead-kicker {
  display: none;
}
.ah-pagehead-lede {
  font-size: 17px;
  line-height: 1.55;
  max-width: 46ch;
  color: var(--text-ink);
}

/* --------- BREADCRUMB --------- */
.ah-crumb {
  font-family: var(--font-body);
  font-size: 14px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-ink);
  padding: 24px 0 0;
}
.ah-crumb a {
  color: var(--color-ink);
  text-decoration: none;
}
.ah-crumb a:hover {
  color: var(--color-ink);
}
.ah-crumb-sep {
  margin: 0 10px;
  color: var(--color-ink);
}

/* --------- TAB / SUB-NAV --------- */
.ah-subnav {
  display: flex;
  gap: 32px;
  padding: 24px 0 0;
  flex-wrap: wrap;
}
.ah-subnav a {
  font-family: var(--font-display);
  font-size: 22px;
  color: var(--color-ink);
  text-decoration: none;
  line-height: 1.3;
}
.ah-subnav a.is-active {
  font-style: italic;
}
.ah-subnav a:hover {
  opacity: 0.6;
}
.ah-subnav .ah-sup {
  font-size: 0.45em;
}

/* --------- RESPONSIVE --------- */
@media (max-width: 1023px) {
  /* .ah-page and .ah-footer pick up the wider gutter automatically
     via the :root --content-gutter-* token override above; no per-
     selector padding overrides needed. The full-bleed-rule sections
     below still need their negative margin / inner padding pair, but
     those values come from the token too. */
  .ah-footer-util {
    margin-left: calc(-1 * var(--content-gutter-left));
    margin-right: calc(-1 * var(--content-gutter-right));
    padding-left: var(--content-gutter-left);
    padding-right: var(--content-gutter-right);
  }
  .ah-note {
    margin-left: calc(-1 * var(--content-gutter-left));
    margin-right: calc(-1 * var(--content-gutter-right));
    padding-left: var(--content-gutter-left);
    padding-right: var(--content-gutter-right);
  }
  .ah-sealrow {
    margin-left: calc(-1 * var(--content-gutter-left));
    margin-right: calc(-1 * var(--content-gutter-right));
    padding-left: var(--content-gutter-left);
    padding-right: var(--content-gutter-right);
  }
  .ah-pagehead {
    margin-left: calc(-1 * var(--content-gutter-left));
    margin-right: calc(-1 * var(--content-gutter-right));
    padding-left: var(--content-gutter-left);
    padding-right: var(--content-gutter-right);
  }
  .ah-journal-head {
    margin-left: calc(-1 * var(--content-gutter-left));
    margin-right: calc(-1 * var(--content-gutter-right));
    padding-left: var(--content-gutter-left);
    padding-right: var(--content-gutter-right);
  }
  .ah-article-header {
    margin-left: calc(-1 * var(--content-gutter-left));
    margin-right: calc(-1 * var(--content-gutter-right));
    padding-left: var(--content-gutter-left);
    padding-right: var(--content-gutter-right);
  }
  .ah-nav-inner {
    padding: 0 24px;
  }
  .ah-nav-center {
    display: none;
  }
  .ah-nav-util {
    display: none;
  }
  .ah-grid-4 {
    grid-template-columns: repeat(2, 1fr);
  }
  .ah-grid-3 {
    grid-template-columns: repeat(2, 1fr);
  }
  /* 2-up: reset the 4-up edge rules, then realign col 1 + col 2 to the gutter. */
  .ah-grid-4--bleed > .ah-tile .ah-tile-caption {
    padding-left: 14px;
    padding-right: 14px;
  }
  .ah-grid-4--bleed > .ah-tile:nth-child(2n + 1) .ah-tile-caption {
    padding-left: var(--content-gutter-left);
  }
  .ah-grid-4--bleed > .ah-tile:nth-child(2n) .ah-tile-caption {
    padding-right: var(--content-gutter-right);
  }
  .ah-plate {
    grid-template-columns: 1fr;
    gap: 40px;
  }
  .ah-team,
  .ah-contact,
  .ah-service-body,
  .ah-note,
  .ah-service-head,
  .ah-journal-head,
  .ah-pagehead {
    grid-template-columns: 1fr;
    gap: 32px;
  }
  .ah-article-body figure {
    margin: 2em 0;
  }
  .ah-pull {
    grid-template-columns: 1fr;
  }
  .ah-plate-gallery {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 640px) {
  .ah-grid-4,
  .ah-grid-3,
  .ah-grid-2 {
    grid-template-columns: 1fr;
  }
  .ah-hero-frame {
    grid-template-columns: 1fr;
  }
  /* 1-up: every caption is both leftmost and rightmost — gutter both sides. */
  .ah-grid-4--bleed > .ah-tile .ah-tile-caption {
    padding-left: var(--content-gutter-left);
    padding-right: var(--content-gutter-right);
  }
}

/* Header collapse — below 1000px the desktop nav links retire and the
   menu icon appears. The header bar, wordmark, and gutter are untouched. */
@media (max-width: 999px) {
  .ah-nav-links {
    display: none;
  }
  .ah-burger {
    display: flex;
  }
}
/* Below 600px the drawer occupies the full viewport width. */
@media (max-width: 599px) {
  .ah-mdrawer {
    width: 100vw;
  }
}

/* --------- SERVICE SUBPAGE (centered title + full-bleed hero) --------- */
.ah-svc-head {
  flex: none;
  min-height: var(--ah-hero-height);
  height: auto;
  padding: 24px var(--content-gutter-right) 24px var(--content-gutter-left);
  box-sizing: border-box;
  text-align: left;
}
.ah-svc-kicker {
  font-family: var(--font-body);
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--color-ink);
  margin: 0 0 18px;
  font-style: normal;
}
.ah-svc-kicker a {
  color: var(--color-ink);
  text-decoration: none;
}
.ah-svc-kicker a:hover {
  color: var(--color-ink);
}
.ah-svc-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--hero-fluid);
  line-height: 1.05;
  letter-spacing: -0.005em;
  margin: 0;
  padding-bottom: 0.06em;
}
.ah-svc-title em {
  font-style: italic;
}

.ah-svc-titlerow {
  display: flex;
  justify-content: space-between;
  gap: 32px;
  flex-wrap: nowrap;
  padding-right: 0;
  height: 100%;
}
.ah-svc-title {
  align-self: flex-start;
}
.ah-svc-tagline {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--dek-fluid);
  line-height: 1.2;
  color: var(--color-ink);
  white-space: normal;
  width: max-content;
  max-width: 60ch;
  text-align: right;
  flex: 0 0 auto;
  align-self: flex-end;
}

.ah-svc-hero-wrap {
  width: 100%;
  padding: 0;
  margin: 0;
  flex: 1 1 0%;
  min-height: 0;
  display: flex;
}
.ah-svc-hero {
  width: 100%;
  height: 100%;
  flex: 1 1 0%;
  aspect-ratio: auto;
  display: block;
}

.ah-svc-essay {
  padding-bottom: 96px;
}
.ah-svc-lede {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(22px, 2.1vw, 30px);
  line-height: 1.4;
  max-width: 60ch;
  margin: 0 auto 56px;
  text-align: center;
  color: var(--text-ink);
}
.ah-svc-lede--inline {
  text-align: left;
  margin: 0 0 28px;
  max-width: 32ch;
  font-size: clamp(20px, 1.7vw, 24px);
  line-height: 1.45;
}
/* Post-hero rule removed: the lede block ("Why the work matters") no longer
   draws a border under the service-subpage hero image. The 56px top padding
   on .ah-service-body keeps the image-to-section gap visually intact. Scoped
   to .ah-service-body--lede only — section dividers elsewhere (the shared
   .ah-rule hairlines, homepage, Selected Works) are unaffected. */
.ah-service-body--lede + hr.ah-rule {
  display: none;
}

/* --------- CONSULTANCY PAGE --------- */
/* The hero reuses .ah-svc-head / .ah-svc-titlerow / .ah-svc-tagline so the
   title and image positioning match the rest of the services subpages.
   Only additions here are a small uppercase eyebrow above the title, and
   sizing adjustments to the dek so the longer copy holds its right-column
   alignment without crowding the title. */
/* The new consultancy dek is short (three words). Let it sit as a single
   italic line, sized to feel balanced against the big "Consultancy" title,
   and anchored to the bottom-right of the hero row like the other services. */
.ah-consult-dek {
  font-size: clamp(28px, 3vw, 44px);
  line-height: 1.2;
  width: auto;
  max-width: none;
  white-space: nowrap;
  align-self: flex-end;
}
@media (max-width: 900px) {
  .ah-consult-dek {
    font-size: 26px;
    align-self: flex-end;
  }
}

/* Selector + body — two columns. Left: the three building types stacked in
   Tid Display italic, hover-driven. Right: the active paragraph. Hovering a
   selector item sets it active instantly; unselected items sit at reduced
   opacity and the hovered/selected item snaps to full opacity with NO
   transition and no colour shift. The last hovered selection persists on
   mouse-out (state isn't reverted), and the paragraph swap is instant. */
.ah-consult-select {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 96px;
  align-items: start;
  padding-top: 120px;
  padding-bottom: 96px;
}
.ah-consult-select__nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}
.ah-consult-select__item {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(30px, 3.2vw, 44px);
  line-height: 1.3;
  letter-spacing: -0.003em;
  color: var(--color-ink);
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  text-align: left;
  cursor: pointer;
  opacity: 0.32;
  transition: none;
}
.ah-consult-select__item:hover,
.ah-consult-select__item.is-active {
  opacity: 1;
}
.ah-consult-select__item:focus-visible {
  outline: 1px solid var(--color-ink);
  outline-offset: 4px;
}
.ah-consult-select__body {
  display: grid;
}
.ah-consult-select__p {
  grid-area: 1 / 1;
  visibility: hidden;
  font-size: var(--type-body);
  line-height: 1.6;
  max-width: 70ch;
  margin: 0;
  color: var(--text-ink);
}
.ah-consult-select__p.is-shown {
  visibility: visible;
}

/* Static block below the selector — intro line, two lead-in lists, and a
   quiet closing line. Lead-ins share a treatment that distinguishes them
   from the bullets without resorting to icons or cards. */
/* Intra-block gaps within a consultancy section are a single 120px,
   owned entirely by each lower block's padding-top; the upper block's
   padding-bottom is zeroed so no stacked padding leaks into the gap.
   The section boundaries (static padding-top 80, select padding-bottom
   96) are preserved so section-to-section spacing is unchanged. */
.ah-consult-static {
  padding-top: 80px;
  padding-bottom: 0;
}
.ah-consult-intro-block {
  padding-top: 120px;
  padding-bottom: 0;
}
.ah-consult-intro {
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 400;
  /* Held at 24px (Subtitle). To keep the ~3-line count the BOX widens to fit
     the type — the type never shrinks. At 24px three lines need roughly
     1120–1600px of measure, so the paragraph fills the page content width
     (running wider than the other blocks) and caps at 1600px so it can't
     collapse to 2 lines on ultra-wide screens. The 14px page gutter keeps it
     off the viewport edge. Below ~1150px the content box can't hold 24px in
     3 lines, so it wraps to 4+ lines (still 24px) — no clamping, full text
     always visible. */
  font-size: var(--type-subtitle);
  line-height: 1.45;
  width: min(1600px, 100%);
  max-width: none;
  margin: 0 auto;
  text-align: center;
  text-wrap: balance;
  color: var(--text-ink);
}
.ah-consult-list {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 96px;
  padding: 40px 0;
}
.ah-consult-list__lead {
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 400;
  font-size: var(--hero-display-size);
  line-height: 1.05;
  letter-spacing: -0.005em;
  color: var(--color-ink);
  align-self: start;
}
.ah-consult-list__items {
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: none;
}
.ah-consult-list__items li {
  font-size: 16px;
  line-height: 1.62;
  color: var(--text-ink);
  padding: 9px 0;
  display: flex;
  align-items: baseline;
  gap: 16px;
  white-space: nowrap;
}
.ah-consult-list__items li:first-child {
  padding-top: 0;
}
.ah-consult-list__items li:last-child {
  padding-bottom: 0;
}
.ah-consult-list__num {
  flex: 0 0 auto;
  width: 2ch;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--color-ink);
}

.ah-consult-closing {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 22px;
  line-height: 1.45;
  max-width: 52ch;
  margin: 80px 0 0;
  color: var(--text-ink);
}

@media (max-width: 900px) {
  .ah-consult-select {
    grid-template-columns: 1fr;
    gap: 24px;
  }
  .ah-consult-list {
    grid-template-columns: 1fr;
    gap: 18px;
  }
  .ah-consult-list__items li {
    white-space: normal;
  }
  .ah-consult-closing {
    font-size: 19px;
    margin-top: 56px;
  }
}

/* --------- ABOUT SPREAD (Artifex Heritage) --------- */
.ah-spread {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: calc(100vh - 80px);
  margin: 0 calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
  position: relative;
  background: var(--color-background);
  align-items: start;
}
.ah-spread-left {
  position: relative;
  padding: 56px 64px 96px 64px;
  display: grid;
  grid-template-rows: auto 1fr;
  gap: 0;
}
.ah-spread-kicker {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--color-ink);
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 56px;
}
.ah-spread-kicker::before {
  content: "01";
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.5px;
  color: var(--color-ink);
}
.ah-spread-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(56px, 7.4vw, 116px);
  line-height: 0.95;
  letter-spacing: -0.012em;
  color: var(--color-ink);
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.ah-spread-title-l1 {
  padding-left: 0;
}
.ah-spread-title-l2 {
  padding-left: 1.4em;
  font-style: italic;
}
.ah-spread-meta {
  margin-top: 28px;
  font-size: 12px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-ink);
  display: flex;
  gap: 28px;
  align-items: baseline;
}
.ah-spread-meta-rule {
  flex: 1;
  height: 1px;
  background: #c4c2bc;
  align-self: center;
}
.ah-spread-body {
  --ah-dropcap-lh: 1.7;
  align-self: end;
  padding-top: 96px;
  width: 100%;
  max-width: 56ch;
  columns: 2;
  column-gap: 48px;
  column-fill: balance;
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--color-ink);
  text-align: justify;
  hyphens: auto;
}
.ah-spread-body p {
  margin: 0 0 1em;
  break-inside: avoid-column;
}
.ah-spread-body p:last-child {
  margin-bottom: 0;
}
.ah-spread-body strong {
  font-weight: 500;
  color: var(--color-ink);
}
.ah-spread-body em {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.06em;
}
.ah-spread-foot {
  margin-top: 56px;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 11px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-ink);
}
.ah-spread-foot-num {
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.5px;
}

.ah-spread-right {
  position: relative;
  height: calc(100vh - 40px);
  align-self: start;
  background: #c8b18a;
  overflow: hidden;
}
.ah-spread-right image-slot,
.ah-spread-right .ah-spread-fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.ah-spread-right .ah-spread-fallback {
  background: radial-gradient(ellipse at 30% 35%, #e8d4b1 0%, transparent 55%),
    linear-gradient(155deg, #d4ba8e 0%, #a78757 55%, #5a4220 100%);
}
.ah-spread-right .ah-spread-flourish {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  mix-blend-mode: screen;
  opacity: 0.65;
}
.ah-spread-right .ah-spread-mark {
  position: absolute;
  bottom: 24px;
  right: 32px;
  z-index: 3;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 1.6px;
  color: rgba(255, 255, 255, 0.86);
  text-transform: uppercase;
}
.ah-spread-right .ah-spread-stamp {
  position: absolute;
  top: 32px;
  left: 32px;
  z-index: 3;
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 2px;
  color: rgba(255, 255, 255, 0.86);
  text-transform: uppercase;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.ah-spread-right .ah-spread-stamp::before {
  content: "";
  display: inline-block;
  width: 28px;
  height: 1px;
  background: rgba(255, 255, 255, 0.7);
  transform: translateY(-3px);
}

/* --------- OUR PHILOSOPHY (manifesto band) --------- */
.ah-philo {
  position: relative;
  background: #2c2620;
  color: #f1ead8;
  padding: 120px var(--content-gutter-right) 140px var(--content-gutter-left);
  margin: 0 calc(-1 * var(--content-gutter-right)) 0
    calc(-1 * var(--content-gutter-left));
}

.ah-philo-head {
  max-width: 1320px;
  margin: 0 auto 96px;
  padding: 0 48px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 48px;
}
.ah-philo-kicker {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  color: #c8b18a;
  display: block;
}
.ah-philo-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(56px, 8vw, 132px);
  line-height: 0.96;
  letter-spacing: -0.02em;
  margin: 0;
  color: #f1ead8;
  text-wrap: pretty;
}
.ah-philo-title span {
  display: block;
}
.ah-philo-title span:nth-child(2) {
  padding-left: 1.4em;
}
.ah-philo-title span:nth-child(3) {
  padding-left: 0.4em;
}
.ah-philo-title-em {
  font-style: italic;
  color: #d6b984;
}

.ah-philo-tenets {
  list-style: none;
  margin: 0 auto;
  padding: 0 48px;
  max-width: 1320px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 96px;
  row-gap: 0;
  counter-reset: philo;
}
.ah-philo-tenet {
  position: relative;
  display: grid;
  grid-template-columns: 96px 1fr;
  column-gap: 32px;
  padding: 56px 0 64px;
}
.ah-philo-tenet:nth-child(1),
.ah-philo-tenet:nth-child(2) {
  padding-top: 0;
}
.ah-philo-tenet:nth-child(odd) {
  padding-right: 24px;
}
.ah-philo-tenet:nth-child(even) {
  padding-left: 24px;
}

.ah-philo-num {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 56px;
  line-height: 1;
  color: #d6b984;
  letter-spacing: -0.02em;
  align-self: start;
  padding-top: 8px;
}
.ah-philo-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 36px;
  line-height: 1.04;
  letter-spacing: -0.01em;
  margin: 0 0 20px;
  color: #f1ead8;
}
.ah-philo-body {
  font-size: var(--type-body);
  line-height: 1.7;
  margin: 0;
  color: rgba(241, 234, 216, 0.82);
  max-width: 44ch;
  grid-column: 2;
}
.ah-philo-body em {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.04em;
  color: #f1ead8;
}

.ah-philo-foot {
  max-width: 1320px;
  margin: 96px auto 0;
  padding: 56px 48px 0;
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 24px;
  flex-wrap: wrap;
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1.5;
  color: rgba(241, 234, 216, 0.78);
  text-align: center;
}
.ah-philo-foot em {
  font-style: italic;
  color: #d6b984;
}
.ah-philo-foot-mark {
  color: #c8b18a;
  letter-spacing: 0.2em;
}

@media (max-width: 1023px) {
  .ah-philo {
    padding: 80px var(--content-gutter-right) 96px var(--content-gutter-left);
    margin: 0 calc(-1 * var(--content-gutter-right)) 0
      calc(-1 * var(--content-gutter-left));
  }
  .ah-philo::before,
  .ah-philo::after {
    left: 32px;
    right: 32px;
  }
  .ah-philo-head {
    padding: 0;
    margin-bottom: 64px;
  }
  .ah-philo-tenets {
    padding: 0;
    grid-template-columns: 1fr;
    column-gap: 0;
  }
  .ah-philo-tenet {
    padding: 48px 0;
  }
  .ah-philo-tenet:nth-child(1) {
    padding-top: 0;
  }
  .ah-philo-tenet:nth-child(2) {
    padding-top: 48px;
  }
  .ah-philo-tenet:nth-child(even) {
    padding-left: 0;
  }
  .ah-philo-tenet:nth-child(odd) {
    padding-right: 0;
  }
  .ah-philo-name {
    font-size: 28px;
  }
  .ah-philo-foot {
    padding: 40px 0 0;
    margin-top: 64px;
    font-size: 18px;
  }
}

/* --------- (legacy) team-bio continuation, kept for safety --------- */
/* padding: 96px 64px 120px;
  border-top: 1px solid var(--color-ink);
  background: var(--color-background);
  margin: 0 calc(-1 * var(--content-gutter-right)) 0 calc(-1 * var(--content-gutter-left));
} */
.ah-spread-cont-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 96px;
  max-width: 1280px;
  margin: 0 auto;
}
.ah-spread-cont-eyebrow {
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--color-ink);
}
.ah-spread-cont-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 2.6vw, 40px);
  line-height: 1.05;
  margin: 12px 0 22px;
}
.ah-spread-cont-bio {
  font-size: var(--type-body);
  line-height: 1.7;
  max-width: 46ch;
  color: var(--color-ink);
}
.ah-spread-cont-bio p {
  margin: 0 0 1em;
}
.ah-spread-cont-bio em {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.06em;
}
.ah-spread-cont-creds {
  margin-top: 24px;
  border-top: 1px solid var(--color-ink);
  padding-top: 18px;
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 8px 24px;
  font-size: 13px;
  line-height: 1.5;
}
.ah-spread-cont-creds dt {
  font-size: 10.5px;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--color-ink);
}
.ah-spread-cont-creds dd {
  margin: 0;
}

/* --------- ABOUT (single column) --------- */
/* About hero — editorial two-column composition. Headline occupies the
   top-left two-thirds; intro prose drops diagonally into the lower-right.
   Sized so headline + body fit within ~900px viewport height. The empty
   lower-left quadrant is intentional. */
.ah-about-hero {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  column-gap: 24px;
  padding: 40px 0 80px;
}
.ah-about-hero__title {
  grid-column: 1 / span 8;
  grid-row: 1;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--hero-fluid);
  line-height: 0.96;
  letter-spacing: -0.012em;
  color: var(--color-ink);
  margin: 0;
}
.ah-about-hero__title em {
  font-style: italic;
}
.ah-about-hero__body {
  grid-column: 7 / span 5;
  grid-row: 2;
  margin-top: 48px;
  font-size: 17px;
  line-height: 1.65;
  color: var(--color-ink);
}
.ah-about-hero__body p {
  margin: 0 0 1.1em;
}
.ah-about-hero__body p:last-child {
  margin-bottom: 0;
}

@media (max-width: 960px) {
  .ah-about-hero {
    column-gap: 16px;
    padding: 32px 0 72px;
  }
  .ah-about-hero__title {
    grid-column: 1 / -1;
  }
  .ah-about-hero__body {
    grid-column: 1 / -1;
    margin-top: 32px;
  }
}

.ah-about-portrait {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  margin-top: 64px;
  background: #eadfd0;
  overflow: hidden;
}

@media (max-width: 768px) {
  .ah-spread {
    grid-template-columns: 1fr;
    min-height: 0;
    margin: 0 calc(-1 * var(--content-gutter-right)) 0
      calc(-1 * var(--content-gutter-left));
  }
  .ah-spread-left {
    padding: 48px 32px 64px;
    border-right: 0;
    border-bottom: 1px solid var(--color-ink);
  }
  .ah-spread-right {
    min-height: 70vh;
  }
  .ah-spread-body {
    columns: 1;
    padding-top: 64px;
  }
  .ah-spread-cont {
    padding: 64px 32px 96px;
    margin: 0 calc(-1 * var(--content-gutter-right)) 0
      calc(-1 * var(--content-gutter-left));
  }
  .ah-spread-cont-grid {
    grid-template-columns: 1fr;
    gap: 64px;
  }
}

/* --------- THE PROCESS — HERO --------- */
/* Applied to a <section className="ah-page ah-process-hero"> — same pattern
   as <section className="ah-page ah-svc-head"> on /windows. The hero's own
   padding overrides .ah-page padding (source order); horizontal gutter is
   sourced from the global content-gutter token so this hero aligns with
   every other section hero. Vertical 24px breathing room is preserved. */
.ah-process-hero {
  min-height: var(--ah-hero-height);
  height: auto;
  padding: 24px var(--content-gutter-right) 24px var(--content-gutter-left);
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  gap: 64px;
  flex-wrap: nowrap;
  text-align: left;
}
.ah-process-hero__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--hero-fluid);
  line-height: 1.05;
  letter-spacing: -0.005em;
  margin: 0;
  padding-bottom: 0.06em;
  font-style: normal;
  flex: 0 0 auto;
  align-self: flex-start;
}
.ah-process-hero__title em {
  font-style: italic;
}
.ah-process-hero__lede {
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.55;
  color: var(--color-ink);
  margin: 0;
  flex: 0 1 46ch;
  max-width: 46ch;
  align-self: flex-end;
  text-align: right;
}
.ah-process-hero__lede p {
  margin: 0;
}
.ah-process-hero__lede p + p {
  margin-top: 1em;
}
@media (max-width: 720px) {
  .ah-process-hero {
    flex-wrap: wrap;
    gap: 32px;
  }
  .ah-process-hero__lede {
    flex-basis: auto;
    max-width: none;
  }
}

/* --------- THE PROCESS — TAB ROW --------- */
/* Applied to <section className="ah-page ah-process-tabrow"> for the same
   padding-override pattern. Inline sentence in Tiempos Display; tabs italic. */
.ah-process-tabrow {
  font-family: var(--font-display);
  font-weight: 400;
  /* Dek register — desktop ceiling pulls the canonical --type-dek (40px).
     Existing narrow-viewport ramp (down to 26px) preserved. */
  font-size: clamp(26px, 3.5vw, var(--type-dek));
  line-height: 1.25;
  color: var(--color-ink);
  padding: 40px var(--content-gutter-right) 40px var(--content-gutter-left);
  margin: 0;
  letter-spacing: -0.003em;
}
.ah-process-tabrow__static {
  color: var(--color-ink);
  opacity: 1;
  font-style: normal;
  font-family: inherit;
}
.ah-process-tab {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
  font-style: italic;
  color: var(--color-ink);
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  text-decoration: none;
  opacity: 0.32;
  display: inline;
}
.ah-process-tab:hover {
  opacity: 1;
}
.ah-process-tab.is-active {
  opacity: 1;
}
.ah-process-tab:focus-visible {
  outline: 1px solid var(--color-ink);
  outline-offset: 4px;
}
/* Step-count superscript — body sans against the serif host, raised to TRUE
   superscript position so its cap-top aligns with the host word's cap-top.
   line-height: 0 prevents the raised marker from inflating the tab row's
   line box. Inherits opacity from the parent button. */
.ah-process-tab__count {
  font-family: var(--font-body);
  font-style: normal;
  font-size: 0.42em;
  font-weight: 400;
  font-feature-settings: normal;
  letter-spacing: 0;
  position: relative;
  top: -1.2em;
  line-height: 0;
  margin-left: 0.45em;
  white-space: nowrap;
}
/* Full-width rule — same rendering technique as the nav's border-bottom
   (border-top: 1px solid #090401) so the line weight is pixel-identical.
   Rendered as a top-level sibling of the page wrapper (no .ah-page parent),
   so it spans the viewport edge-to-edge with no negative margin. */
.ah-process-rule {
  height: 0;
  border: 0;
  border-top: 1px solid var(--color-ink);
  margin: 0;
  padding: 0;
  background: transparent;
  display: block;
}

/* --------- THE PROCESS — STEP ROWS --------- */
/* Each step is a top-level sibling of the page wrapper, with full-bleed
   rules above and below. Horizontal padding is the shared 24px gutter on
   both sides, so the step's left column and the body copy's right edge sit
   on the same frame as every other block. */
.ah-process-step {
  display: grid;
  grid-template-columns: repeat(
    4,
    1fr
  ); /* four equal columns; boundaries at 25/50/75% */
  gap: 0; /* no inter-column gap, so the boundaries are exact */
  padding: 40px var(--content-gutter-right) 40px var(--content-gutter-left);
  align-items: baseline;
}
@media (max-width: 1023px) {
  .ah-process-step {
    padding-left: var(--content-gutter-left);
    padding-right: var(--content-gutter-right);
  }
}
@media (max-width: 720px) {
  .ah-process-step {
    grid-template-columns: 56px 1fr;
    gap: 24px;
  }
  .ah-process-step__body {
    grid-column: 1 / -1;
  }
}
.ah-process-step__num {
  grid-column: 1; /* column one — numeral at the gutter (unmoved) */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--type-subtitle);
  letter-spacing: 0;
  color: var(--color-ink);
  line-height: 1.3;
}
.ah-process-step__title {
  grid-column: 2; /* column two — title begins at 25% */
  font-family: var(--font-display);
  font-weight: 400;
  font-style: normal;
  font-size: var(--type-subtitle);
  line-height: 1.3;
  color: var(--color-ink);
  margin: 0;
}
.ah-process-step__body {
  /* No explicit grid-column: with the numeral pinned to col 1 and the title
     to col 2, the description auto-places into column THREE (50%→75%), leaving
     column four empty. The ≤720px override (grid-column: 1 / -1) still wins. */
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  color: var(--color-ink);
  margin: 0;
  text-align: left; /* ragged right — no justification */
  -webkit-hyphens: none;
  hyphens: none; /* no hyphenated line breaks */
}

/* --------- PRIVACY (/privacy) ---------
   Quiet text page. Inherits hero from .ah-process-hero and rule from
   .ah-process-rule. Body is a single ~62ch column, left-aligned, with
   small-caps section labels prefixed by Roman numerals. */

/* LAST UPDATED line — sits below the hero rule, right-aligned, in the
   same small-caps label register as the OFFICE / PRESS / NEWSLETTER
   labels on /contact. */
.ah-privacy-meta {
  padding-top: 24px;
  padding-bottom: 24px;
  text-align: right;
}
.ah-privacy-meta__updated {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-ink);
}

/* Body column — sits in the same left column the H1 starts in (24px from
   the viewport edge on desktop, since .ah-process-hero overrides .ah-page
   to 24px padding). We mirror that with section padding so the lede sits
   under the H1. */
.ah-privacy-body {
  padding-top: 24px;
  padding-bottom: 96px;
}
.ah-privacy-prose {
  max-width: 62ch;
  margin: 0;
  color: var(--color-ink);
}
.ah-privacy-prose p {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  color: var(--color-ink);
  margin: 0 0 1em;
}
.ah-privacy-prose p:last-child {
  margin-bottom: 0;
}
.ah-privacy-prose em {
  font-style: italic;
}

/* Lede paragraph — sits directly under the LAST UPDATED line, above the
   first section header. Slightly larger than body so it carries weight. */
.ah-privacy-lede {
  font-size: 17px !important;
  margin-bottom: 8px !important;
}

/* Section header — Roman numeral + non-breaking en-space + uppercase
   label, in the display face. Roughly 2.5× the paragraph leading of
   breathing room above each one. */
.ah-privacy-head {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 18px;
  letter-spacing: 0.18em;
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--color-ink);
  margin: 64px 0 22px;
}
.ah-privacy-head__num {
  font-style: italic;
  font-family: var(--font-display);
  letter-spacing: 0.06em;
  margin-right: 0.1em;
  display: inline-block;
  min-width: 1.6em;
}
.ah-privacy-head__label {
  /* label inherits text-transform from parent */
}

/* Em-dash leader list (not bullets) */
.ah-privacy-list {
  list-style: none;
  padding: 0;
  margin: 0 0 1em;
}
.ah-privacy-list li {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  color: var(--color-ink);
  margin: 0 0 12px;
  padding-left: 1.5em;
  text-indent: -1.5em;
}
.ah-privacy-list li::before {
  content: "— ";
  color: var(--color-ink);
}
.ah-privacy-list li:last-child {
  margin-bottom: 0;
}
.ah-privacy-list em {
  font-style: italic;
}

/* Inline links — quiet underline in the ink colour */
.ah-privacy-link {
  color: var(--color-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  transition: opacity 150ms ease;
}
.ah-privacy-link:hover {
  opacity: 0.6;
}

/* Address block in §XI */
.ah-privacy-address {
  font-style: normal;
}

/* Page foot — short paragraph left, Back to top right; stacked on mobile */
.ah-privacy-foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 32px;
  padding-top: 28px;
  padding-bottom: 64px;
}
.ah-privacy-foot__text {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--color-ink);
  margin: 0;
  max-width: 62ch;
}
.ah-privacy-foot__top {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-ink);
  text-decoration: none;
  white-space: nowrap;
  transition: opacity 150ms ease;
}
.ah-privacy-foot__top:hover {
  opacity: 0.6;
}

@media (max-width: 720px) {
  .ah-privacy-meta {
    text-align: right;
  }
  .ah-privacy-foot {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  .ah-privacy-foot__top {
    align-self: flex-end;
  }
  .ah-privacy-head {
    font-size: 16px;
    margin-top: 56px;
  }
  .ah-privacy-prose {
    max-width: none;
  }
}

/* ============================================================
   AFFILIATIONS BAND
   Full-bleed dark band that sits directly above the footer on
   the homepage. Hero echoes .ah-process-hero exactly (display
   face, size scale, alignment, padding); colour inverts to
   cream on brown. Beneath, a single slow right-to-left marquee.
   ============================================================ */

.ah-affil {
  /* Full-bleed: cancels the body / page gutter on both axes.
     Sits as a direct child of the screen wrapper (NOT inside .ah-page),
     so 100vw works cleanly without horizontal scroll (body has overflow-x: clip). */
  background: var(--color-background);
  color: var(--color-ink);
  /* No top rule — transition from the map section is handled by
     spacing alone. Bottom edge is supplied by the footer's own
     full-opacity top border (.ah-footer { border-top: 1px solid #090401 }). */
  border-top: 0;
  border-bottom: 0;
  /* Top buffer specified to the heading's CAP-TOP (one section-rhythm
     step to the visible top of "Affiliations"): subtract the display
     face's cap
     inset so the cap-top sits exactly one section-rhythm step below the
     Heritage band's settled bottom edge. The buffer ladders 120 / 80
     / 56 across desktop / tablet / phone (overrides below). */
  padding: calc(120px - var(--display-cap-inset)) 0 0;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* HERO — horizontal gutter sourced from the global content-gutter
   token so the Affiliations title aligns with every other section
   hero on the page. Vertical rhythm and font size unchanged. */
.ah-affil-hero {
  padding: 0 var(--content-gutter-right) 0 var(--content-gutter-left);
  /* Gap from hero baseline to the underlying rule — matches the
     Selected Works title-to-content gap (72/56/40). */
  margin: 0 0 72px;
}
.ah-affil-hero__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--hero-display-size);
  line-height: 1.05;
  letter-spacing: -0.005em;
  margin: 0;
  padding-bottom: 0.06em;
  font-style: normal;
  color: var(--color-ink);
}

/* Full-bleed structural rule beneath the hero title.
   Rendered as a border-top on the marquee wrap below (matching the
   footer's border-top implementation exactly) so both 1px rules are
   rasterised by the browser via the same code path — no sub-pixel
   mismatch from mixing background-fill HR and border-top approaches.
   The .ah-affil-rule class is retained as a no-op for any legacy refs. */
.ah-affil-rule {
  display: none;
}

/* Marquee wrap — occupies the full vertical space between the rule
   above and the section's bottom hairline below. Centred via flex on
   both axes so items align to their optical centre regardless of how
   tall they grow (wordmark only, logo only, or logo + wordmark). */
.ah-affil-marquee-wrap {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 0;
  /* Minimum breathing room above and below the tallest item. */
  padding: 56px 0;
  box-sizing: border-box;
  /* Upper structural rule — identical implementation to the footer's
     own border-top so the two rules rasterise the same. */
  border-top: 1px solid var(--color-ink);
}

/* MARQUEE */
.ah-affil-marquee {
  /* No edge fades — the band runs full-bleed and items clip hard at the
     container edge. overflow:hidden keeps scrolling items disappearing
     cleanly at both edges rather than spilling outside the band. */
  width: 100%;
  overflow: hidden;
}

.ah-affil-marquee__track {
  display: flex;
  width: max-content;
  /* 70s linear loop — slow, editorial. Two copies of the set,
     translate -50% across one cycle for a perfect seam. */
  animation: ah-affil-scroll 50s linear infinite;
  will-change: transform;
}

.ah-affil-marquee:hover .ah-affil-marquee__track {
  animation-play-state: paused;
}

.ah-affil-marquee__set {
  display: flex;
  align-items: center;
  gap: 96px;
  padding-right: 96px; /* gap between the seam join */
  flex: 0 0 auto;
}

.ah-affil-mark {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 24px;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--color-ink);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  height: 36px; /* matches logo cap-height target */
}

/* Two-line marks — same font size; an explicit pair of lines stacked in a
   column, each kept on one line. height:auto lets the band grow; the set's
   align-items:center keeps single- and two-line marks optically centred. */
.ah-affil-mark--stack {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: auto;
  line-height: 1.15;
}
.ah-affil-mark__line {
  white-space: nowrap;
}

@keyframes ah-affil-scroll {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

/* Visually-hidden accessible list */
.ah-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;
}

/* Tablet */
@media (max-width: 1023px) {
  .ah-affil {
    padding-top: calc(80px - var(--display-cap-inset));
  }
  .ah-affil-hero {
    padding: 0 var(--content-gutter-right) 0 var(--content-gutter-left);
    margin-bottom: 56px;
  }
  .ah-affil-marquee-wrap {
    padding: 40px 0;
  }
}

/* Phone */
@media (max-width: 720px) {
  .ah-affil {
    padding-top: calc(56px - var(--display-cap-inset));
  }
  .ah-affil-hero {
    padding: 0 var(--content-gutter-right) 0 var(--content-gutter-left);
    margin-bottom: 40px;
  }
  .ah-affil-marquee-wrap {
    padding: 32px 0;
  }
  .ah-affil-marquee__set {
    gap: 56px;
    padding-right: 56px;
  }
  .ah-affil-mark {
    font-size: 18px;
    height: 28px;
  }
}

/* Reduced motion — pause the marquee entirely; first set is centred. */
@media (prefers-reduced-motion: reduce) {
  .ah-affil-marquee {
    -webkit-mask-image: none;
    mask-image: none;
  }
  .ah-affil-marquee__track {
    animation: none;
    width: 100%;
    justify-content: center;
    flex-wrap: wrap;
  }
  .ah-affil-marquee__track .ah-affil-marquee__set:nth-child(2) {
    display: none;
  }
  .ah-affil-marquee__set {
    flex-wrap: wrap;
    justify-content: center;
    padding-right: 0;
    row-gap: 16px;
  }
}

/* ============================================================
   SERVICE AREA — 50/50 editorial split.
   Left: regional index with hover-reveal rows.
   Right: static SVG map (StatCan 2021 Census Division boundaries,
   reprojected from EPSG:3347). The map column is sticky so the index
   column can grow without shifting the map. Hover on an index row
   inverts the matching region's fill via a single data-active-region
   attribute on the SVG wrapper.
   Palette: var(--color-background) ground, #ebe7dc land base, #090401 linework & type.
   ============================================================ */

.ah-map-section {
  background: var(--color-background);
  color: var(--color-ink);
  /* Suppress scroll anchoring within this section. The map is anchored to the
     grid top (align-self:start on .ah-map-col) so its position is independent
     of accordion height; combined with the JS height reservation the section
     should never change height on open/close. overflow-anchor:none is the
     belt-and-suspenders guard: should any sub-pixel reflow occur, the browser
     will not re-anchor the scroll position and visually jump the map. Scoped
     to this section only. */
  overflow-anchor: none;
  border-top: 0;
  border-bottom: 0;
  box-sizing: border-box;
  display: block;
  position: relative;
  /* Heading-to-rule buffer token (used by .ah-map-head__title's bottom gap).
     The section itself has NO bottom padding: the gap from this section's
     settled (reservation-stabilised) bottom edge to the Affiliations hero is
     owned solely by .ah-affil's top padding (--space-hero-buffer, 120px), so
     the buffer is a single value and holds in every accordion state. */
  --map-section-buffer: 72px;
  padding-bottom: 0;
}

/* ----- SECTION HERO ----- */

.ah-map-head {
  /* Match the Selected Works hero rhythm: 120 top, 72 bottom on
     desktop, scaled at tablet/phone. Full-bleed: the hairline below
     spans both columns by sitting on the section's full width.
     Horizontal gutter sourced from the global token so all section
     heroes share a single left edge. */
  display: block;
  padding: 0 var(--content-gutter-right) 0 var(--content-gutter-left);
  margin: var(--space-hero-buffer) 0 0;
}
.ah-map-head__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--hero-display-size);
  line-height: 1.05;
  letter-spacing: -0.005em;
  margin: 0;
  padding: 0 0 var(--map-section-buffer);
  color: var(--color-ink);
}

/* Heading rule removed per spec — no rule sits beneath the
   "Service Area" heading band. The first accordion row therefore
   carries no top hairline; the per-row bottom hairlines (the
   dividers BETWEEN accordion items) are unaffected. */
.ah-map-head {
  border-bottom: 0;
}

/* --------- HOME EDITORIAL STATEMENT ---------
   Dek + two-column conservation block on the homepage, on the Service
   Area warm panel directly below its full-bleed top rule and above the
   "Service Area" hero. The two columns replicate the hero intro block's
   metrics (equal columns, 56px central gutter, a 1px #090401 hairline
   centred in the gutter, drop cap, justify, hyphens). Implemented with
   CSS grid rather than the template's multicol so the much-longer right
   paragraph renders in full and the hairline runs the right column's
   height. Background (var(--color-background)) and ink (#090401) inherit from
   .ah-map-section. */
.ah-statement {
  /* 72px below the rule (section buffer rhythm); gutters from the global
     token so the left edge aligns with every other section hero. */
  padding: 72px var(--content-gutter-right) 0 var(--content-gutter-left);
}
/* SW grid → Service Area inter-band gap: the section's full-bleed top
   rule closes Selected Works; the credo opens one section-rhythm step
   below it (the rule itself stays hard against the grid). The buffer
   ladders 120 / 80 / 56 across desktop / tablet / phone. */
.ah-map-section > .ah-statement {
  padding-top: 120px;
}
@media (max-width: 1023px) {
  .ah-map-section > .ah-statement {
    padding-top: 80px;
  }
}
@media (max-width: 720px) {
  .ah-map-section > .ah-statement {
    padding-top: 56px;
  }
}
.ah-statement .ah-hero-dek {
  margin: 0;
} /* wrapper owns the rule→dek space */
.ah-statement__block {
  --ah-dropcap-lh: 1.6;
  padding-top: 32px; /* dek→block gap = template intro padding-top */
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 0;
}
.ah-statement__block > p {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: inherit;
  text-align: justify;
  -webkit-hyphens: auto;
  hyphens: auto;
}
.ah-statement__block > p:first-child {
  padding-right: 28px;
}
.ah-statement__block > p + p {
  padding-left: 28px;
  border-left: 1px solid var(--color-ink); /* hairline on the right column's left edge, centred in the 56px gutter */
}
/* The statement owns the gap down to the Service Area hero. */
.ah-statement + .ah-map-head {
  margin-top: 96px;
}

/* Credo — single Tid Display italic line replacing the two-column essay.
   Inherits the section ink (#090401) and the 24px gutter from .ah-statement. */
.ah-credo__line {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--type-statement);
  line-height: 1.08;
  letter-spacing: -0.005em;
  color: var(--color-ink);
  max-width: none;
  margin: 0;
  text-wrap: pretty;
}
/* Service Area credo (the two-line conservation maxim) sits at 50px,
   matching the lowered hero statement. The Heritage band credo keeps
   the default statement size. */
.ah-map-section .ah-credo__line {
  font-size: 54px;
}
/* Heritage band credo sits at 54px. */
.ah-heritage-band .ah-credo__line {
  font-size: 54px;
}
.ah-credo__link {
  display: inline-block;
  margin-top: 32px;
  font-family: var(--font-body);
  font-size: 14px;
  white-space: nowrap;
}

/* The two homepage credo sections (Heritage band + Process band) sit in two
   slots whose spacing is bound to POSITION, not to the section. After the
   section swap, the Heritage band occupies slot 1 (above Services) and the
   Process band occupies slot 2 (after Service Area, last before the footer).
   The slot treatments below follow the positions. */

/* Slot 1 — credo section directly ABOVE Services. One standard inter-section
   step (120 / 80 / 56) below Selected Works; the gap DOWN to Services is owned
   by .ah-services' own 120px top margin. */
.ah-heritage-band > .ah-statement {
  padding-top: 120px;
}
@media (max-width: 1023px) {
  .ah-heritage-band > .ah-statement {
    padding-top: 80px;
  }
}
@media (max-width: 720px) {
  .ah-heritage-band > .ah-statement {
    padding-top: 56px;
  }
}

/* Slot 2 — credo section directly AFTER Service Area and last before the
   footer. Opaque cream so it paints over the map section's -175px desktop
   trailing overlap (the slot's job, regardless of which section fills it);
   it owns the buffer down to the footer's top rule (120 / 80 / 56). Its
   statement keeps the base 72px top padding the map overlap is tuned against. */
.ah-process-band {
  position: relative;
  background: var(--color-background);
  color: var(--color-ink);
  padding-bottom: 120px;
}
@media (max-width: 1023px) {
  .ah-process-band {
    padding-bottom: 80px;
  }
}
@media (max-width: 720px) {
  .ah-process-band {
    padding-bottom: 56px;
  }
}

@media (max-width: 768px) {
  /* Single column in document order (P1 then P2). Matches the template's
     narrow fallback: left-align + manual hyphenation to avoid justified
     word-gap rivers. Drop cap retained (house default drops it here). */
  .ah-statement + .ah-map-head {
    margin-top: 80px;
  }
  .ah-credo__line {
    font-size: 34px;
    max-width: 100%;
  }
  .ah-statement__block {
    grid-template-columns: 1fr;
  }
  .ah-statement__block > p {
    text-align: left;
    -webkit-hyphens: manual;
    hyphens: manual;
  }
  .ah-statement__block > p:first-child {
    padding-right: 0;
  }
  .ah-statement__block > p + p {
    padding-left: 0;
    border-left: 0;
    margin-top: 1.1em;
  }
  .ah-statement .ah-drop .ah-dropcap {
    float: left;
    font-size: calc((5 * var(--ah-dropcap-lh, 1.6) + 1) / 2 * 1em);
    line-height: 1;
    padding-top: calc(
      (var(--ah-dropcap-lh, 1.6) - 1) / (5 * var(--ah-dropcap-lh, 1.6) + 1) *
        1em
    );
    margin: 0 0.1em 0 0;
  }
}
@supports (text-box-trim: trim-both) {
  @media (max-width: 768px) {
    .ah-statement .ah-drop .ah-dropcap {
      text-box-trim: trim-both;
      text-box-edge: cap alphabetic;
      font-size: calc((2 * var(--ah-dropcap-lh, 1.6) + 0.7) / 0.7 * 1em);
      padding-top: 0;
      margin-top: calc(
        (0.35 * (var(--ah-dropcap-lh, 1.6) - 1) + 0.26) /
          (2 * var(--ah-dropcap-lh, 1.6) + 0.7) * 1em
      );
    }
  }
}

/* ----- 40/60 grid below the hero — map column wider so all
   seven regions fit. No column gap; the map starts exactly where
   the index column ends. ----- */

.ah-map-grid {
  display: grid;
  grid-template-columns: 2fr 3fr;
  grid-template-rows: auto;
  align-items: stretch;
  gap: 0;
}

/* ----- LEFT COLUMN: regional index -----
   No horizontal padding on the column itself so the row hairlines
   span the full column width (touching the viewport's left edge and
   the map column's left edge). Content alignment with the site's
   editorial gutter is restored via padding-left on the row content. */

.ah-region-col {
  /* Auto height — grows as a row expands. Anchored to the top of
     the column so the first row's hairline sits at the standard
     hero-to-content gap below the Service Area heading hairline,
     matching the rhythm used by Selected Works and other section
     heros. The map column's top edge aligns with this top hairline
     via align-items: start on the grid. */
  display: flex;
  align-items: flex-start;
  padding: 0 0 80px 0;
  box-sizing: border-box;
}
.ah-region-inner {
  width: 100%;
}

.ah-region-list {
  list-style: none;
  margin: 0;
  padding: 0;
  /* No top hairline — the Service Area hero's full-bleed hairline
     directly above doubles as the top edge of the first row. Each
     row carries its own bottom hairline. */
}

.ah-region-row {
  position: relative;
  /* Bottom hairline per row — full ink, spans full column width
     because horizontal padding lives on .ah-region-headrow, not the row. */
  border-bottom: 1px solid var(--color-ink);
  cursor: pointer;
  display: block;
}

.ah-region-headrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* Vertical breathing room + horizontal gutter for content alignment.
     Left edge sits on the standard 24px page gutter (matches the
     "Service Area" hero and the rest of the page body). */
  padding: 28px 32px 28px var(--content-gutter-left);
  transition: transform 400ms cubic-bezier(0.25, 1, 0.5, 1);
  will-change: transform;
}
.ah-region-row.is-open .ah-region-headrow {
  transform: translateX(4px);
}
.ah-region-heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--type-subtitle);
  line-height: 1.05;
  letter-spacing: 0.005em;
  color: var(--color-ink);
  margin: 0;
}

/* Reveal pane — single height-driven animation. Content does not
   fade and does not translate; it simply reveals as the row unfolds. */
.ah-region-reveal {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 400ms cubic-bezier(0.25, 1, 0.5, 1);
}
.ah-region-row.is-open .ah-region-reveal {
  grid-template-rows: 1fr;
}
.ah-region-reveal-inner {
  overflow: hidden;
  min-height: 0;
}
.ah-region-places {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--color-ink);
  margin: 0;
  /* Match the heading's left gutter so the revealed text aligns
     vertically with the heading above it. Right padding pulls the
     line of text inset from the right column edge for legibility. */
  padding: 12px 32px 28px var(--content-gutter-left);
}

/* ----- RIGHT COLUMN: the static SVG map ----- */

.ah-map-svg-wrap {
  /* The map sizes itself to the column width and lets the SVG's
     1000:767 aspect ratio drive the height — no fixed viewport-
     relative height, no transform shift, no overflow clipping.
     This keeps every label inside the visible map regardless of
     viewport size, and lets the section's padding-bottom provide
     deliberate breathing room below the southern coast. */
  position: relative;
  width: 100%;
  aspect-ratio: 1000 / 767;
  background: var(--color-background);
}

/* The grid cell that hosts the map. Natural height — driven by the
   SVG aspect ratio above. `align-self: start` keeps the cell from
   stretching to match the index column's height (so it doesn't grow
   when an index row expands). */
.ah-map-col {
  position: relative;
  align-self: start;
  width: 100%;
}
.ah-map-svg-mount,
.ah-map-svg-mount svg {
  display: block;
  width: 100%;
  height: auto;
}
.ah-service-svg {
  /* Container styling lives here; per-element fills below. */
  display: block;
}

/* Land base — the rect behind everything, visible wherever no region
   path paints. Vellum so the map's outer boundary effectively dissolves
   into the section background; only the region polygons (white) and
   their hairline borders read on the page. */
.land-base-fill {
  fill: var(--color-background);
}

/* Region polygons — default state. White paper against the vellum
   surround. Fill change is INSTANT (no transition): hover toggles a
   state indicator, not a content reveal. */
.region {
  fill: #ffffff;
  stroke: var(--color-ink);
  stroke-opacity: 0.3;
  stroke-width: 0.5;
  vector-effect: non-scaling-stroke;
  cursor: pointer;
}

/* Region inversion — driven by a single data attr on the SVG wrap.
   Listed explicitly so the rule's specificity is consistent and we
   don't depend on attribute-selector matching against arbitrary values. */
.ah-map-svg-wrap[data-active-region="region-city-of-ottawa"]
  #region-city-of-ottawa,
.ah-map-svg-wrap[data-active-region="region-ottawa-valley"]
  #region-ottawa-valley,
.ah-map-svg-wrap[data-active-region="region-lanark"] #region-lanark,
.ah-map-svg-wrap[data-active-region="region-leeds-grenville"]
  #region-leeds-grenville,
.ah-map-svg-wrap[data-active-region="region-frontenac-kingston"]
  #region-frontenac-kingston,
.ah-map-svg-wrap[data-active-region="region-stormont-dundas-glengarry"]
  #region-stormont-dundas-glengarry,
.ah-map-svg-wrap[data-active-region="region-prescott-russell"]
  #region-prescott-russell {
  fill: var(--color-ink);
  stroke-opacity: 0;
}

/* City markers and labels — italic serif, ink. The base layer is
   always rendered in ink; vellum duplicates live in #labels-overlay
   and become visible (clipped to the region) when their region is
   active, producing two-toned text at the polygon edge. */
.city-dot {
  fill: var(--color-ink);
}
/* Ottawa composite marker — open circle + filled five-point star.
   Inverts to vellum when the City of Ottawa region is active, via the
   labels-overlay duplicate that's clipped to the region polygon. */
.ottawa-marker-ring {
  fill: none;
  stroke: var(--color-ink);
  stroke-width: 1.2px;
}
.ottawa-marker-star {
  fill: var(--color-ink);
}
#labels-overlay .ottawa-marker-ring {
  stroke: var(--color-background);
}
#labels-overlay .ottawa-marker-star {
  fill: var(--color-background);
}
.city-label {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 11.5px;
  fill: var(--color-ink);
  letter-spacing: 0.04em;
}
.city-label.is-primary {
  font-size: 13px;
  font-weight: 400;
}

/* Labels are pointer-event-transparent so the underlying region
   path receives hover/click events, even where a label sits over it. */
#labels-base,
#labels-rivers,
#labels-overlay {
  pointer-events: none;
}

/* River labels — quieter italic. Ditto: no stroke or halo. */
.river-label {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.12em;
  fill: rgba(9, 4, 1, 0.55);
}

/* Overlay layer — vellum duplicates of dots/labels inside each region,
   clipped to that region's polygon via <clipPath>. Hidden by default,
   shown when the wrap's data-active-region matches the overlay's region.
   Visibility toggle is instant (no transition) to match the region fill. */
#labels-overlay > g {
  visibility: hidden;
}
#labels-overlay .city-dot,
#labels-overlay .city-label,
#labels-overlay .river-label {
  fill: var(--color-background);
}
.ah-map-svg-wrap[data-active-region="region-city-of-ottawa"]
  #overlay-region-city-of-ottawa,
.ah-map-svg-wrap[data-active-region="region-ottawa-valley"]
  #overlay-region-ottawa-valley,
.ah-map-svg-wrap[data-active-region="region-lanark"] #overlay-region-lanark,
.ah-map-svg-wrap[data-active-region="region-leeds-grenville"]
  #overlay-region-leeds-grenville,
.ah-map-svg-wrap[data-active-region="region-frontenac-kingston"]
  #overlay-region-frontenac-kingston,
.ah-map-svg-wrap[data-active-region="region-stormont-dundas-glengarry"]
  #overlay-region-stormont-dundas-glengarry,
.ah-map-svg-wrap[data-active-region="region-prescott-russell"]
  #overlay-region-prescott-russell {
  visibility: visible;
}

/* Fallback when the SVG fails to load — quiet copy. */
.ah-map-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-family: var(--font-body);
  font-size: 14px;
  color: rgba(9, 4, 1, 0.6);
  padding: 32px;
}

/* Visually-hidden helper (reused) */
.ah-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;
}

/* ----- Tablet / narrow-desktop: keep 40/60 but tighten padding ----- */
@media (max-width: 1280px) {
  .ah-region-col {
    padding: 0 0 56px 0;
  }
  .ah-region-headrow {
    padding: 22px 32px 22px var(--content-gutter-left);
  }
  .ah-region-places {
    padding: 10px 32px 22px var(--content-gutter-left);
  }
  .ah-region-heading {
    font-size: clamp(22px, 2.4vw, 28px);
  }
}

/* ----- Mobile (<1024px): stack column above map; map is not sticky ----- */
@media (max-width: 1023px) {
  .ah-map-head {
    margin-top: 80px;
    padding: 0 var(--content-gutter-right) 0 var(--content-gutter-left);
  }
  .ah-map-head__title {
    padding-bottom: 56px;
  }
  .ah-map-grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
    min-height: 0;
  }
  .ah-region-col {
    padding: 0 0 56px 0;
    align-items: flex-start;
    min-height: 0;
  }
  .ah-region-inner {
    max-width: none;
  }
  .ah-map-col {
    position: static;
  }
  .ah-map-svg-wrap {
    position: static;
    /* aspect-ratio (1000 / 767) from the desktop rule continues to
       drive the height; no fixed viewport-relative height. */
    margin-top: 0;
  }
  /* City labels scale a bit smaller on phones */
  .city-label {
    font-size: 12px;
  }
  .city-label.is-primary {
    font-size: 14px;
  }
  .river-label {
    font-size: 10px;
  }
}

/* ----- Phone refinements ----- */
@media (max-width: 720px) {
  .ah-map-head {
    margin-top: 56px;
    padding: 0 var(--content-gutter-right) 0 var(--content-gutter-left);
  }
  .ah-map-head__title {
    padding-bottom: 40px;
  }
  .ah-region-col {
    padding: 0 0 40px 0;
  }
  .ah-region-headrow {
    padding: 20px 24px 20px var(--content-gutter-left);
  }
  .ah-region-places {
    padding: 8px 24px 20px var(--content-gutter-left);
  }
  .ah-region-heading {
    font-size: 24px;
  }
}

/* ----- Reduced motion ----- */
@media (prefers-reduced-motion: reduce) {
  .region,
  .ah-region-headrow,
  .ah-region-reveal,
  .ah-region-reveal-inner {
    transition: none !important;
  }
}

/* ----- Service Area — side-by-side height reservation (desktop) -----
   The accordion column is held at a constant height so expand/collapse
   never resizes the section (and never shifts Affiliations below it).
   The reserved min-height is measured per viewport width at runtime by
   ServiceMap (collapsed rows + the tallest single-row reveal) — a fixed
   px would be wrong at other widths because the reveal grows as the
   column narrows. Here we only drop the column's bottom padding in the
   side-by-side band, so the single --map-section-buffer (72px) is the
   ONLY gap from the section content to the Affiliations hero. Below
   1024px the columns stack: ServiceMap clears the min-height and the
   column keeps its normal flow padding (see the max-width rules above). */
@media (min-width: 1024px) {
  .ah-region-col {
    padding-bottom: 0;
    /* TOP-align the region list within the fixed (tallest-open) column
       height. The first row is pinned to the column top; the reserved
       expansion room sits BELOW the last row. Opening a row therefore
       expands DOWNWARD: rows above the open item hold position, rows below
       shift down into the reserved room, and the column's total height
       (held by the JS-measured min-height) never changes — so nothing below
       the section, including Affiliations, moves. */
    align-items: flex-start;
    /* Static vertical offset for the whole accordion block (all seven rows
       + dividers) as one unit. Combines step 2 (level "City of Ottawa" cap
       with the map's "Hawkesbury" label) and step 3 (set the 82px heading→
       first-row glyph gap). Purely a compositor offset: it does NOT touch
       internal row spacing, the min-height reservation, or expand/collapse.
       Derived by live glyph measurement at desktop width: -41.6px lands the
       "City of Ottawa" cap exactly 82px below the "Service Area" heading's
       lowest glyph AND level with the map's "Hawkesbury" label. */
    transform: translateY(-41.6px);
  }
  /* Map stays in normal grid flow (fully visible, never clipped). The fixed
     accordion height keeps the grid height constant, so the map never moves
     when a row opens/closes. Size/scale/aspect/horizontal placement unchanged. */
  .ah-map-col {
    /* Permanent static vertical offset (step 3 move). A transform is a
       compositor-level offset that never participates in layout, so it is
       never recalculated or re-animated on accordion open/close, on scroll-
       reveal playback, or on any interaction. No JS drives the map position.
       Horizontal position and scale unchanged. The -120.2px raises the map so
       its "Hawkesbury" label (top of the labelled extent) is level with the
       "City of Ottawa" first row, holding the step-2 alignment after the
       step-3 move. */
    transform: translateY(-120.2px);
  }

  /* ----- Open-panel title→body gap normalised to the site standard -----
     The expanded panel's body text (Inter) must sit --space-heading-body
     (14px) below the region title (Tid Display), matching the heading-to-body
     rhythm used elsewhere on the site rather than the previous ~40px.
     Constraint: the COLLAPSED rows, their dividers, and the title positions
     must not move. So the 14px reclaimed from the headrow's bottom padding is
     re-parented onto the row as bottom padding — the title→divider distance
     stays a constant 28px (14 above the panel + 14 below it) whether open or
     closed, so no row, divider, or title shifts and the 82px heading gap and
     the map are untouched. Applied once at the panel level, governing all
     seven regions. */
  .ah-region-row {
    /* Compensation: the 14px removed from .ah-region-headrow's bottom padding
       is restored here, BELOW the panel, so the collapsed row height (and the
       divider) is pixel-identical to before. */
    padding-bottom: var(--space-heading-body);
  }
  .ah-region-headrow {
    /* Title→panel gap = the standard. (Top padding unchanged, so the title
       row does not move and the 82px heading gap is preserved.) */
    padding-bottom: var(--space-heading-body);
  }
  .ah-region-places {
    /* Body paragraph sits directly under the 14px gap (no extra panel inset),
       and its bottom inset matches the token so below-panel space (14 here +
       14 on the row) stays the original 28px. */
    padding-top: 0;
    padding-bottom: var(--space-heading-body);
  }

  /* ----- Service Area → Affiliations gap: reduce the section's trailing
     reserved space so Affiliations (and the footer) rise to sit at the
     section-gap reference below the final accordion divider. -----
     The accordion is top-aligned with slack below it and the section height
     is driven by the (transform-raised) map, so the un-reduced trailing space
     left a ~347px gap with the tallest panel open — far larger than the
     134.5px --section-gap reference. A negative bottom margin pulls the whole
     Affiliations unit up (its internal layout is untouched; it moves as one).
     The map is NOT moved or clipped: Affiliations' background is opaque and
     paints over the section, so it may not rise past the map's lowest VISIBLE
     point (the white Frontenac–Kingston region polygon). Pulling the full
     reference distance would put the Affiliations background ~13px ABOVE that
     point, covering the map's southern tip; so the reduction is capped to keep
     a positive ~24px clearance between the map's lowest visible point and the
     top of the Affiliations background. The resulting open-state gap (~172px)
     is the closest map-safe value to the reference. Because the section height
     (reservation/map) is unchanged and this margin is static, Affiliations and
     everything below hold position in every accordion state. Desktop only —
     below 1024px the columns stack and the slack does not exist. */
  .ah-map-section {
    margin-bottom: -175px;
    /* Prescott & Russell (last row) reveal extends into the 175px overlap zone
       where the following section's opaque background would paint over it.
       z-index: 1 ensures the map section paints above the overlap. Both
       sections share var(--color-background) so there is no visual change
       in the empty zone — only the reveal text becomes correctly visible. */
    z-index: 1;
  }
}

/* ================================================================
   HOMEPAGE — SERVICES SECTION
   Sits directly above the Service Area section. Heading treatment is
   identical to .ah-map-head__title (Tid Display, 500, 100px). The
   info block is height-locked to its tallest state (Interiors, four
   items) so the image row never shifts when content swaps. Desktop
   pass only — mobile is intentionally deferred.
   ================================================================ */
.ah-services {
  margin-top: var(--space-hero-buffer); /* 120px — section rhythm */
}
.ah-services__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--hero-display-size); /* 100px */
  line-height: 1.05;
  letter-spacing: -0.005em;
  color: var(--color-ink);
  margin: 0;
  /* 82px from the "Services" heading baseline (its glyph bottom — no
     descenders) to the TOP of the editorial rule. */
  padding: 0 0 61.3px;
}
/* The info block: an editorial vertical rule at the 24px gutter with the
   category title + service list set to its right — the same treatment as
   the homepage standfirst paragraph (.ah-prose--news): a 1px #090401 rule
   with the text inset 24px from it. The rule's height is fixed to the
   tallest state (the four-item Interiors list) so it never changes when
   states swap, and the title's column is fixed-width so the list's left
   edge holds a constant x in every state. No frame, no fill, no padding box. */
.ah-services__info {
  position: relative;
  display: flex;
  align-items: flex-start;
  height: 102.4px; /* reserved = four-item list box (4 × 25.6) */
  /* Title sits flush at the 24px gutter (no indent); the rule now lives
     between the title and the list. */
}
/* The editorial rule — a real 1px element BETWEEN the title and the list
   (absolutely positioned, out of flow so it never shifts the text). Same
   1px weight and ink as the homepage standfirst rule. Its x is fixed: the
   widest title "05. Consultancy" @24px (144.24) + the 24px paragraph
   rule-to-text gap. Height spans the block's reserved (four-item) height,
   fixed across states. */
.ah-services__rule {
  position: absolute;
  left: 168.24px; /* 144.24 widest title + 24px gap */
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--color-ink);
}
.ah-services__cat {
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 400;
  font-size: 24px;
  line-height: 1;
  letter-spacing: -0.005em;
  color: var(--color-ink);
  /* Fixed column = widest title (144.24) + 24px gap + 24px gap, so the rule
     is centred between the widest title and the list and the list's left
     edge holds a constant x in every state. margin-top drops the title so
     its cap aligns with the list cap. */
  flex: 0 0 192.24px;
  margin: 5px 0 0;
  white-space: nowrap;
}
.ah-services__list {
  font-family: var(--font-body);
  font-style: normal;
  font-size: 16px;
  line-height: 1.6;
  color: var(--color-ink);
  list-style: none;
  flex: 0 0 auto;
  margin: 0;
  padding: 0;
}
.ah-services__list li {
  margin: 0;
  font-weight: 400;
}
.ah-services__row {
  margin-top: 82px; /* info block → image labels */
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 48px;
}
.ah-services__cell {
  margin: 0;
  display: flex;
  flex-direction: column;
}
.ah-services__label {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--color-ink);
  margin: 0 0 16px; /* 16px label → image */
}
.ah-services__plate {
  aspect-ratio: 3 / 4;
  cursor: pointer;
}
/* Instant greyscale / colour swap — no transition, per the house rule. */
.ah-services__plate[data-colour="false"] {
  filter: grayscale(1);
}
.ah-services__plate[data-colour="true"] {
  filter: none;
}
