/* ==========================================================================
   NEMA X — SHARED SYSTEM CSS
   Reset, base, motion, and every component reused across Home / Archive /
   Project Detail. Requires tokens.css loaded first.
   Source: Master Specification §1–2.
   ========================================================================== */

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
html{scroll-behavior:smooth;}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important;}
}
img,svg{display:block;max-width:100%;}
a{color:inherit;text-decoration:none;}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer;}
ul,ol{list-style:none;}

body{
  background:var(--paper); color:var(--ink); font-family:var(--f-body);
  font-size:16px; line-height:1.5; -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
/* Same off-canvas clip technique as .screen-reader-text (1x1px + clip),
   not a large negative offset: position:absolute with a huge left/right
   value escapes any ancestor's overflow:hidden (it resolves against the
   viewport, not body), so it was quietly inflating documentElement's
   scrollWidth in both languages — RTL's flipped inset-inline-start just
   moved the escaped box to the other edge and made it visible as real
   horizontal overflow. The clip-rect technique never escapes at all. */
.skip-link{ position:absolute!important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; z-index:9999; background:var(--ink); color:var(--paper); font-family:var(--f-mono); font-size:13px; }
.skip-link:focus{ width:auto; height:auto; margin:0; overflow:visible; clip:auto; white-space:normal; position:absolute!important; inset-inline-start:var(--edge); top:var(--edge); padding:12px 20px; }
/* Standard WP visually-hidden pattern — content that must exist for
   assistive tech but never occupies visual layout space. */
.screen-reader-text{ position:absolute!important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
:focus-visible{ outline:2px solid var(--stamp); outline-offset:3px; }
.container{ max-width:var(--max); margin-inline:auto; padding-inline:var(--edge); }
.dark{ background:var(--ink); color:var(--paper); }

/* signature transition — "the Plate turns the page" — Master Spec §5 */
@view-transition{ navigation: auto; }
::view-transition-group(*){ animation-duration: var(--i4); animation-timing-function: var(--ease-instrument); }
::view-transition-old(root), ::view-transition-new(root){ animation-duration: var(--i3); animation-timing-function: var(--ease-instrument); }

.eyebrow{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-wide); text-transform:uppercase; color:var(--ink-soft); display:flex; align-items:center; gap:10px; }
.dark .eyebrow{ color:var(--on-dark-soft); }
.eyebrow::before{ content:""; width:20px; height:1px; background:currentColor; }

.reveal{ opacity:0; transform:translateY(10px); transition:opacity var(--i4) var(--ease-instrument), transform var(--i4) var(--ease-instrument); }
.reveal.is-visible{ opacity:1; transform:none; }
.reveal--fade{ transform:none; transition:opacity var(--i5) var(--ease-instrument); }
.reveal--fade.is-visible{ transform:none; }
@media (prefers-reduced-motion:reduce){ .reveal,.reveal--fade{ opacity:1; transform:none; } }

/* ============================== NAV — HEADER SYSTEM ==============================
   An architectural overlay, not a UI trend: no blur, no drop shadow. Every
   state is a pure function of two continuous, JS-computed custom properties
   — --nav-solid (0=over the Hero, 1=solid content-area) and --nav-progress /
   --nav-logo-progress (0→1 across the first Transition Distance px of
   scroll) — so background, height, colour, border and the logo crossfade
   all move together and reverse cleanly on scroll-up. Every default below
   reproduces the exact numbers the original, approved Header used
   (92/72px heights, rgba(237,234,227,.88) ≡ --paper @ 88%, 160px
   transition, 22px item gap, 11px/.08em type) — a fresh install with
   nothing configured at NEMA X → Header renders identically to before.
   ========================================================================== */
.site-nav{
  --nav-solid:0; --nav-scale:1; --nav-progress:0; --nav-logo-progress:0; --nav-logo-contrast:1;
  --nav-height-mix:var(--nav-solid,0); --nav-bg-mix:var(--nav-solid,0);
  --nav-text-color:var(--nav-color-scroll,#4A4842);
  position:fixed; top:0; left:0; right:0; z-index:1000;
  height:calc(var(--nav-height-hero,92px) + (var(--nav-height-scroll,72px) - var(--nav-height-hero,92px)) * var(--nav-height-mix));
  transition:height var(--i3) var(--ease-instrument);
}
.site-nav[data-sticky="0"]{ position:absolute; }
.site-nav[data-compact="0"]{ --nav-height-mix:0; }
.site-nav[data-transparent-bg="0"]{ --nav-bg-mix:1; }
.site-nav[data-dynamic-contrast="1"]{ --nav-text-color:color-mix(in srgb, var(--nav-color-hero,#4A4842) calc((1 - var(--nav-solid,0)) * 100%), var(--nav-color-scroll,#4A4842) calc(var(--nav-solid,0) * 100%)); }

.nav-bg{ position:absolute; inset:0; z-index:-1; pointer-events:none; opacity:calc(var(--nav-bg-opacity,.88) * var(--nav-bg-mix)); transition:background-color var(--i2) var(--ease-instrument); }
.site-nav[data-bg-style="cream"] .nav-bg{ background:var(--paper); }
.site-nav[data-bg-style="white"] .nav-bg{ background:#fff; }
.site-nav[data-bg-style="custom"] .nav-bg{ background:var(--nav-bg-color,var(--paper)); }
.site-nav[data-bg-style="transparent"] .nav-bg{ opacity:0; }

/* Hero-state dark, transparent fill — only rendered (navbar.php) when the
   page actually has a Hero band behind the Header. Exact opacity-formula
   complement of .nav-bg above, both driven by the one shared --nav-bg-mix,
   the same two-layer crossfade technique the Logo Full⇄Icon swap already
   uses (never a JS class toggle, so it reverses cleanly on scroll-up). */
.nav-bg-hero{ position:absolute; inset:0; z-index:-1; pointer-events:none; background:var(--nav-hero-bg-color,#0E0E0C); opacity:calc(var(--nav-hero-bg-opacity,.48) * (1 - var(--nav-bg-mix,0))); transition:background-color var(--i2) var(--ease-instrument); }

.nav-gradient{ position:absolute; inset:0; z-index:-1; pointer-events:none; height:var(--nav-gradient-height,26vh); opacity:var(--nav-gradient-opacity,.22); }
.nav-gradient--top-down{ background:linear-gradient(to bottom, var(--ink) 0%, transparent 100%); }
.nav-gradient--radial{ background:radial-gradient(ellipse at top, var(--ink) 0%, transparent 75%); }

/* One true divider, two states — same element, same 1px height, colour and
   opacity cross-fading together via the shared --nav-bg-mix (0 = Hero-state
   light hairline on dark, 1 = Scrolled-state dark hairline on light). On
   every non-Hero page --nav-bg-mix is permanently pinned to 1 (see
   [data-transparent-bg="0"] above), so this collapses back to exactly the
   old single-colour border with zero behaviour change there. */
.nav-border{
	position:absolute; left:0; right:0; bottom:0; height:1px; pointer-events:none;
	background:color-mix(in srgb, var(--nav-hero-border-color,var(--nav-border-color,var(--line))) calc((1 - var(--nav-bg-mix,1)) * 100%), var(--nav-border-color,var(--line)) calc(var(--nav-bg-mix,1) * 100%));
	opacity:calc((var(--nav-hero-border-opacity,1) * (1 - var(--nav-bg-mix,1))) + (var(--nav-border-opacity,1) * var(--nav-bg-mix,1)));
	transition:background-color var(--i2) var(--ease-instrument);
}
.nav-top-separator{ position:absolute; left:var(--edge); right:var(--edge); bottom:0; height:1px; background:var(--stamp); pointer-events:none; opacity:calc(var(--nav-progress,0) * (1 - var(--nav-bg-mix,0))); }

.nav-inner{ position:relative; height:100%; width:100%; padding-inline:var(--edge); display:flex; justify-content:space-between; align-items:center; gap:24px; }
.site-nav[data-width="contained"] .nav-inner{ max-width:var(--nav-container-w,1560px); margin-inline:auto; }
/* Grid alignment (Header ⇄ Hero) — front page only. The Hero's own
   technical text (.arrival-mark) and rail sit flush against the raw
   viewport edge (left:var(--edge), rail right:var(--rail-edge)), not inside
   a centered max-width box — so on the front page the Header's inner
   container must do the same, reusing the identical tokens, rather than
   the "contained" centered box used on Archive/Project/Contact. */
.site-nav[data-front="1"] .nav-inner{ padding-right:var(--rail-edge, 26px); }
.site-nav[data-front="1"][data-width="contained"] .nav-inner{ max-width:none; margin-inline:0; }

/* Logo mount: wordmark today, native WP custom-logo the moment one is
   uploaded (Customize → Site Identity) — both share this one scroll-
   compact behavior, direct-bound to scroll like Rail's own fill/label
   (Master Spec §1.4's sanctioned exception for scroll-linked motion),
   smoothed by the same short linear transition the Rail label already
   uses rather than a new easing curve. */
.nav-mark{ flex-shrink:0; transform-origin:left center; transform:scale(var(--nav-scale, 1)); transition:transform var(--i1) linear; }
/* A quiet navigation identity mark, not a second Hero logo — technical
   mono/uppercase/wide-tracking, the same language every small structural
   label sitewide already uses (eyebrows, coordinates, section numbers).
   Deliberately closer in visual weight to the "=" menu trigger beside it
   than to the Hero's own large serif/animated centre branding. */
.nav-wordmark{
  display:block; font-family:var(--f-mono); font-weight:500; font-size:13px;
  letter-spacing:.22em; text-transform:uppercase; color:var(--nav-text-color);
  white-space:nowrap;
  /* 1 at Scroll, ~.88 over the Hero — a restrained dimming on top of the
     colour cross-fade above, never touched on non-Hero pages since
     --nav-bg-mix is pinned to 1 there. */
  opacity:calc(.88 + (.12 * var(--nav-bg-mix,1)));
  transition:color var(--i2) var(--ease-instrument), opacity var(--i2) var(--ease-instrument);
}
.nav-wordmark:hover, .nav-wordmark:focus-visible{ opacity:1; }
.nav-wordmark-year{ opacity:.6; font-weight:400; }
/* Centre discipline line — "B — Editorial" Header layout. Absolutely
   centred against the full bar so it stays visually centred regardless of
   how wide the wordmark or right-hand controls are; hidden on mobile. */
.nav-center{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-wide,.12em); text-transform:uppercase;
  color:var(--nav-text-color); white-space:nowrap; pointer-events:none;
  opacity:calc(.88 + (.12 * var(--nav-bg-mix,1)));
}
@media (max-width:639px){ .nav-center{ display:none; } .nav-wordmark-year{ display:none; } }
.nav-mark .custom-logo-link{ display:block; }
.nav-mark img.custom-logo{ display:block; height:40px; width:auto; max-width:200px; }

/* Full Logo ⇄ Compact Icon (--nav-logo-progress) crossed with Light ⇄ Dark
   (--nav-logo-contrast) — two independent, continuous, reversible axes,
   never a JS class toggle, so nothing ever "snaps". A Light image only
   ever exists in the DOM at all when Context-Aware Logo actually needs it
   (see navbar.php) — the opacity formulas below are safe either way. */
.nav-logo-stack{ position:relative; display:block; height:var(--logo-max-h,40px); }
.nav-logo-full, .nav-logo-icon{ position:absolute; top:0; left:0; height:100%; width:auto; max-width:var(--logo-w-desktop,160px); transition:opacity var(--i2) var(--ease-instrument); }
@media (max-width:639px){ .nav-logo-full, .nav-logo-icon{ max-width:var(--logo-w-mobile,120px); } }
.nav-logo-full.nav-logo-dark{ opacity:calc((1 - var(--nav-logo-progress,0)) * var(--nav-logo-contrast,1)); }
.nav-logo-full.nav-logo-light{ opacity:calc((1 - var(--nav-logo-progress,0)) * (1 - var(--nav-logo-contrast,1))); }
.nav-logo-icon.nav-logo-dark{ opacity:calc(var(--nav-logo-progress,0) * var(--nav-logo-contrast,1)); }
.nav-logo-icon.nav-logo-light{ opacity:calc(var(--nav-logo-progress,0) * (1 - var(--nav-logo-contrast,1))); }
/* No real Light asset uploaded (NEMA X → Header) — stand the same Dark
   asset in for the Light slot, colour-flipped only, never redrawn. Bypassed
   automatically the moment a real Light asset exists (navbar.php). */
.nav-logo--synthesized-light{ filter:invert(1); }
@media (prefers-reduced-motion:reduce){ .nav-logo-full, .nav-logo-icon{ transition:none; } }

.nav-index{ display:none; gap:calc(var(--nav-menu-item-spacing,22px) - (6px * var(--nav-progress,0))); }
@media (min-width:640px){ .nav-index{ display:flex; } }
.nav-index a{ font-family:var(--f-mono); font-size:clamp(var(--nav-menu-font-mobile,11px), 1.4vw, var(--nav-menu-font-desktop,11px)); letter-spacing:var(--nav-menu-letterspacing,.08em); text-transform:uppercase; color:var(--nav-text-color); padding-bottom:2px; transition:color var(--i2) var(--ease-instrument), opacity var(--i2) var(--ease-instrument); }

.nav-index[data-hover="underline"] a{ border-bottom:1px solid transparent; }
.nav-index[data-hover="underline"][data-underline="dashed"] a{ border-bottom-style:dashed; }
.nav-index[data-hover="underline"] a:hover, .nav-index[data-hover="underline"] a:focus-visible, .nav-index[data-hover="underline"] a[aria-current="page"]{ border-color:var(--nav-hover-color,var(--stamp)); }
.nav-index[data-hover="accent"] a:hover, .nav-index[data-hover="accent"] a:focus-visible, .nav-index[data-hover="accent"] a[aria-current="page"]{ color:var(--nav-hover-color,var(--stamp)); }
.nav-index[data-hover="line"] a{ position:relative; }
.nav-index[data-hover="line"] a::after{ content:""; position:absolute; left:0; right:0; bottom:0; height:1px; background:var(--nav-hover-color,var(--stamp)); transform:scaleX(0); transform-origin:left; transition:transform var(--i2) var(--ease-instrument); }
.nav-index[data-hover="line"] a:hover::after, .nav-index[data-hover="line"] a:focus-visible::after, .nav-index[data-hover="line"] a[aria-current="page"]::after{ transform:scaleX(1); }
.nav-index[data-hover="opacity"]:hover a{ opacity:.55; }
.nav-index[data-hover="opacity"]:hover a:hover, .nav-index[data-hover="opacity"] a:focus-visible, .nav-index[data-hover="opacity"] a[aria-current="page"]{ opacity:1; }

.nav-toggle{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-label); text-transform:uppercase; display:flex; align-items:center; gap:10px; flex-shrink:0; color:var(--nav-text-color); }
@media (min-width:640px){ .nav-toggle{ display:none; } }
.nav-toggle .bars{ display:flex; flex-direction:column; gap:4px; }
.nav-toggle .bars span{ width:18px; height:1px; background:currentColor; }

/* ---- Language switcher — grouped with whichever menu trigger is active
   (Architectural or Legacy) so it reads as one right-hand control cluster,
   never a separate widget. Same mono label, same --nav-text-color the
   trigger/nav-index already use — Hero-state and scrolled-state colour
   come along for free, no dedicated switcher palette (Multilingual Master
   Spec §7/§8). Deliberately just a link, no dropdown/flag/pill: there are
   only ever two states, "the other language," so a single toggle covers
   every case the brief allows. ---- */
.nav-controls{ display:flex; align-items:center; gap:16px; flex-shrink:0; }
.nav-lang-switch{
  font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-label,.08em); text-transform:uppercase;
  color:var(--nav-text-color); opacity:.72; flex-shrink:0;
  transition:opacity var(--i2) var(--ease-instrument), color var(--i2) var(--ease-instrument);
}
.nav-lang-switch:hover, .nav-lang-switch:focus-visible{ opacity:1; }

.mobile-menu{ position:fixed; inset:0; background:var(--ink); color:var(--paper); z-index:1999; display:flex; flex-direction:column; justify-content:center; padding:var(--edge); transform:translateY(-100%); transition:transform var(--i4) var(--ease-instrument); }
.mobile-menu.is-open{ transform:translateY(0); }
.mobile-menu a{ font-family:var(--f-display); font-style:italic; font-weight:400; font-size:clamp(30px,9vw,52px); padding:12px 0; border-bottom:1px solid var(--line-dark); display:flex; justify-content:space-between; }
.mobile-menu a span{ font-family:var(--f-mono); font-style:normal; font-size:13px; color:var(--accent-on-dark); align-self:center; }
.mobile-close{ position:absolute; top:26px; right:var(--edge); font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-label); text-transform:uppercase; }
.mobile-close-icon{ --icon-size:12px; margin-left:6px; }

/* ==========================================================================
   MENU EXPERIENCE — Architectural Index (NEMA X → Header → Menu Style).
   Entirely inert on Legacy pages (none of these selectors exist there —
   .nav-toggle/.nav-index/.mobile-menu above are untouched). One shared
   trigger replaces both the always-visible desktop links and the mobile
   hamburger; one shared full-viewport panel replaces the old mobile-only
   overlay on desktop and mobile alike.
   ========================================================================== */

/* ---- Trigger — "MENU" label + a thin rule underneath (no hamburger glyph),
   "B — Editorial" Header layout. Still meets the 44px minimum tap target
   (Master accessibility baseline used everywhere else in this theme). ---- */
.menu-trigger{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px;
  min-width:44px; min-height:44px; padding:8px 2px; flex-shrink:0;
  color:var(--nav-text-color); background:none; border:0; cursor:pointer;
}
.menu-trigger-label{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-label,.08em); text-transform:uppercase; }
.menu-trigger-rule{ width:26px; height:1px; background:currentColor; transition:width var(--i2) var(--ease-instrument); }
.menu-trigger:hover .menu-trigger-rule, .menu-trigger:focus-visible .menu-trigger-rule{ width:36px; }
.mt-icon{ position:relative; width:22px; height:14px; flex-shrink:0; }
.mt-line{
  position:absolute; left:0; right:0; top:0; height:1px; background:currentColor;
  transition:top var(--i2) var(--ease-instrument), transform var(--i2) var(--ease-instrument);
}
.mt-line--1{ top:0; }
.mt-line--2{ top:calc(100% - 1px); }
/* Corner-tick motif reused from the Plate component (.plate-tick) — the
   same "registration mark" language, not a new decorative element. Zero
   height by default: invisible until the NX open state grows it in. */
.mt-tick{
  position:absolute; top:50%; transform:translateY(-50%); width:1px; height:0;
  background:currentColor; opacity:0;
  transition:height var(--i2) var(--ease-instrument), opacity var(--i2) var(--ease-instrument);
}
.mt-tick--l{ left:-6px; }
.mt-tick--r{ right:-6px; }

.menu-trigger[aria-expanded="true"] .mt-line--1{ top:50%; transform:translateY(-50%) rotate(45deg); }
.menu-trigger[aria-expanded="true"] .mt-line--2{ top:50%; transform:translateY(-50%) rotate(-45deg); }
.menu-trigger[aria-expanded="true"][data-mark="nx"] .mt-tick{ height:14px; opacity:.85; }
@media (hover:hover){ .menu-trigger:hover{ opacity:.7; } }
.menu-trigger:focus-visible{ outline:1px solid currentColor; outline-offset:4px; }
@media (prefers-reduced-motion:reduce){ .mt-line, .mt-tick{ transition:none; } }

.nav-index--noscript{ display:flex !important; } /* only ever rendered inside <noscript> */

/* ---- Panel — full-viewport architectural index. Closed by default via
   the `hidden` attribute (a closed nav drawer being hidden is correct,
   expected UX — not the "critical content invisible" failure this theme
   has fixed twice before). What that fix DOES apply to here: once OPEN,
   every link/label below is visible by default; only .js-anim (added by
   system.js, and only once it can actually run the open/close JS at all)
   opts into the stagger-in version. Reduced motion, or the admin's own
   Menu Animation = Off, simply never adds .js-anim — content still opens
   fully visible, just without the stagger. */
.arch-menu{
  position:fixed; inset:0; z-index:1500; background:var(--ink); color:var(--paper);
  overflow-y:auto; -webkit-overflow-scrolling:touch;
  opacity:0; transition:opacity var(--i4) var(--ease-instrument);
}
.arch-menu.is-open{ opacity:1; }
@media (prefers-reduced-motion:reduce){ .arch-menu{ transition:none; } }

/* Seamless blend with the header strip the panel opens under — cosmetic
   only (menu-is-open is added by JS); the panel's own content and the
   trigger itself never depend on this for visibility or function. Only
   meaningful in Fullscreen presentation (Floating leaves the header's own
   look alone, since it's no longer the same surface as the panel). */
.site-nav[data-menu-style="architectural"] .nav-bg{ transition:opacity var(--i3) var(--ease-instrument); }
body.menu-is-open .site-nav .nav-bg,
body.menu-is-open .site-nav .nav-bg-hero{ opacity:0; }
body.menu-is-open .site-nav{ --nav-text-color:var(--paper); }

/* ---- Menu Presentation = Floating Panel ----
   Fullscreen (default) is completely untouched above: .arch-menu-panel has
   no width/height/position rules there, so it simply fills .arch-menu edge
   to edge exactly as the old markup did. Floating turns .arch-menu itself
   into a dimmed, click-to-close backdrop and .arch-menu-panel into the
   large floating sheet — sharp corners, no blur/gradient on the sheet
   itself, only a restrained shadow to separate it from the page. */
.arch-menu[data-presentation="floating"]{
  display:flex; align-items:center; justify-content:center;
  background:rgba(10,10,10,.55);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  padding:32px; overflow:hidden;
}
.arch-menu-panel{ min-height:100%; width:100%; }
.arch-menu[data-presentation="floating"] .arch-menu-panel{
  position:relative;
  width:min(76vw, 1360px); height:min(80vh, 900px); min-height:0;
  background:var(--ink); border:1px solid var(--line-dark);
  box-shadow:0 20px 50px rgba(0,0,0,.3);
  overflow-y:auto; -webkit-overflow-scrolling:touch;
  opacity:0; transform:translateY(14px) scale(.988);
  transition:opacity var(--i3) var(--ease-instrument), transform var(--i3) var(--ease-instrument);
}
.arch-menu[data-presentation="floating"].is-open .arch-menu-panel{ opacity:1; transform:none; }
.arch-menu[data-presentation="floating"] .arch-menu-inner{ padding:56px var(--edge) 48px; }
@media (prefers-reduced-motion:reduce){
  .arch-menu[data-presentation="floating"] .arch-menu-panel{ transition:none; }
}
@media (max-width:768px){
  .arch-menu[data-presentation="floating"]{ padding:16px; }
  .arch-menu[data-presentation="floating"] .arch-menu-panel{ width:94vw; height:92vh; }
}

.arch-menu-inner{ max-width:var(--max); margin-inline:auto; min-height:100%; padding:calc(var(--nav-height-hero,92px) + 48px) var(--edge) 64px; display:flex; flex-direction:column; gap:36px; }
.arch-menu-wordmark{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--on-dark-soft); }

.arch-menu-nav{ display:flex; flex-direction:column; }
.ami{ position:relative; display:grid; grid-template-columns:auto 1fr; column-gap:20px; align-items:baseline; padding:20px 0; border-bottom:1px solid var(--line-dark); text-decoration:none; color:var(--paper); }
.ami-n{ font-family:var(--f-mono); font-size:12px; color:var(--on-dark-soft); letter-spacing:var(--ls-tight); align-self:start; padding-top:.6em; transition:color var(--i2) var(--ease-instrument); }
.ami-label{ grid-column:2; display:block; font-family:var(--f-body); font-weight:500; font-size:clamp(30px,5.4vw,54px); line-height:1.05; transition:transform var(--i2) var(--ease-instrument); }
.ami-desc{ grid-column:2; display:block; font-family:var(--f-mono); font-size:12px; color:var(--on-dark-soft); margin-top:8px; letter-spacing:var(--ls-tight); transition:color var(--i2) var(--ease-instrument); }
.ami::after{ content:""; position:absolute; left:0; right:0; bottom:-1px; height:1px; width:0; background:var(--stamp-on-dark); transition:width var(--i2) var(--ease-instrument); }
.ami[aria-current="page"]::after{ width:100%; }
.ami[aria-current="page"] .ami-n{ color:var(--stamp-on-dark); }
@media (hover:hover){
  .ami:hover::after, .ami:focus-visible::after{ width:100%; }
  .ami:hover .ami-n, .ami:focus-visible .ami-n{ color:var(--stamp-on-dark); }
  .ami:hover .ami-label, .ami:focus-visible .ami-label{ transform:translateX(4px); }
  .ami:hover .ami-desc, .ami:focus-visible .ami-desc{ color:var(--on-dark); }
}
.ami:focus-visible{ outline:1px solid var(--stamp-on-dark); outline-offset:6px; }

.arch-menu-aside{ display:flex; flex-direction:column; gap:24px; padding-top:4px; }
.ama-coords{ display:flex; flex-direction:column; gap:2px; font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-tight); color:var(--on-dark-soft); }
.ama-discipline{ font-family:var(--f-display); font-style:italic; font-weight:360; font-size:clamp(15px,1.6vw,17px); color:var(--paper); max-width:32ch; }
.ama-links{ display:flex; flex-direction:column; gap:8px; font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-tight); text-transform:uppercase; }
.ama-links a{ color:var(--paper); text-decoration:none; transition:color var(--i2) var(--ease-instrument); }
.ama-links a:hover, .ama-links a:focus-visible{ color:var(--stamp-on-dark); }
/* View Catalogue — same row/typography as Instagram+email above (still a
   plain .ama-links a, so it inherits their color/hover rule for free);
   align-self:flex-start keeps its own box down to the text's actual width
   so the hover underline below hugs the label instead of the full aside
   column, and the extra margin-top (on top of .ama-links' own 8px gap)
   is the "slightly more breathing room" the brief asked for. Text itself
   never moves — only the thin rule grows, same restrained language as
   the main nav rows' own .ami::after. */
.ama-catalogue{ position:relative; align-self:flex-start; margin-top:8px; }
.ama-catalogue::after{
  content:""; position:absolute; left:0; right:0; bottom:-3px; height:1px; width:0;
  background:var(--stamp-on-dark); transition:width var(--i2) var(--ease-instrument);
}
.ama-catalogue:hover::after, .ama-catalogue:focus-visible::after{ width:100%; }
.ama-catalogue-arrow{ display:inline-block; }
.ama-catalogue--disabled{ opacity:.45; cursor:default; }
.ama-catalogue--disabled::after{ display:none; }

@media (min-width:900px){
  .arch-menu-inner{ display:grid; grid-template-columns:1.6fr .9fr; column-gap:64px; align-content:start; }
  .arch-menu-wordmark{ grid-column:1 / -1; }
  .arch-menu-aside{ padding-top:10px; }
}

/* Stagger-in — opt-in only, see the comment on .arch-menu above. */
.arch-menu.js-anim .ami, .arch-menu.js-anim .arch-menu-aside > *{
  opacity:0; transform:translateY(10px);
  transition:opacity var(--i3) var(--ease-instrument), transform var(--i3) var(--ease-instrument);
}
.arch-menu.js-anim.is-open .ami, .arch-menu.js-anim.is-open .arch-menu-aside > *{ opacity:1; transform:none; }
.arch-menu.js-anim .ami:nth-child(1){ transition-delay:40ms; }
.arch-menu.js-anim .ami:nth-child(2){ transition-delay:80ms; }
.arch-menu.js-anim .ami:nth-child(3){ transition-delay:120ms; }
.arch-menu.js-anim .ami:nth-child(4){ transition-delay:160ms; }
.arch-menu.js-anim .arch-menu-aside > *{ transition-delay:200ms; }

.topline{ position:fixed; top:0; left:0; right:0; height:2px; background:var(--line); z-index:999; }
.topline-fill{ height:100%; width:0%; background:var(--stamp); }
@media (min-width:1180px){ .topline{ display:none; } }

.rail{
  display:none;
  --rail-line:var(--line); --rail-fill:var(--stamp); --rail-tick:var(--ink-soft); --rail-label:var(--ink-soft);
}
/* Rail → Hero — the rail's resting palette reads fine over every light
   section already; only over the (potentially photographic, potentially
   dark) Hero does it need its own ivory/terracotta pass, same accent
   either way. Toggled by system.js's existing section-tracking geometry —
   no new observer, no redesign of the rail itself. */
.rail.rail--on-hero{
  --rail-line:var(--ivory-warm); --rail-fill:var(--stamp-on-dark);
  --rail-tick:var(--ivory-warm); --rail-label:var(--ivory-warm);
  transition:color var(--i3) var(--ease-instrument);
}
@media (min-width:1180px){
  .rail{ display:block; position:fixed; right:var(--rail-edge, 26px); top:0; bottom:0; width:20px; z-index:900; pointer-events:none; }
  .rail-track{ position:absolute; left:50%; top:120px; bottom:120px; width:1px; background:var(--rail-line); transform:translateX(-50%); transition:background var(--i3) var(--ease-instrument); }
  .rail-fill{ position:absolute; left:50%; top:120px; width:1px; background:var(--rail-fill); transform:translateX(-50%); height:0%; transition:background var(--i3) var(--ease-instrument); }
  .rail-tick{ position:absolute; left:50%; width:8px; height:1px; background:var(--rail-tick); transform:translate(-50%,0); opacity:.5; transition:background var(--i3) var(--ease-instrument); }
  .rail-tick.is-passed{ background:var(--rail-fill); opacity:1; }
  .rail-label{ position:absolute; left:14px; writing-mode:vertical-rl; font-family:var(--f-mono); font-size:10px; letter-spacing:var(--ls-wide); text-transform:uppercase; color:var(--rail-label); white-space:nowrap; transition:top var(--i1) linear, color var(--i3) var(--ease-instrument); }
}

/* ============================== PLATE ==============================
   data-ar sets the frame shape (the only four permitted anywhere).
   .on-dark/.on-light sets tone. .ticks-quiet = two corner ticks not four.
   ==================================================================== */
.plate{ position:relative; display:block; width:100%; border:1px solid; overflow:hidden; }
.plate.on-dark{ border-color:var(--line-dark); }
.plate.on-light{ border-color:var(--line); }
.plate[data-ar="portrait"]{ aspect-ratio:4/5; }
.plate[data-ar="cinema"]{ aspect-ratio:21/9; }
.plate[data-ar="square"]{ aspect-ratio:5/4; }
.plate[data-ar="landscape"]{ aspect-ratio:3/2; }
/* archive-feature / archive-standard — Archive Project Card system only
   (assets/css/pages/archive.css's .card--feature/.card--standard); the
   fourth target (Portrait) reuses the "portrait" ratio above exactly,
   since 4:5 was already the site's portrait shape. */
.plate[data-ar="archive-feature"]{ aspect-ratio:16/9; }
.plate[data-ar="archive-standard"]{ aspect-ratio:4/3; }
/* natural — Single Project redesign only (Cover + Visual Story): the
   frame takes its height from the image itself instead of snapping to one
   of the four fixed shapes above, so architecture is never cropped to fit
   a box it wasn't composed for. */
.plate[data-ar="natural"]{ aspect-ratio:auto; }
.plate[data-ar="natural"] img{ position:static; display:block; width:100%; height:auto; object-fit:initial; }
.plate-fill{ position:absolute; inset:0; background-image:repeating-linear-gradient(45deg, rgba(255,255,255,.045) 0 1px, transparent 1px 15px); }
.plate.on-light .plate-fill{ background-image:repeating-linear-gradient(45deg, rgba(28,27,23,.06) 0 1px, transparent 1px 15px); }
.plate img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.plate-sketch{ position:absolute; inset:14%; width:auto; height:auto; opacity:.15; }
.plate.on-dark .plate-sketch{ color:var(--paper); }
.plate.on-light .plate-sketch{ color:var(--ink); }
.plate-tick{ position:absolute; width:14px; height:14px; opacity:.55; }
.plate-tick::before,.plate-tick::after{ content:""; position:absolute; background:currentColor; }
.plate-tick::before{ width:14px; height:1px; top:0; left:0; }
.plate-tick::after{ width:1px; height:14px; top:0; left:0; }
.pt-tl{ top:10px; left:10px; }
.pt-tr{ top:10px; right:10px; transform:scaleX(-1); }
.pt-bl{ bottom:10px; left:10px; transform:scaleY(-1); }
.pt-br{ bottom:10px; right:10px; transform:scale(-1,-1); }
@media (hover:hover){ .plate:hover .plate-tick{ transition:transform var(--i2) var(--ease-instrument); } }
.plate:hover .pt-tl{ transform:translate(2px,2px); }
.plate:hover .pt-tr{ transform:scaleX(-1) translate(2px,2px); }
.plate:hover .pt-bl{ transform:scaleY(-1) translate(2px,2px); }
.plate:hover .pt-br{ transform:scale(-1,-1) translate(2px,2px); }
.plate.ticks-quiet .pt-tr, .plate.ticks-quiet .pt-bl{ display:none; }
.plate-caption{ position:absolute; left:14px; bottom:14px; right:14px; display:flex; justify-content:space-between; gap:12px; font-family:var(--f-mono); font-size:10px; letter-spacing:var(--ls-tight); opacity:.7; z-index:1; }
.plate-center{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px; font-family:var(--f-mono); font-size:10px; letter-spacing:var(--ls-label); text-transform:uppercase; opacity:.5; text-align:center; }

/* ============================== STAMP ============================== */
/* --stamp-color, when set inline (Contact → Stamp), overrides the shared
   --stamp token for that one instance only — Rooms' own stamp
   (template-parts/home/archive.php) never sets it, so it keeps the
   token default exactly as before. */
.stamp{
  position:absolute; z-index:3; border:1.5px solid var(--stamp-color, var(--stamp)); padding:9px 15px; color:var(--stamp-color, var(--stamp));
  font-family:var(--f-mono); text-align:center; background:rgba(28,27,23,.02);
  transform:rotate(-8deg) translateY(-8px); opacity:0;
  transition:opacity var(--i3) var(--ease-contact), transform var(--i3) var(--ease-contact);
}
.stamp::before{ content:""; position:absolute; inset:4px; border:1px solid var(--stamp-color, var(--stamp)); pointer-events:none; }
.stamp.is-stamped{ transform:rotate(-8deg) translateY(0); opacity:.92; }
.stamp.on-dark, .stamp.on-dark::before{ border-color:var(--stamp-on-dark); color:var(--stamp-on-dark); }
.stamp .s1{ font-size:9px; letter-spacing:var(--ls-label); display:block; }
.stamp .s2{ font-size:12px; letter-spacing:var(--ls-tight); font-weight:700; display:block; margin-top:4px; }
@media (max-width:759px){
  .stamp{ position:static; display:inline-block; margin-top:18px; transform:rotate(0) translateY(0); opacity:0; }
  .stamp.is-stamped{ opacity:.92; }
}

/* ============================== INDEX ROW ============================== */
/* .index-row is a positioning wrapper only (no position of its own — its
   .ir-preview child relies on bubbling up to a shared positioned ancestor,
   see the Ledger block in assets/css/pages/home.css); .ir-link carries the
   actual row layout and is the one real navigation element (whole row,
   not just the name, is clickable). */
.index-row{ border-bottom:1px solid var(--line); transition:border-color var(--i3) var(--ease-instrument), opacity var(--i3) var(--ease-instrument); }
.index-row.is-active{ border-bottom-color:var(--stamp); }
.ir-link{ display:flex; align-items:baseline; gap:16px; padding:15px 0; color:inherit; text-decoration:none; }
.ir-mark{ font-family:var(--f-mono); font-size:11px; color:var(--stamp); width:20px; flex-shrink:0; }
.ir-name{ font-family:var(--f-display); font-weight:500; font-size:16px; flex:1; transition:color var(--i2) var(--ease-instrument); }
.index-row.is-active .ir-name{ color:var(--ink); }
.ir-tag{ font-family:var(--f-mono); font-size:10px; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--ink-soft); opacity:.7; border-left:1px solid var(--line); padding-left:8px; white-space:nowrap; }
.ir-meta{ font-family:var(--f-mono); font-size:11px; color:var(--ink-soft); white-space:nowrap; }
.ir-preview{ pointer-events:none; }

/* ============================== PROJECT CARD ==============================
   One Plate + title + meta — the Archive grid's only card component
   (template-parts/project-card.php). Its aspect ratio comes entirely from
   the Plate's own data-ar (archive-feature/archive-standard/portrait, set
   per nemax_archive_card_type()'s classification — see inc/template-tags.php
   and assets/css/pages/archive.css for the grid-span/column behavior);
   no card-type sizing rule lives here, only the title/meta typography
   every type shares equally.
   ==================================================================== */
.card{ display:block; }
.card-title{ font-family:var(--f-display); font-weight:500; font-size:18px; letter-spacing:var(--ls-head); margin-top:14px; line-height:1.2; transition:color var(--i2) var(--ease-instrument); }
.card:hover .card-title{ color:var(--stamp); }
.card-meta{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-tight); color:var(--ink-soft); margin-top:6px; }
.card--feature .card-title{ font-size:clamp(20px,1.6vw,24px); }
/* Grid settles in row by row rather than all at once. */
.a-grid .card:nth-child(4n+1){ transition-delay:0ms; }
.a-grid .card:nth-child(4n+2){ transition-delay:60ms; }
.a-grid .card:nth-child(4n+3){ transition-delay:120ms; }
.a-grid .card:nth-child(4n+4){ transition-delay:180ms; }

.interstitial{ text-align:center; padding:var(--pad-beat) var(--edge); }
.interstitial span{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-wide); text-transform:uppercase; color:var(--ink-soft); }
.dark .interstitial span{ color:var(--on-dark-soft); }

/* ============================== PLAQUE (cornerstone) ============================== */
.plaque{ position:relative; background:var(--paper); color:var(--ink); padding:26px 22px 24px; border:1px solid var(--line-dark); }
.plaque::before{ content:""; position:absolute; inset:5px; border:1px solid var(--line-dark); opacity:.5; pointer-events:none; }
.plaque-rivet{ position:absolute; width:3px; height:3px; border-radius:50%; background:var(--line-dark); opacity:.6; }
.rv-tl{ top:8px; left:8px; } .rv-tr{ top:8px; right:8px; } .rv-bl{ bottom:8px; left:8px; } .rv-br{ bottom:8px; right:8px; }
.plaque-num{ font-family:var(--f-mono); font-size:26px; color:var(--stamp); }
.plaque b{ display:block; font-size:13px; margin-top:10px; }
.plaque span:not(.plaque-rivet){ display:block; font-family:var(--f-mono); font-size:11px; color:var(--ink-soft); margin-top:6px; line-height:var(--lh-read); }

/* ============================== INDEX OF PRACTICE ==============================
   Replaces the old numeric plaques (Master Spec §3.6/§8) — a computed list,
   not a stat block. Reuses the plaque frame for visual consistency, but the
   content is the actual typologies/cities in use, not a claim about counts.
   ==================================================================== */
.practice-index{ display:grid; grid-template-columns:1fr; gap:16px 20px; margin-top:clamp(70px,10vw,110px); }
@media (min-width:640px){ .practice-index{ grid-template-columns:1fr 1fr; } }
.practice-index-group b{ display:block; font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-wide); text-transform:uppercase; color:var(--bronze-deep); margin-bottom:14px; }
.practice-index-group ul{ display:flex; flex-direction:column; gap:8px; }
.practice-index-group li{ font-family:var(--f-display); font-size:16px; color:var(--paper); border-bottom:1px solid var(--line-dark); padding-bottom:8px; }

/* ============================== REGISTER (FAQ) ==============================
   An architectural reveal, not an accordion. Hover draws a short accent
   tick and settles the question's type; opening flashes the item's top
   border and unfolds the answer (grid-template-rows, unchanged technique)
   with its own content staggered slightly behind — highlight, body, then
   Related Project arriving last. Register — Visual Options (NEMA X → FAQ)
   gate the --no-divider / --no-number / --no-animation modifiers below;
   Featured (per-question) gets a standing, not just on-open, accent.
   ========================================================================== */
.register{ margin-top:clamp(70px,10vw,110px); background:var(--paper-2); color:var(--ink); padding:clamp(36px,5vw,56px) clamp(24px,4vw,48px); max-width:900px; }
.register-label{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-wide); text-transform:uppercase; color:var(--bronze-deep); display:block; margin-bottom:12px; }
.register-intro{ font-family:var(--f-display); font-style:italic; font-size:15px; line-height:var(--lh-body); color:var(--ink-soft); max-width:52ch; margin-bottom:22px; font-variant-numeric:oldstyle-figures; }

.reg-item{ border-top:1px solid var(--line); transition:border-color var(--i3) var(--ease-instrument); }
.reg-item:last-child{ border-bottom:1px solid var(--line); }
.register--no-divider .reg-item{ transition:none; }
.reg-item.is-open{ border-top-color:var(--stamp); }
.register--no-divider .reg-item.is-open{ border-top-color:var(--line); }

.reg-q{ position:relative; width:100%; display:flex; gap:18px; align-items:center; padding:20px 0; text-align:left; }
/* Thin architectural line — a short accent tick, not a full-width
   underline, drawing in on hover as the one "line extends" cue. */
.reg-q::after{ content:""; position:absolute; left:0; bottom:0; height:1px; width:0; background:var(--stamp); transition:width var(--i3) var(--ease-instrument); }
.reg-item:hover .reg-q::after, .reg-item.is-open .reg-q::after{ width:48px; }

.reg-number{ font-family:var(--f-mono); font-size:12px; color:var(--stamp); width:22px; flex-shrink:0; opacity:0; transition:opacity var(--i3) var(--ease-instrument), color var(--i3) var(--ease-instrument); }
.reg-item:hover .reg-number{ opacity:.45; }
.reg-item.is-open .reg-number{ opacity:1; }
.register--no-number .reg-number{ display:none; }
.reg-item.is-featured .reg-number{ opacity:.7; }
.reg-item.is-featured.is-open .reg-number{ opacity:1; }

.reg-q-text{ font-family:var(--f-mono); font-size:12px; letter-spacing:var(--ls-tight); text-transform:uppercase; flex:1; transition:letter-spacing var(--i3) var(--ease-instrument), transform var(--i3) var(--ease-instrument); }
.reg-item:hover .reg-q-text, .reg-item.is-open .reg-q-text{ letter-spacing:calc(var(--ls-tight) + .03em); transform:translateX(3px); }
.reg-item.is-featured .reg-q-text{ color:var(--stamp); }

/* grid-template-rows 0fr→1fr — smoother than the old JS-measured
   max-height (no scrollHeight read, no snapping once surrounding content
   changes). .reg-a wraps a single .reg-a-inner child (never the answer's
   own <p> tags directly — a FAQ answer can be more than one paragraph via
   the_content's own wpautop, and grid-template-rows only sizes cleanly
   when there's exactly one grid child); that child needs min-height:0 for
   the row to actually collapse, since grid items default to min-height:auto. */
.reg-a{ display:grid; grid-template-rows:0fr; overflow:hidden; transition:grid-template-rows var(--i3) var(--ease-instrument); }
.reg-item.is-open .reg-a{ grid-template-rows:1fr; }
.reg-a-inner{ min-height:0; overflow:hidden; }
/* The row unfolds first; its own content settles in a beat behind —
   "paper unfolding," not a skew/scale trick. Disabled outright (instant)
   under reduced-motion or Register — Reveal animation off. */
.reg-highlight, .reg-a-body, .reg-related{ opacity:0; transition:opacity var(--i3) var(--ease-instrument); }
.reg-item.is-open .reg-highlight{ opacity:1; transition-delay:.08s; }
.reg-item.is-open .reg-a-body{ opacity:1; transition-delay:.14s; }
.reg-item.is-open .reg-related{ opacity:1; transition-delay:.22s; }
.register--no-animation .reg-a{ transition:none; }
.register--no-animation .reg-highlight, .register--no-animation .reg-a-body, .register--no-animation .reg-related{ transition:none; opacity:1; }

.reg-highlight{ font-family:var(--f-display); font-style:italic; font-weight:600; font-size:16px; line-height:var(--lh-body); color:var(--ink); padding:0 0 14px 40px; max-width:54ch; font-variant-numeric:oldstyle-figures; }
.reg-a-body p{ font-family:var(--f-display); font-style:italic; font-size:15px; line-height:var(--lh-body); color:var(--ink-soft); padding:0 0 22px 40px; max-width:56ch; font-variant-numeric:oldstyle-figures; }

.reg-related{ padding:0 0 22px 40px; display:flex; flex-direction:column; gap:8px; }
.reg-related-label{ font-family:var(--f-mono); font-size:10px; letter-spacing:var(--ls-wide); text-transform:uppercase; color:var(--bronze-deep); }
.reg-related-item{ display:flex; justify-content:space-between; align-items:baseline; gap:14px; border-bottom:1px solid var(--line); padding-bottom:8px; transition:border-color var(--i2) var(--ease-instrument); }
.reg-related-item:hover{ border-color:var(--stamp); }
.reg-related-title{ font-family:var(--f-body); font-size:14px; color:var(--ink); }
.reg-related-city{ font-family:var(--f-mono); font-size:11px; color:var(--ink-soft); margin-left:8px; }
.reg-related-view{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--stamp); white-space:nowrap; }

@media (max-width:639px){
  .reg-highlight, .reg-a-body p, .reg-related{ padding-left:22px; }
}
@media (prefers-reduced-motion:reduce){
  .reg-highlight, .reg-a-body, .reg-related{ transition:none; opacity:1; }
}

/* ============================== FORM CONTROLS ============================== */
.field{ margin-bottom:28px; }
.field label{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--ink-soft); display:block; margin-bottom:10px; }
.field input, .field textarea, .field select{
  width:100%; background:transparent; border:none; border-bottom:1px solid var(--line);
  font-family:var(--f-body); font-size:16px; padding:8px 0; color:var(--ink); transition:border-color var(--i2) var(--ease-instrument);
}
.field input:focus, .field textarea:focus, .field select:focus{ border-color:var(--stamp); outline:none; }

.chips{ display:flex; flex-wrap:wrap; gap:10px; }
.chip{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-tight); border:1px solid var(--line); padding:8px 16px; transition:border-color var(--i2) var(--ease-instrument), color var(--i2) var(--ease-instrument), background var(--i2) var(--ease-instrument); }
.chip[aria-pressed="true"]{ border-color:var(--stamp); color:var(--stamp); background:rgba(161,61,44,.06); }

.btn-mono{ font-family:var(--f-mono); font-size:12px; letter-spacing:var(--ls-label); text-transform:uppercase; border:1px solid var(--ink); padding:14px 28px; display:inline-block; transition:background var(--i2) var(--ease-instrument), color var(--i2) var(--ease-instrument); }
.btn-mono:hover{ background:var(--ink); color:var(--paper); }
.btn-mono:disabled{ opacity:.35; pointer-events:none; }
.link-mono{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-label); text-transform:uppercase; text-decoration:underline; text-underline-offset:3px; transition:opacity var(--i2) var(--ease-instrument); }
.link-mono:hover{ opacity:.6; }

/* ============================== COLOPHON ==============================
   NEMA X's closing architectural gesture, not leftover navigation — the
   only deliberately dark surface on the site. A real, uploaded logo
   (never a redrawn text mark) at two sizes, the studio's own rule/
   coordinates/scale-label language kept and refined, and one sequential
   entrance that reuses the sitewide .reveal/.reveal--fade observer
   already wired in system.js — each block just gets its own short
   transition-delay so they settle in order rather than as one flat
   fade-up. The large signature's cursor drift (assets/js/system.js) is
   the one genuinely new script in this section. ========================
   ========================================================================== */
.colophon{
  background:var(--ink); color:var(--on-dark);
  border-top:1px solid var(--line-dark);
  padding:calc(70px * var(--footer-spacing-mul,1)) var(--edge) 0;
  overflow:hidden; position:relative;
}
.colophon-inner{ max-width:var(--max); margin-inline:auto; }

/* ---- Lead — logo/statement left, Start a Project right ----
   The Footer Logo lives inside this wrapper, and the generic .reveal
   system it was already built on has no safe default: opacity:0 until
   JS + IntersectionObserver add .is-visible, with no unconditional
   fallback (the exact class of bug previously found and fixed on the
   Homepage Portfolio's .arc-media.reveal--mask). The Footer Logo must
   never depend on JS to be visible, so — scoped to .colophon-lead only,
   the generic .reveal class elsewhere on the site is untouched — this
   follows that same proven hardened pattern: visible by default, and
   only opts into the fade-in once .js-reveal-ready confirms JS actually
   can run it (added in assets/js/system.js only after IntersectionObserver
   support and no-reduced-motion are both confirmed). */
.colophon-lead{ display:flex; justify-content:space-between; align-items:flex-end; gap:40px; flex-wrap:wrap; padding-bottom:clamp(40px,6vw,64px); }
.colophon-lead.reveal{ opacity:1; transform:none; transition-delay:60ms; }
.js-reveal-ready .colophon-lead.reveal{ opacity:0; transform:translateY(10px); }
.js-reveal-ready .colophon-lead.reveal.is-visible{ opacity:1; transform:none; }

.colophon-brand{ max-width:480px; }
.colophon-signature{ display:inline-block; }
.colophon-logo-img{ display:block; height:var(--footer-logo-h,32px); width:auto; }
.colophon-signature img.custom-logo{ height:var(--footer-logo-h,32px); width:auto; }
.colophon-wordmark{ display:block; font-family:var(--f-display); font-weight:440; font-size:22px; color:var(--on-dark); }
/* No real Light logo uploaded (NEMA X → Header) — the Dark asset stands
   in, colour-flipped only, same technique as the Header's own nav logo. */
.colophon-logo-img--synthesized-light{ filter:invert(1); }
.colophon-footer-logo-img{ display:block; width:var(--footer-logo-w,160px); height:auto; max-width:100%; opacity:var(--footer-logo-custom-opacity,1); }

.colophon-statement{ font-family:var(--f-display); font-style:italic; font-weight:360; font-size:clamp(17px,1.8vw,21px); line-height:var(--lh-read); color:var(--on-dark); margin-top:18px; max-width:32ch; font-variant-numeric:oldstyle-figures; }
.colophon-tagline{ font-family:var(--f-mono); font-size:11px; letter-spacing:var(--ls-wide); text-transform:uppercase; color:var(--on-dark-soft); margin-top:14px; }

/* Start a Project — text + a growing underline + a small arrow shift.
   No fill, no button, no scale bounce. */
.colophon-cta{ position:relative; display:inline-flex; align-items:center; gap:10px; padding-bottom:4px; font-family:var(--f-mono); font-size:12px; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--on-dark); flex-shrink:0; }
.colophon-cta::after{ content:""; position:absolute; left:0; right:0; bottom:0; height:1px; background:var(--stamp-on-dark); transform:scaleX(.3); transform-origin:left; transition:transform var(--i3) var(--ease-instrument); }
.colophon-cta:hover::after, .colophon-cta:focus-visible::after{ transform:scaleX(1); }
.colophon-cta-arrow{ display:inline-block; transition:transform var(--i2) var(--ease-instrument); }
.colophon-cta:hover .colophon-cta-arrow, .colophon-cta:focus-visible .colophon-cta-arrow{ transform:translateX(4px); }

/* ---- Rule — the one drawn-width element ("the rule draws in") ---- */
.colophon-rule{ height:1px; background:var(--line-dark); transform-origin:left center; }
.colophon-rule.reveal{ transform:scaleX(0); opacity:1; transition:transform var(--i5) var(--ease-instrument); transition-delay:0ms; }
.colophon-rule.reveal.is-visible{ transform:scaleX(1); }

/* ---- Info row — Explore / Studio / Connect, compact by design ---- */
.colophon-row{ display:flex; flex-wrap:wrap; justify-content:space-between; gap:32px 40px; padding-block:32px 40px; border-bottom:1px solid var(--line-dark); }
.colophon-row.reveal{ transition-delay:120ms; }
.colophon-col{ display:flex; flex-direction:column; gap:10px; font-family:var(--f-mono); font-size:12px; color:var(--on-dark-soft); }
.colophon-col-label{ font-size:10px; letter-spacing:var(--ls-wide); text-transform:uppercase; color:var(--stamp-on-dark); margin-bottom:2px; }
.colophon-col-note{ opacity:.7; }

.colophon-nav{ display:flex; flex-direction:column; gap:8px; list-style:none; }
.colophon-nav li{ margin:0; }
.colophon-nav a{ position:relative; display:inline-block; padding-bottom:2px; color:var(--on-dark-soft); transition:color var(--i2) var(--ease-instrument); }
.colophon-nav a::after{ content:""; position:absolute; left:0; right:0; bottom:0; height:1px; background:var(--stamp-on-dark); transform:scaleX(0); transform-origin:left; transition:transform var(--i2) var(--ease-instrument); }
.colophon-nav a:hover, .colophon-nav a:focus-visible{ color:var(--on-dark); }
.colophon-nav a:hover::after, .colophon-nav a:focus-visible::after{ transform:scaleX(1); }

.colophon-col--connect{ display:flex; flex-direction:column; gap:8px; }
.colophon-col--connect a{ transition:color var(--i2) var(--ease-instrument); }
.colophon-col--connect a:hover, .colophon-col--connect a:focus-visible{ color:var(--on-dark); }
.colophon-external-icon{ --icon-size:10px; margin-left:4px; opacity:.6; }
.colophon-email-icon{ --icon-size:12px; margin-right:6px; opacity:.7; }

@media (max-width:639px){
  .colophon-row{ flex-direction:column; gap:28px; }
}

/* ---- Large signature — a watermark, not an advertisement. Two nested
   elements on purpose: the outer .reveal handles the one-shot entrance
   (opacity, CSS-transitioned); .colophon-watermark-img handles its own
   one-shot scale/translateY entrance; .colophon-watermark-cursor only
   ever receives a JS-written translateX (assets/js/system.js) every
   frame, with no CSS transition of its own — so the continuous
   cursor value and the one-shot entrance never fight over one property. */
.colophon-watermark{ display:flex; justify-content:center; padding:8px 0 6px; pointer-events:none; opacity:var(--watermark-opacity,.05); }
.colophon-watermark.reveal{ opacity:0; transform:none; transition:opacity var(--i5) var(--ease-instrument); transition-delay:180ms; }
.colophon-watermark.reveal.is-visible{ opacity:var(--watermark-opacity,.05); }

.colophon-watermark-cursor{ will-change:transform; }
.colophon-watermark-img{
  display:block; height:clamp(140px,26vw,360px); width:auto; max-width:none;
  transform:scale(.98) translateY(6px);
  transition:transform var(--i5) var(--ease-instrument);
}
.colophon-watermark.is-visible .colophon-watermark-img{ transform:scale(1) translateY(0); }
@media (max-width:639px){ .colophon-watermark-img{ height:clamp(90px,30vw,180px); } }

@media (prefers-reduced-motion:reduce){
  .colophon-rule.reveal{ transform:scaleX(1); }
  .colophon-lead.reveal, .colophon-row.reveal, .colophon-foot.reveal{ opacity:1; transform:none; }
  .colophon-watermark.reveal{ opacity:var(--watermark-opacity,.05); }
  .colophon-watermark-img{ transform:none; transition:none; }
}

/* ---- Foot — legal line + Back to Top, same underline/arrow language ---- */
.colophon-foot{ display:flex; justify-content:space-between; align-items:center; gap:20px; flex-wrap:wrap; font-family:var(--f-mono); font-size:11px; color:var(--on-dark-soft); letter-spacing:var(--ls-label); padding-block:22px 26px; }
.colophon-foot.reveal{ transition-delay:240ms; }

.colophon-totop{ position:relative; display:inline-flex; align-items:center; gap:8px; padding:0 0 4px; background:none; border:none; cursor:pointer; font:inherit; color:var(--on-dark-soft); }
.colophon-totop::after{ content:""; position:absolute; left:0; right:0; bottom:0; height:1px; background:var(--stamp-on-dark); transform:scaleX(.3); transform-origin:left; transition:transform var(--i3) var(--ease-instrument); }
.colophon-totop:hover::after, .colophon-totop:focus-visible::after{ transform:scaleX(1); }
.colophon-totop-arrow{ display:inline-block; transition:transform var(--i2) var(--ease-instrument); }
.colophon-totop:hover .colophon-totop-arrow, .colophon-totop:focus-visible .colophon-totop-arrow{ transform:translateY(-3px); }
[hidden]{ display:none !important; }
