/* ===========================================================
   ARIES — Design System
   Amaze Research, Innovation & Exploration Society

   Concept: "the published record". An editorial research
   institution — large serif display type over full-bleed
   imagery, generous air between ideas, and quiet hairline
   structure underneath. Photography does the heavy lifting;
   the type stays confident and plain.
   =========================================================== */

/* ---------- Typefaces ----------
   Self-hosted, Latin subset, woff2 only. Nothing is fetched from a third
   party, so the CSP allows no external style or font origin and no visitor
   IP reaches Google.

   `unicode-range` is not an optimisation here, it is required behaviour:
   the nav chevron is U+25BE, which sits outside the Latin subset. Declaring
   the range lets it fall through to a system face exactly as it did when
   these were served from Google. Drop the range and it renders as tofu.

   Newsreader and Libre Franklin are variable; the weight range in each
   `font-weight` descriptor is what makes one file cover every cut. */
@font-face{
  font-family:'Newsreader';
  src:url('../fonts/newsreader.woff2') format('woff2');
  font-weight:200 800;
  font-style:normal;
  font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Libre Franklin';
  src:url('../fonts/libre-franklin.woff2') format('woff2');
  font-weight:100 900;
  font-style:normal;
  font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/* `.prose em` asked for italic that was never loaded, so those runs were
   being synthesised by the browser. This is the real cut. */
@font-face{
  font-family:'Libre Franklin';
  src:url('../fonts/libre-franklin-italic.woff2') format('woff2');
  font-weight:100 900;
  font-style:italic;
  font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'IBM Plex Mono';
  src:url('../fonts/ibm-plex-mono-400.woff2') format('woff2');
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'IBM Plex Mono';
  src:url('../fonts/ibm-plex-mono-500.woff2') format('woff2');
  font-weight:500;
  font-style:normal;
  font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* ---------- Design tokens ---------- */
:root{
  /* --- ground: warm paper. Printed, not screen-grey. --- */
  --ground:#F7F5F0;
  --ground-sunk:#EEEBE3;
  --ground-deep:#E5E1D6;
  --raised:#FFFFFF;
  --ink:#15170F;
  --ink-soft:#3E4539;

  /* --- brand pine, taken from the mark --- */
  --pine-deep:#07220F;
  --pine-dark:#0A331F;
  --pine:#0E4A2A;
  --pine-mid:#155C36;
  --pine-light:#1D6F42;
  --pine-wash:#E3EADF;
  --pine-wash-soft:#EEF2EA;

  /* --- accent: dry engraved brass, desaturated off gold leaf --- */
  --brass:#8E6A2B;
  /* Text-safe brass. The accent above is 4.15:1 on --ground-sunk, which
     fails AA for 12px copy like .eyebrow; this clears 4.5:1 on every
     light ground while reading as the same colour. Use --brass for
     rules, borders and icons; --brass-ink whenever it's actual text. */
  --brass-ink:#7E5D26;
  /* Brass for eyebrows set over photography. --brass-pale is a mid-tone
     gold; at 12px over an unpredictable photographic backdrop it lands at
     4.2-4.4:1 however hard the scrim is pushed, and darkening the scrim
     far enough to rescue it would bury the photograph. Lifting the type
     instead is stable across whatever image is dropped in later. */
  --brass-on-photo:#E3D2A6;
  --brass-bright:#B08D45;
  --brass-pale:#DCC793;

  --sage:#5B6459;
  --sage-light:#8A9086;
  --line:#DEDACE;
  --line-strong:#C6C1B1;
  --line-on-dark:rgba(255,255,255,.16);
  --line-on-dark-strong:rgba(255,255,255,.32);
  --paper-on-dark:#F1EFE8;
  --paper-on-dark-soft:rgba(241,239,232,.80);
  --paper-on-dark-faint:rgba(241,239,232,.62);

  /* semantic state — deliberately separate from the brass accent */
  --state-active-bg:#E3EADF;
  --state-active-text:#0A331F;
  --state-done-bg:#E9E7DE;
  --state-done-text:#5B6459;
  --danger:#8A3A2C;

  /* --- type --- */
  --font-serif:'Newsreader', 'Iowan Old Style', Georgia, serif;
  --font-sans:'Libre Franklin', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono:'IBM Plex Mono', ui-monospace, 'Courier New', monospace;

  /* Type scale. The display end is deliberately far away from the
     body end — that gap is most of what makes the page read as
     editorial rather than as an app.

     The reading tiers (2xs…md) are held where they were: they are set
     at sizes that were already checked for contrast and line length,
     and there is nothing to gain by moving them. Everything from `lg`
     up has been pushed, so the distance between a paragraph and a
     headline is now much larger than a template would dare.

     Every minimum is chosen to still fit a 360px viewport; the sweep
     across 360/375/390/412/428 is what proves it. */
  --t-2xs:11px;
  --t-xs:12px;
  --t-sm:13.5px;
  --t-base:15.5px;
  --t-md:17px;
  --t-lg:clamp(19px,1.6vw,23px);
  --t-xl:clamp(24px,2.3vw,33px);
  --t-2xl:clamp(29px,3.6vw,46px);
  --t-3xl:clamp(35px,5.2vw,66px);
  --t-4xl:clamp(41px,6.8vw,88px);
  --t-display:clamp(45px,8.6vw,124px);

  /* Tracking tightens as type grows: optical compensation, since the
     same letter-spacing that suits 16px looks slack at 100px. */
  --track-display:-.035em;
  --track-4xl:-.032em;
  --track-3xl:-.028em;
  --track-2xl:-.022em;

  /* spacing scale */
  --sp-1:.25rem;
  --sp-2:.5rem;
  --sp-3:.75rem;
  --sp-4:1rem;
  --sp-5:1.5rem;
  --sp-6:2rem;
  --sp-7:3rem;
  --sp-8:4rem;
  --sp-9:6rem;
  --sp-10:8rem;

  /* Section rhythm. One token so the vertical air stays consistent
     and scales down in one place on small screens. */
  --sp-section:clamp(68px,9.5vw,144px);
  --sp-section-tight:clamp(48px,6.5vw,96px);

  --radius-sm:2px;
  --radius-md:3px;
  --radius-lg:6px;
  --container:1280px;
  --container-narrow:940px;
  --gutter:clamp(20px,4.2vw,64px);
  --header-h:82px;
  --header-h-condensed:62px;

  /* motion */
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --dur-fast:.16s;
  --dur:.3s;
  --dur-slow:.55s;

  /* elevation — restrained; this design leans on rules, not shadows */
  --shadow-sm:0 1px 3px rgba(7,34,15,.07);
  --shadow-md:0 10px 30px rgba(7,34,15,.10);
  --shadow-lg:0 24px 56px rgba(7,34,15,.16);
}

/* The palette commits to a single light "paper record" world.
   Declaring it stops browsers force-darkening form controls. */
:root{color-scheme:light;}

*,*::before,*::after{box-sizing:border-box;}
html{
  scroll-behavior:smooth;-webkit-text-size-adjust:100%;
  /* Body below uses `overflow-x:clip`, which is the stronger, newer form.
     These are the fallback for browsers older than Safari 16 that don't
     understand `clip` and would otherwise drop the declaration silently. */
  overflow-x:hidden;max-width:100%;
}
body{
  margin:0;
  background:var(--ground);
  color:var(--ink);
  font-family:var(--font-sans);
  font-size:16px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:clip;
  /* Newsreader carries a real optical-size axis (6–72). Left on `auto`
     the browser drives `opsz` from the used font-size, so display type
     gets the high-contrast cut and body copy gets the sturdy one from
     the same file. This is the reason for shipping the variable font
     rather than three static weights. */
  font-optical-sizing:auto;
}
img{max-width:100%;display:block;}
a{color:inherit;}
h1,h2,h3,h4{
  font-family:var(--font-serif);font-weight:500;line-height:1.1;margin:0;
  letter-spacing:-.015em;text-wrap:balance;
}
h1{font-weight:400;letter-spacing:-.025em;}

/* Every figure on the site is tabular, not just the ones that happened to
   declare it. main.js counts figures up on reveal and animates the bar
   values, so proportional digits make the number visibly jitter and shove
   its label around while it settles. Applied once here rather than being
   remembered at each call site. */
.stat-num,.sb-num,.hs-num,.s-num,.bar-value,.badge-num,.ed-index,
.proj-meta,.pub-meta,.event-date,[data-year]{
  font-variant-numeric:tabular-nums;
}
p{margin:0;text-wrap:pretty;}
ul{margin:0;padding:0;list-style:none;}
button{font-family:inherit;}
::selection{background:var(--pine-wash);color:var(--pine-deep);}

/* ---------- Accessibility helpers ---------- */
.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;
}
.skip-link{
  position:absolute;left:-9999px;top:0;background:var(--ink);color:var(--ground);
  padding:12px 20px;z-index:1000;font-size:14px;font-weight:500;
}
.skip-link:focus{left:16px;top:16px;}
:focus-visible{outline:2px solid var(--brass);outline-offset:3px;border-radius:1px;}

/* ---------- Layout ---------- */
.container{max-width:var(--container);margin:0 auto;padding:0 var(--gutter);}
.container--narrow{max-width:var(--container-narrow);}

.section{padding:var(--sp-section) 0;}
.section--tight{padding:var(--sp-section-tight) 0;}
.section--paper{background:var(--ground);}
.section--tint{background:var(--ground-sunk);}
.section--dark{background:var(--ink);color:var(--paper-on-dark);position:relative;overflow:hidden;}
.section--brand{background:var(--pine);color:var(--ground);position:relative;overflow:hidden;}

/* ---------- Contour motif ----------
   One survey drawing, reused at deliberately different scales and crops so
   it reads as a recurring signature rather than a texture applied once.
   Scaling well past 100% is the point: each placement shows a different
   fragment of the same contours, so the asset never repeats a recognisable
   shape and never reads as wallpaper.

   Positions use the two-value percentage form on purpose. The four-value
   edge-offset form (`right -18% bottom -40%`) resolves against the
   *difference* between image and container, so with an image several times
   the height of its box it lands entirely outside and paints nothing. */

/* Contour texture on dark grounds */
.section--dark::after,.section--brand:not(.hero)::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:url('../img/topo-lines-light.svg') center 45%/cover no-repeat;
  opacity:.32;
}

/* Tinted bands carry the motif at a much larger scale, cropped hard to the
   left edge, so the recurrence is felt rather than noticed. */
.section--tint{position:relative;overflow:hidden;}
.section--tint::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:url('../img/topo-lines-dark.svg') 12% 38%/230% auto no-repeat;
  opacity:.22;
  -webkit-mask-image:linear-gradient(100deg,#000 0%,transparent 66%);
  mask-image:linear-gradient(100deg,#000 0%,transparent 66%);
}
.section--tint > .container{position:relative;z-index:1;}

/* The footer closes the record: the motif returns at the largest scale on
   the site, anchored to the opposite corner from the tint bands. */
.site-footer{position:relative;overflow:hidden;}
.site-footer::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:url('../img/topo-lines-light.svg') 82% 62%/300% auto no-repeat;
  opacity:.20;
  -webkit-mask-image:linear-gradient(300deg,#000 0%,transparent 74%);
  mask-image:linear-gradient(300deg,#000 0%,transparent 74%);
}
.site-footer > .container{position:relative;z-index:1;}
.section--dark::after{opacity:.2;background-position:center 60%;}
.section--dark > .container,.section--brand > .container{position:relative;z-index:1;}

/* Section head. The heading sits large on the left with a short
   standfirst opposite — the standard editorial opener. */
.section-head{
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:var(--sp-6) var(--sp-8);align-items:end;
  margin-bottom:clamp(36px,4.5vw,68px);
}
.section-head > :first-child{min-width:0;}
.section-head .lede{
  max-width:44ch;font-size:var(--t-md);color:var(--sage);line-height:1.62;
}
.section-head .btn-arrow,.section-head .arrow-cta{justify-self:start;align-self:end;}
@media (max-width:820px){
  .section-head{grid-template-columns:1fr;gap:var(--sp-4);align-items:start;}
  .section-head .lede{max-width:60ch;}
}

/* Mono micro-label */
.eyebrow{
  font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:.16em;
  text-transform:uppercase;color:var(--brass-ink);margin:0 0 var(--sp-4);font-weight:500;
}
.section--dark .eyebrow,.section--brand .eyebrow{color:var(--brass-pale);}

h2.section-title{font-size:var(--t-3xl);max-width:16ch;letter-spacing:var(--track-3xl);}
h2.section-title--wide{max-width:24ch;}
h3.card-title{font-size:var(--t-lg);}
.section--dark .section-title,.section--brand .section-title{color:var(--ground);}

/* Standing intro paragraph beneath a section heading */
.section-lede{
  font-size:var(--t-md);color:var(--ink-soft);line-height:1.72;
  max-width:58ch;margin-top:var(--sp-5);
}
.section--dark .section-lede,.section--brand .section-lede,
.section--dark .lede,.section--brand .lede{color:var(--paper-on-dark-soft);}
.section--dark .form-note,.section--brand .form-note{color:var(--paper-on-dark-faint);}

/* Inline links in body copy */
.prose a,.lede a,.form-note a,.c-value a,.pub-abstract a,.stat-label a{
  color:var(--pine-dark);text-underline-offset:2px;
}
/* …but pine-dark on a dark ground is all but invisible (1.21:1 in the
   cover hero). On dark grounds the accent takes over. */
.section--dark :is(.prose,.lede,.form-note,.c-value,.pub-abstract,.stat-label) a,
.section--brand :is(.prose,.lede,.form-note,.c-value,.pub-abstract,.stat-label) a,
.page-hero--cover :is(.prose,.lede,.form-note,.breadcrumb) a,
.hero :is(.prose,.lede,.form-note) a{
  color:var(--brass-pale);
}

/* Titles-only reference list */
.ref-list li{
  padding:13px 0;border-bottom:1px solid var(--line);
  font-size:15px;color:var(--ink-soft);line-height:1.6;
}
.ref-list li:last-child{border-bottom:none;}
.block-divider{margin-top:var(--sp-7);padding-top:var(--sp-6);border-top:1px solid var(--line);}

/* ---------- Placeholder flag ---------- */
.placeholder{
  display:inline-block;font-family:var(--font-mono);font-size:10px;letter-spacing:.08em;
  color:var(--danger);background:#F6EAE7;border:1px solid #E0C6BF;border-radius:2px;
  padding:1px 7px;margin-left:7px;vertical-align:middle;text-transform:uppercase;
  font-weight:500;line-height:1.5;
}
.placeholder-block{
  border:1px solid var(--line-strong);border-left:3px solid var(--brass);
  background:var(--raised);color:var(--ink-soft);
  font-size:var(--t-base);padding:var(--sp-5);line-height:1.65;
}
.placeholder-block a{color:var(--pine-dark);}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font-size:14.5px;font-weight:500;min-height:48px;
  padding:13px 28px;border-radius:var(--radius-sm);text-decoration:none;
  border:1px solid transparent;cursor:pointer;position:relative;letter-spacing:.005em;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
}
.btn-primary{background:var(--pine);color:#fff;}
.btn-primary:hover{background:var(--pine-deep);box-shadow:var(--shadow-sm);}
.btn-primary:active{background:var(--pine-deep);box-shadow:none;}
.btn-secondary{
  border-color:var(--line-strong);color:var(--ink);background:transparent;
  overflow:hidden;z-index:0;
}
.btn-secondary::before{
  content:"";position:absolute;inset:0;background:var(--pine-wash);z-index:-1;
  transform:scaleX(0);transform-origin:left;transition:transform var(--dur-slow) var(--ease);
}
.btn-secondary:hover{border-color:var(--pine);}
.btn-secondary:hover::before{transform:scaleX(1);}
.section--dark .btn-secondary,.section--brand .btn-secondary{
  border-color:var(--line-on-dark-strong);color:var(--ground);
}
.section--dark .btn-secondary::before,.section--brand .btn-secondary::before{background:rgba(255,255,255,.1);}
.section--brand .btn-primary{background:var(--ground);color:var(--pine-deep);}
.section--brand .btn-primary:hover{background:#fff;}

/* ---------- Arrow CTA ----------
   The workhorse call to action: a filled disc holding an arrow,
   with the label set beside it. Used in place of a second button
   wherever the action is "read on" rather than "do something". */
.arrow-cta{
  display:inline-flex;align-items:center;gap:15px;text-decoration:none;
  color:inherit;font-size:15.5px;font-weight:500;line-height:1.4;
  width:fit-content;max-width:100%;
}
.arrow-cta-icon{
  flex:none;width:46px;height:46px;border-radius:50%;
  background:var(--ink);color:var(--ground);
  display:grid;place-items:center;
  transition:background var(--dur) var(--ease),transform var(--dur) var(--ease);
}
.arrow-cta-icon svg{width:17px;height:17px;display:block;}
.arrow-cta-label{
  position:relative;padding-bottom:2px;
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size var(--dur-slow) var(--ease);
}
.arrow-cta:hover .arrow-cta-icon,.arrow-cta:focus-visible .arrow-cta-icon{
  background:var(--pine);transform:translateX(3px);
}
.arrow-cta:hover .arrow-cta-label,.arrow-cta:focus-visible .arrow-cta-label{background-size:100% 1px;}
.arrow-cta--sm{gap:12px;font-size:14.5px;}
.arrow-cta--sm .arrow-cta-icon{width:38px;height:38px;}
.arrow-cta--sm .arrow-cta-icon svg{width:14px;height:14px;}
.section--dark .arrow-cta-icon,.section--brand .arrow-cta-icon,
.hero .arrow-cta-icon{background:var(--ground);color:var(--ink);}
.section--dark .arrow-cta:hover .arrow-cta-icon,
.section--brand .arrow-cta:hover .arrow-cta-icon,
.hero .arrow-cta:hover .arrow-cta-icon{background:#fff;}
/* Inside a card the whole cell is the link, so the disc has to
   respond to the card's hover rather than only its own. */
.media-card:hover .arrow-cta-icon{background:var(--pine);transform:translateX(3px);}
.media-card:hover .arrow-cta-label{background-size:100% 1px;}

/* Inline "read on" link — a rule that draws itself in brass */
.btn-arrow{
  font-size:13.5px;font-weight:500;text-decoration:none;color:inherit;
  display:inline-flex;align-items:center;gap:7px;padding-bottom:3px;
  position:relative;width:fit-content;
  transition:color var(--dur) var(--ease);
}
.btn-arrow::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--brass);transform:scaleX(0);transform-origin:left;
  transition:transform var(--dur-slow) var(--ease);
}
.btn-arrow:hover{color:var(--pine-dark);}
.btn-arrow:hover::after{transform:scaleX(1);}
.section--dark .btn-arrow:hover,.section--brand .btn-arrow:hover{color:#fff;}

/* ---------- Badges / stickers ----------
   Small stamped accents for a stat, a label, or a rank. Kept
   flat and tinted rather than shadowed — a printed sticker,
   not a UI chip. */
.badge{
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--font-mono);font-size:var(--t-2xs);font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;
  padding:6px 12px;border-radius:100px;
  background:var(--pine-wash);color:var(--pine-dark);
  white-space:nowrap;
}
.badge--brass{background:#F3EAD6;color:#6E5220;}
.badge--outline{background:transparent;border:1px solid var(--line-strong);color:var(--sage);}
.section--dark .badge,.section--brand .badge,.hero .badge{
  background:rgba(255,255,255,.13);color:var(--paper-on-dark);
}
.section--dark .badge--brass,.hero .badge--brass{
  background:rgba(220,199,147,.18);color:var(--brass-pale);
}

/* Numeral tile — the ranked/indexed accent */
.badge-num{
  flex:none;display:grid;place-items:center;
  width:58px;height:58px;border-radius:var(--radius-md);
  background:var(--ground-sunk);color:var(--pine-dark);
  font-family:var(--font-serif);font-size:26px;font-weight:500;
  line-height:1;font-variant-numeric:tabular-nums;letter-spacing:-.02em;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease);
}
.section--tint .badge-num{background:var(--ground-deep);}
.section--dark .badge-num{background:rgba(255,255,255,.09);color:var(--brass-pale);}

/* Circular stat sticker — a figure with its unit beneath */
.stat-badge{
  display:flex;flex-direction:column;align-items:flex-start;justify-content:center;
  padding:var(--sp-6) var(--sp-5);
  background:var(--raised);border:1px solid var(--line);border-radius:var(--radius-lg);
  transition:border-color var(--dur) var(--ease),transform var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}
.stat-badge:hover{border-color:var(--line-strong);transform:translateY(-3px);box-shadow:var(--shadow-md);}
.stat-badge .sb-num{
  font-family:var(--font-serif);font-size:clamp(44px,5vw,64px);font-weight:400;
  color:var(--pine-dark);line-height:1;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;
}
.stat-badge .sb-label{
  font-size:14px;color:var(--sage);line-height:1.55;margin-top:var(--sp-4);max-width:26ch;
}
.stat-badge .badge{margin-bottom:var(--sp-4);}
.section--dark .stat-badge{background:rgba(255,255,255,.045);border-color:var(--line-on-dark);}
.section--dark .stat-badge:hover{border-color:var(--line-on-dark-strong);}
.section--dark .stat-badge .sb-num{color:var(--brass-pale);}
.section--dark .stat-badge .sb-label{color:var(--paper-on-dark-soft);}

.badge-row{display:flex;flex-wrap:wrap;gap:10px;}

/* ---------- Header / Nav ---------- */
.site-header{
  position:sticky;top:0;z-index:200;background:rgba(247,245,240,.88);
  backdrop-filter:blur(12px) saturate(1.4);-webkit-backdrop-filter:blur(12px) saturate(1.4);
  border-bottom:1px solid var(--line);
  transition:box-shadow var(--dur) var(--ease),background var(--dur) var(--ease);
}
.site-header.is-scrolled{background:rgba(247,245,240,.97);box-shadow:0 1px 0 var(--line),0 10px 24px rgba(7,34,15,.05);}
.site-header > .container{
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);
  height:var(--header-h);
  transition:height var(--dur) var(--ease);
}
.site-header.is-scrolled > .container{height:var(--header-h-condensed);}
.brand{display:flex;align-items:center;gap:12px;text-decoration:none;min-width:0;}
.brand img{
  height:38px;width:38px;flex:none;
  transition:height var(--dur) var(--ease),width var(--dur) var(--ease);
}
.site-header.is-scrolled .brand img{height:30px;width:30px;}
.brand-word{
  font-family:var(--font-serif);font-weight:500;font-size:21px;color:var(--ink);
  line-height:1.05;letter-spacing:.01em;min-width:0;
}
.brand-word small{
  display:block;font-family:var(--font-mono);font-weight:400;font-size:9px;
  letter-spacing:.13em;color:var(--sage);margin-top:3px;white-space:nowrap;
  transition:opacity var(--dur) var(--ease),margin-top var(--dur) var(--ease);
}
.site-header.is-scrolled .brand-word small{opacity:0;margin-top:-9px;}
/* The expanded society name is ~330px of nowrap text. Below this it
   starts crowding the nav — the mark plus the wordmark carry the
   identity on their own. */
@media (max-width:1240px){ .brand-word small{display:none;} }

.nav-desktop{display:flex;align-items:center;gap:2px;}
.nav-desktop > li{position:relative;}
.nav-link{
  position:relative;display:flex;align-items:center;gap:6px;font-size:14.5px;font-weight:500;
  color:var(--ink);text-decoration:none;padding:14px 15px;
}
.nav-link::after{
  content:"";position:absolute;left:15px;right:15px;bottom:8px;height:1.5px;
  background:var(--brass);transform:scaleX(0);transform-origin:left;
  transition:transform var(--dur) var(--ease);
}
.nav-link:hover::after,.nav-link:focus-visible::after{transform:scaleX(1);}
.nav-link[aria-current="page"]{color:var(--pine-dark);}
.nav-link[aria-current="page"]::after{transform:scaleX(1);background:var(--pine);}
.nav-link .chev{font-size:9px;color:var(--sage-light);transition:transform var(--dur) var(--ease);}
.has-dropdown:hover .chev,.has-dropdown:focus-within .chev,.has-dropdown.is-open .chev{transform:rotate(180deg);}
.nav-cta{
  background:var(--pine);color:#fff;padding:11px 21px;border-radius:var(--radius-sm);
  font-size:14.5px;font-weight:500;text-decoration:none;margin-left:10px;
  display:inline-flex;align-items:center;white-space:nowrap;
  transition:background var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
}
.nav-cta:hover{background:var(--pine-deep);box-shadow:var(--shadow-sm);}

/* Dropdown — right-anchored so a panel near the viewport edge
   can't overflow, regardless of how many nav items exist. */
.dropdown{
  position:absolute;top:100%;right:0;
  background:var(--raised);border:1px solid var(--line);box-shadow:var(--shadow-lg);
  padding:8px;display:flex;flex-direction:column;gap:2px;width:320px;
  border-radius:var(--radius-md);
  opacity:0;visibility:hidden;pointer-events:none;
  transform:translateY(-6px);
  transition:opacity var(--dur) var(--ease),transform var(--dur) var(--ease),visibility var(--dur);
}
.has-dropdown:hover .dropdown,.has-dropdown:focus-within .dropdown,.has-dropdown.is-open .dropdown{
  opacity:1;visibility:visible;pointer-events:auto;transform:translateY(0);
}
.dropdown a{
  display:block;text-decoration:none;position:relative;padding:12px 14px;
  border-radius:var(--radius-sm);border-left:2px solid transparent;
  transition:background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease);
}
.dropdown a:hover{background:var(--pine-wash-soft);border-left-color:var(--brass);}
.dropdown .dd-title{
  font-size:14.5px;font-weight:600;color:var(--ink);margin:0 0 3px;
  transition:color var(--dur-fast) ease;
}
.dropdown .dd-desc{font-size:12.5px;color:var(--sage);line-height:1.5;}
.dropdown a:hover .dd-title{color:var(--pine-dark);}

.nav-toggle{
  display:none;background:none;border:none;cursor:pointer;
  width:44px;height:44px;margin-right:-10px;
  flex-direction:column;align-items:center;justify-content:center;gap:5px;flex:none;
}
.nav-toggle span{
  width:22px;height:1.5px;background:var(--ink);display:block;
  transition:transform var(--dur) var(--ease),opacity var(--dur) var(--ease);
}
.nav-toggle.is-active span:nth-child(1){transform:translateY(6.5px) rotate(45deg);}
.nav-toggle.is-active span:nth-child(2){opacity:0;}
.nav-toggle.is-active span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg);}

/* Mobile nav.
   `visibility` is toggled alongside the transform so the closed panel
   is genuinely inert — otherwise its links stay in the tab order and
   keyboard users fall into an invisible menu. */
.nav-mobile{
  display:none;position:fixed;
  top:var(--header-h-live,var(--header-h));left:0;right:0;bottom:0;
  background:var(--ground);z-index:190;
  overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  padding:var(--sp-5) var(--gutter) calc(var(--sp-8) + env(safe-area-inset-bottom));
  transform:translateX(100%);visibility:hidden;
  transition:transform var(--dur-slow) var(--ease),visibility var(--dur-slow);
}
.nav-mobile.is-open{transform:translateX(0);visibility:visible;}
.nav-mobile-item{
  border-bottom:1px solid var(--line);
  opacity:0;transform:translateY(8px);
  transition:opacity var(--dur-slow) var(--ease),transform var(--dur-slow) var(--ease);
}
.nav-mobile.is-open .nav-mobile-item{opacity:1;transform:translateY(0);}
.nav-mobile.is-open .nav-mobile-item:nth-child(1){transition-delay:.05s;}
.nav-mobile.is-open .nav-mobile-item:nth-child(2){transition-delay:.1s;}
.nav-mobile.is-open .nav-mobile-item:nth-child(3){transition-delay:.15s;}
.nav-mobile.is-open .nav-mobile-item:nth-child(4){transition-delay:.2s;}
.nav-mobile.is-open .nav-mobile-item:nth-child(5){transition-delay:.25s;}
.nav-mobile.is-open .nav-mobile-item:nth-child(6){transition-delay:.3s;}
/* The delay alone was here, without the opacity/transform reset the
   items get — so the CTA stayed at opacity:0 and never appeared. */
.nav-mobile.is-open .nav-cta{opacity:1;transform:translateY(0);transition-delay:.35s;}
.nav-mobile-link{
  display:flex;justify-content:space-between;align-items:center;gap:var(--sp-4);
  padding:16px 2px;min-height:56px;
  font-family:var(--font-serif);font-size:22px;font-weight:500;
  text-decoration:none;color:var(--ink);
}
.nav-mobile-link .chev{font-size:11px;color:var(--sage-light);transition:transform var(--dur) var(--ease);}
.nav-mobile-link[aria-expanded="true"] .chev{transform:rotate(180deg);}
.nav-mobile-children{display:none;padding:0 2px 14px;}
.nav-mobile-children.is-open{display:block;animation:fadeUp var(--dur-slow) var(--ease) both;}
.nav-mobile-children a{
  display:block;padding:11px 0 11px 14px;font-size:15.5px;color:var(--sage);
  text-decoration:none;border-left:1px solid var(--line);
  transition:color var(--dur-fast) ease,border-color var(--dur-fast) ease;
}
.nav-mobile-children a:hover{color:var(--pine-dark);border-left-color:var(--brass);}
.nav-mobile .nav-cta{
  display:inline-flex;margin:24px 2px 0;min-height:48px;
  opacity:0;transform:translateY(8px);
  transition:opacity var(--dur-slow) var(--ease),transform var(--dur-slow) var(--ease),
    background var(--dur) var(--ease);
}

@media (max-width:1150px){ .nav-link{padding:14px 12px;} .nav-link::after{left:12px;right:12px;} }
@media (max-width:1040px){
  .nav-desktop{display:none;}
  .nav-toggle{display:flex;}
  .nav-mobile{display:block;}
}

/* ---------- Home hero ----------
   Full-bleed photograph, a scrim graded for legibility, and the
   headline set as large as the viewport will carry. */
.hero{
  position:relative;isolation:isolate;overflow:hidden;
  background:var(--pine-deep);color:var(--ground);
  min-height:min(88svh,860px);
  display:flex;align-items:flex-end;
  padding:calc(var(--sp-section) + 40px) 0 var(--sp-section);
}
/* svh is not universal; vh is the fallback and is close enough
   for a section that is already min-height driven. */
@supports not (height:1svh){ .hero{min-height:min(88vh,860px);} }

.hero-media{position:absolute;inset:0;z-index:-2;overflow:hidden;}
.hero-media img{width:100%;height:100%;object-fit:cover;object-position:center 40%;}
.hero::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  /* Measured against the actual photograph rather than assumed: the old
     gradient dipped to .12 alpha across the middle, and the worst-case
     backdrop pixel behind the lede came out at 1.55:1 where 4.5:1 is
     needed. The floor is raised through the whole text zone and the
     falloff moved to the upper right, which is the only part of the frame
     that carries no type. */
  background:
    linear-gradient(180deg,rgba(7,34,15,.66) 0%,rgba(7,34,15,.54) 24%,rgba(7,34,15,.86) 58%,rgba(7,34,15,.95) 100%),
    linear-gradient(96deg,rgba(7,34,15,.82) 0%,rgba(7,34,15,.56) 52%,rgba(7,34,15,.08) 100%);
}
.hero > .container{position:relative;z-index:1;width:100%;}
.hero-inner{max-width:23ch;}
.hero .eyebrow{color:var(--brass-pale);margin-bottom:var(--sp-5);}
.hero h1{
  font-size:var(--t-display);margin-bottom:var(--sp-5);font-weight:400;letter-spacing:var(--track-display);
  letter-spacing:-.03em;line-height:1.02;color:#FCFDFA;
  text-shadow:0 1px 40px rgba(7,34,15,.35);
}

/* Split hero: the headline column beside a promoted item, so the
   far side of a wide viewport carries something rather than sitting
   as empty photograph. */
.hero-grid{
  display:grid;grid-template-columns:minmax(0,1.32fr) minmax(0,.68fr);
  gap:clamp(36px,4vw,80px);align-items:end;
}
.hero--split .hero-inner{max-width:none;}
.hero--split h1{font-size:clamp(40px,5.4vw,78px);}
.hero--split .lede{max-width:46ch;}

/* The promoted card. Translucent over the photograph rather than
   solid, so the image still reads underneath it. */
.hero-feature{
  display:flex;flex-direction:column;text-decoration:none;color:var(--paper-on-dark);
  background:rgba(7,34,15,.52);
  backdrop-filter:blur(14px) saturate(1.2);-webkit-backdrop-filter:blur(14px) saturate(1.2);
  border:1px solid rgba(255,255,255,.18);border-radius:var(--radius-lg);
  overflow:hidden;
  transition:transform var(--dur) var(--ease),border-color var(--dur) var(--ease),
    background var(--dur) var(--ease);
}
.hero-feature:hover{
  transform:translateY(-4px);border-color:rgba(255,255,255,.34);
  background:rgba(7,34,15,.62);
}
.hero-feature .hff-img{aspect-ratio:3/2;overflow:hidden;flex:none;background:var(--pine-dark);}
.hero-feature .hff-img img{
  width:100%;height:100%;object-fit:cover;
  transition:transform .7s var(--ease-out);
}
.hero-feature:hover .hff-img img{transform:scale(1.05);}
.hero-feature .hff-body{
  padding:var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-3);align-items:flex-start;
}
.hero-feature .hff-title{
  font-family:var(--font-serif);font-size:var(--t-lg);font-weight:500;
  line-height:1.16;letter-spacing:-.015em;color:#FCFDFA;
}
.hero-feature .hff-dek{font-size:14.5px;line-height:1.6;color:rgba(241,239,232,.78);}
.hero-feature .arrow-cta{margin-top:var(--sp-2);}
.hero-feature:hover .arrow-cta-icon{background:#fff;transform:translateX(3px);}
.hero-feature:hover .arrow-cta-label{background-size:100% 1px;}
.hero .hero-feature{animation:heroUp .9s var(--ease-out) both;animation-delay:.44s;}

@media (max-width:1040px){
  .hero-grid{grid-template-columns:1fr;gap:var(--sp-7);align-items:start;}
  /* Below the split the card is a banner, not a column — a stacked
     3:2 image at full width would push the fold off the screen. */
  .hero-feature{flex-direction:row;align-items:stretch;}
  .hero-feature .hff-img{aspect-ratio:auto;width:38%;max-width:260px;min-height:150px;}
  .hero-feature .hff-body{justify-content:center;flex:1;}
}
@media (max-width:560px){
  .hero-feature{flex-direction:column;}
  .hero-feature .hff-img{aspect-ratio:16/9;width:100%;max-width:none;min-height:0;}
}
.hero .lede{
  font-size:var(--t-md);max-width:54ch;line-height:1.66;margin-bottom:var(--sp-6);
  color:rgba(241,239,232,.88);
}
.hero .actions{display:flex;gap:16px 26px;flex-wrap:wrap;align-items:center;}
.hero .btn-secondary{border-color:var(--line-on-dark-strong);color:var(--ground);}
.hero .btn-secondary::before{background:rgba(255,255,255,.12);}
.hero .btn-primary{background:var(--ground);color:var(--pine-deep);}
.hero .btn-primary:hover{background:#fff;}

/* Hero entrance. Kept as CSS animations rather than observer work
   because the hero is above the fold by definition. */
.hero .eyebrow{animation:heroUp .7s var(--ease-out) both;animation-delay:.06s;}
.hero h1{animation:heroUp .9s var(--ease-out) both;animation-delay:.14s;}
.hero .lede{animation:heroUp .9s var(--ease-out) both;animation-delay:.26s;}
.hero .actions{animation:heroUp .9s var(--ease-out) both;animation-delay:.38s;}
.hero .hero-stats{animation:heroUp .9s var(--ease-out) both;animation-delay:.5s;}

/* A strip of figures sitting on the hero's bottom edge */
.hero-stats{
  display:flex;flex-wrap:wrap;gap:var(--sp-5) var(--sp-8);
  margin-top:clamp(40px,5vw,72px);padding-top:var(--sp-5);
  border-top:1px solid var(--line-on-dark);
}
.hero-stat{min-width:0;}
.hero-stat .hs-num{
  font-family:var(--font-serif);font-size:clamp(30px,3.2vw,42px);font-weight:400;
  line-height:1;color:#FCFDFA;letter-spacing:-.025em;font-variant-numeric:tabular-nums;
}
.hero-stat .hs-label{
  font-family:var(--font-mono);font-size:var(--t-2xs);letter-spacing:.11em;
  text-transform:uppercase;color:var(--brass-pale);margin-top:10px;
}

@media (max-width:900px){
  .hero-inner{max-width:none;}
  .hero h1{max-width:14ch;}
}
@media (max-width:700px){
  .hero{
    min-height:min(78svh,640px);
    padding:calc(var(--sp-section) + 24px) 0 var(--sp-section-tight);
  }
  .hero::before{
    background:linear-gradient(178deg,rgba(7,34,15,.74) 0%,rgba(7,34,15,.68) 26%,
      rgba(7,34,15,.90) 66%,rgba(7,34,15,.96) 100%);
  }
  .hero h1{max-width:none;line-height:1.06;}
  .hero .actions{gap:14px;}
  .hero .actions .btn{width:100%;}
  .hero-stats{gap:var(--sp-5) var(--sp-6);}
  .hero-stat{flex:1 1 40%;}
}
@supports not (height:1svh){
  @media (max-width:700px){ .hero{min-height:min(78vh,640px);} }
}

/* ---------- Interior page hero ---------- */
.page-hero{
  position:relative;overflow:hidden;
  padding:clamp(56px,7vw,104px) 0 clamp(44px,5.5vw,80px);
  border-bottom:1px solid var(--line);
}
.page-hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:url('../img/topo-lines-dark.svg') center 25%/cover no-repeat;
  opacity:.34;
  -webkit-mask-image:linear-gradient(75deg,transparent 30%,#000 100%);
  mask-image:linear-gradient(75deg,transparent 30%,#000 100%);
}
.page-hero > .container{position:relative;z-index:1;}
.page-hero h1{
  font-size:var(--t-4xl);max-width:18ch;letter-spacing:var(--track-4xl);
  animation:heroUp .75s var(--ease-out) both;animation-delay:.13s;
}
.page-hero .lede{
  font-size:var(--t-md);max-width:58ch;color:var(--ink-soft);
  margin-top:var(--sp-5);line-height:1.7;
  animation:heroUp .75s var(--ease-out) both;animation-delay:.22s;
}
.page-hero .breadcrumb{animation:heroUp .55s var(--ease-out) both;}
.page-hero .eyebrow{animation:heroUp .6s var(--ease-out) both;animation-delay:.07s;}
.page-hero .badge-row{
  margin-top:var(--sp-6);
  animation:heroUp .75s var(--ease-out) both;animation-delay:.3s;
}

/* Cover variant — the title block sits on the photograph, matching
   the home hero so interior pages don't read as a different site. */
.page-hero--cover{
  border-bottom:none;isolation:isolate;
  background:var(--pine-deep);color:var(--paper-on-dark);
  padding:clamp(72px,9vw,132px) 0 clamp(56px,7vw,104px);
  display:flex;align-items:flex-end;min-height:min(56svh,520px);
}
@supports not (height:1svh){ .page-hero--cover{min-height:min(56vh,520px);} }
.page-hero--cover::after{display:none;}
.page-hero--cover .hero-media{position:absolute;inset:0;z-index:-2;overflow:hidden;}
.page-hero--cover .hero-media img{width:100%;height:100%;object-fit:cover;object-position:center 42%;}
.page-hero--cover::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(7,34,15,.78) 0%,rgba(7,34,15,.64) 36%,rgba(7,34,15,.90) 100%),
    linear-gradient(96deg,rgba(7,34,15,.84) 0%,rgba(7,34,15,.62) 60%,rgba(7,34,15,.22) 100%);
}
.page-hero--cover > .container{width:100%;}
.page-hero--cover h1{color:#FCFDFA;max-width:17ch;}
.page-hero--cover .lede{color:rgba(241,239,232,.95);}
.page-hero--cover .eyebrow{color:var(--brass-on-photo);}
.page-hero--cover .breadcrumb{color:rgba(241,239,232,.92);}
.page-hero--cover .breadcrumb a{color:rgba(241,239,232,.92);}
.page-hero--cover .breadcrumb a:hover{color:#fff;}
@media (max-width:700px){
  .page-hero--cover{min-height:min(46svh,400px);}
  .page-hero--cover::before{
    background:linear-gradient(178deg,rgba(7,34,15,.80) 0%,rgba(7,34,15,.76) 40%,rgba(7,34,15,.94) 100%);
  }
}
@supports not (height:1svh){
  @media (max-width:700px){ .page-hero--cover{min-height:min(46vh,400px);} }
}

/* Photographic variant — a band of image beneath the title block */
.page-hero--photo{border-bottom:none;padding-bottom:0;}
.page-hero--photo::after{display:none;}
.page-hero--photo .page-hero-media{
  margin-top:clamp(40px,5vw,72px);
  height:clamp(220px,32vw,430px);overflow:hidden;
  border-radius:var(--radius-lg) var(--radius-lg) 0 0;
}
.page-hero--photo .page-hero-media img{
  width:100%;height:100%;object-fit:cover;
  animation:mediaIn 1.1s var(--ease-out) both;animation-delay:.3s;
}

.breadcrumb{
  font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:.06em;
  color:var(--sage);margin-bottom:var(--sp-4);text-transform:uppercase;
}
.breadcrumb a{text-decoration:none;color:var(--sage);transition:color var(--dur-fast) ease;}
.breadcrumb a:hover{color:var(--pine-dark);}

@keyframes heroUp{from{opacity:0;transform:translateY(22px);}to{opacity:1;transform:translateY(0);}}
@keyframes mediaIn{from{opacity:0;transform:scale(1.04);}to{opacity:1;transform:scale(1);}}
@keyframes lineDraw{from{transform:scaleX(0);}to{transform:scaleX(1);}}
@keyframes fadeUp{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:translateY(0);}}

/* ---------- Scroll reveal ----------
   Driven by a `data-reveal` attribute so markup declares its own
   entrance and the script only has to flip one class. */
[data-reveal]{
  opacity:0;
  transition:opacity .8s var(--ease-out),transform .8s var(--ease-out);
  will-change:opacity,transform;
}
[data-reveal="up"]{transform:translateY(30px);}
[data-reveal="fade"]{transform:none;}
[data-reveal="left"]{transform:translateX(-26px);}
[data-reveal="right"]{transform:translateX(26px);}
[data-reveal="scale"]{transform:scale(.97);}
[data-reveal].is-revealed{opacity:1;transform:none;will-change:auto;}

/* Reveals are opacity:0 until the script flips `.is-revealed`. If the
   script never runs — blocked, failed, or disabled — the page must still
   show its content rather than render blank. The inline snippet in <head>
   swaps `no-js` for `js` before this file is parsed. */
.no-js [data-reveal]{opacity:1 !important;transform:none !important;}

/* The ±26px horizontal entrance is a wide-screen flourish. On a phone the
   container already spans the gutter, so the pre-reveal offset pushes past
   the viewport edge and widens the document. Rise instead. */
@media (max-width:900px){
  [data-reveal="left"],[data-reveal="right"]{transform:translateY(30px);}
}

/* Curtain wipe for imagery — the picture is uncovered rather than
   faded, which reads as deliberate rather than as a slow load. */
[data-reveal="mask"]{
  opacity:1;clip-path:inset(0 0 100% 0);
  transition:clip-path 1.1s var(--ease-out);
}
[data-reveal="mask"].is-revealed{clip-path:inset(0 0 0 0);}
/* The plate drifts back to rest under the wipe, so the two motions
   resolve together instead of the image sitting dead behind it. */
[data-reveal="mask"] img{
  transform:scale(1.08);transition:transform 1.4s var(--ease-out);
}
[data-reveal="mask"].is-revealed img{transform:scale(1);}

/* A rule that draws itself across as its section arrives */
[data-reveal="rule"]{
  opacity:1;transform:scaleX(0);transform-origin:left;
  transition:transform 1.1s var(--ease-out);
}
[data-reveal="rule"].is-revealed{transform:scaleX(1);}

/* ---------- Headline word stagger ----------
   JS wraps each word so the line can rise out of its own mask.
   `is-split` cancels the block-level entrance the heading would
   otherwise run, so the two don't fight. */
.is-split{animation:none !important;opacity:1 !important;}
.split-word{
  display:inline-block;overflow:hidden;vertical-align:bottom;
  padding-bottom:.06em;margin-bottom:-.06em;
}
.split-word > i{
  display:inline-block;font-style:inherit;
  transform:translateY(110%);
  /* Tightened from .95s. Each word is clipped by its own mask while it
     rises, so the longer this runs the longer a headline sits in a
     half-drawn state — which is what reads as a glitch on arrival,
     especially when a page transition is playing at the same time. */
  animation:wordRise .6s var(--ease-out) both;
}
@keyframes wordRise{from{transform:translateY(110%);}to{transform:translateY(0);}}

/* ---------- Scroll progress ----------
   A hairline under the header showing position through the page. */
.scroll-progress{
  position:absolute;left:0;bottom:-1px;height:2px;width:100%;
  background:var(--brass);transform:scaleX(0);transform-origin:left;
  pointer-events:none;z-index:2;
}

/* ---------- Section rule ---------- */
.rule{height:1px;background:var(--line);border:0;margin:0;}
.section--dark .rule,.hero .rule{background:var(--line-on-dark);}

/* Legacy hook, kept so any page not yet migrated still animates */
.reveal{opacity:0;transform:translateY(20px);transition:opacity .65s var(--ease),transform .65s var(--ease);}
.reveal-visible{opacity:1;transform:translateY(0);}

/* ---------- Grids ---------- */
.grid-3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));}
.grid-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-8);}
.grid-halves{grid-template-columns:minmax(0,1fr) minmax(0,1fr);}
/* Editorial split: a wide column of substance beside a narrower rail */
.grid-split{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.82fr);
  gap:clamp(40px,5vw,92px);align-items:start;
}
@media (max-width:900px){
  .grid-3.card-row,.grid-halves.card-row{grid-template-columns:1fr;}
  .grid-2,.grid-split{grid-template-columns:1fr;gap:var(--sp-7);}
}

/* Hairline-joined row of cards */
.card-row{
  gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--radius-md);overflow:hidden;
}

/* Cards inside a ledger row must not lift — a transform would open a
   grey seam where the cell used to sit. They shift ground instead. */
.card{
  background:var(--raised);padding:var(--sp-6) var(--sp-5);position:relative;
  display:flex;flex-direction:column;align-items:flex-start;height:100%;
  transition:background var(--dur) var(--ease);
}
.card::before{
  content:"";position:absolute;left:0;top:var(--sp-6);width:2px;height:0;
  background:var(--brass);transition:height var(--dur-slow) var(--ease);
}
.card:hover{background:var(--pine-wash-soft);}
.card:hover::before{height:26px;}
.card h3{margin-bottom:var(--sp-3);}
.card p{font-size:15px;color:var(--sage);line-height:1.68;margin-bottom:var(--sp-5);}
.card p:last-child{margin-bottom:0;}
.card .btn-arrow{margin-top:auto;}

/* A card wrapped in a link — keep the whole cell clickable */
.card-link{display:block;text-decoration:none;color:inherit;height:100%;}
.card-link:focus-visible{outline-offset:-3px;}

.card-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-6);}
.card-grid--2{grid-template-columns:repeat(2,minmax(0,1fr));}
@media (max-width:900px){ .card-grid{grid-template-columns:repeat(2,minmax(0,1fr));} }
@media (max-width:700px){ .card-grid--2{grid-template-columns:1fr;} }
@media (max-width:640px){ .card-grid{grid-template-columns:1fr;} }

/* ---------- Media card ----------
   Image flush on top, tinted body beneath. The image scales
   very slightly on hover; the title picks up its underline.
   The card is a link, so everything inside is presentational. */
.media-card{
  display:flex;flex-direction:column;text-decoration:none;color:inherit;
  background:var(--ground-sunk);border-radius:var(--radius-lg);overflow:hidden;
  height:100%;
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
}
.media-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-md);}
.media-card:focus-visible{outline-offset:2px;}
.section--tint .media-card{background:var(--ground-deep);}
.section--dark .media-card{background:rgba(255,255,255,.055);}

.media-card-img{
  aspect-ratio:3/2;overflow:hidden;background:var(--pine-wash);flex:none;
}
.media-card-img img{
  width:100%;height:100%;object-fit:cover;
  transition:transform .7s var(--ease-out);
}
.media-card:hover .media-card-img img{transform:scale(1.05);}

.media-card-body{
  padding:var(--sp-6) var(--sp-5) var(--sp-6);
  display:flex;flex-direction:column;gap:var(--sp-3);flex:1;
}
.media-card-body :is(h2,h3){
  font-size:var(--t-xl);letter-spacing:-.02em;
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1.5px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size var(--dur-slow) var(--ease);
  display:inline;
}
.media-card:hover .media-card-body :is(h2,h3){background-size:100% 1.5px;}
.media-card-body p{font-size:15px;color:var(--sage);line-height:1.68;}
.section--dark .media-card-body p{color:var(--paper-on-dark-soft);}
.media-card-body .arrow-cta{margin-top:auto;padding-top:var(--sp-4);}
.media-card-body .eyebrow{margin-bottom:0;}

/* A media card laid on its side, for a featured item */
.media-card--wide{
  display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);align-items:stretch;
}
.media-card--wide .media-card-img{aspect-ratio:auto;height:100%;min-height:280px;}
.media-card--wide .media-card-body{padding:clamp(28px,3.4vw,52px);justify-content:center;}
.media-card--wide .media-card-body :is(h2,h3){font-size:var(--t-2xl);letter-spacing:var(--track-2xl);}
@media (max-width:820px){
  .media-card--wide{grid-template-columns:1fr;}
  .media-card--wide .media-card-img{aspect-ratio:16/9;min-height:0;}
}

/* ---------- Figure ----------
   A standalone image with an optional caption, for the places a
   picture is illustration rather than a link target. */
/* The reveal zooms the image to scale(1.08); without clipping, that
   overhang widens the document on narrow screens. */
.figure{margin:0;overflow:hidden;}
.figure img{
  width:100%;height:100%;object-fit:cover;
  border-radius:var(--radius-lg);background:var(--pine-wash);
}
.figure figcaption{
  font-family:var(--font-mono);font-size:var(--t-xs);color:var(--sage);
  line-height:1.55;margin-top:var(--sp-3);letter-spacing:.02em;
  padding-left:12px;border-left:1px solid var(--line-strong);
}
.section--dark .figure figcaption{color:var(--paper-on-dark-faint);border-left-color:var(--line-on-dark);}
.figure--portrait img{aspect-ratio:4/5;}
.figure--wide img{aspect-ratio:16/9;}
.figure--square img{aspect-ratio:1;}
/* A tall portrait beside a short text column leaves the column
   stranded; capping it keeps the pair balanced. */
@media (max-width:900px){
  .figure--portrait img{aspect-ratio:16/10;}
}

/* ---------- Editorial row ----------
   Hairline-separated list entry: title and dek on the left,
   a small plate on the right. */
.editorial-list{border-top:1px solid var(--line);}
.section--dark .editorial-list{border-color:var(--line-on-dark);}
.editorial-row{
  display:grid;grid-template-columns:minmax(0,1fr) 210px;
  gap:var(--sp-6) var(--sp-7);align-items:start;
  padding:clamp(28px,3.4vw,44px) 18px;margin:0 -18px;
  border-bottom:1px solid var(--line);
  text-decoration:none;color:inherit;
  transition:background var(--dur) var(--ease);
}
.section--dark .editorial-row{border-color:var(--line-on-dark);}
.editorial-row:hover{background:var(--pine-wash-soft);}
.section--dark .editorial-row:hover{background:rgba(255,255,255,.04);}
.editorial-row .ed-index{
  font-family:var(--font-mono);font-size:var(--t-xs);color:var(--brass-ink);
  letter-spacing:.1em;text-transform:uppercase;margin-bottom:var(--sp-3);
}
.editorial-row h3{
  font-size:var(--t-2xl);max-width:20ch;letter-spacing:var(--track-2xl);
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1.5px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size var(--dur-slow) var(--ease);
  display:inline;
}
.editorial-row:hover h3{background-size:100% 1.5px;}
.editorial-row .ed-dek{
  font-size:var(--t-md);color:var(--ink-soft);line-height:1.7;
  max-width:62ch;margin-top:var(--sp-4);
}
.section--dark .editorial-row .ed-dek{color:var(--paper-on-dark-soft);}
.editorial-row .ed-meta{
  font-family:var(--font-mono);font-size:var(--t-xs);color:var(--sage);
  letter-spacing:.05em;margin-top:var(--sp-4);
  display:flex;flex-wrap:wrap;gap:8px 18px;
}
.editorial-row .ed-media{
  aspect-ratio:4/3;overflow:hidden;border-radius:var(--radius-md);
  background:var(--pine-wash);
}
.editorial-row .ed-media img{
  width:100%;height:100%;object-fit:cover;
  transition:transform .7s var(--ease-out);
}
.editorial-row:hover .ed-media img{transform:scale(1.06);}
.editorial-row .badge{margin-top:var(--sp-4);}
/* Indexed variant — a numeral tile leads the row */
.editorial-row--numbered{grid-template-columns:auto minmax(0,1fr) 210px;}
.editorial-row--numbered .badge-num{margin-top:4px;}
.editorial-row:hover .badge-num{background:var(--pine);color:#fff;}

@media (max-width:900px){
  .editorial-row{grid-template-columns:minmax(0,1fr) 150px;gap:var(--sp-5);}
  .editorial-row--numbered{grid-template-columns:auto minmax(0,1fr);}
  .editorial-row--numbered .ed-media{grid-column:1 / -1;aspect-ratio:16/9;}
}
@media (max-width:600px){
  .editorial-row,.editorial-row--numbered{grid-template-columns:1fr;gap:var(--sp-4);}
  .editorial-row .ed-media{aspect-ratio:16/9;order:-1;}
  .editorial-row--numbered .ed-media{order:-1;}
  .editorial-row h3{max-width:none;}
}

/* ---------- Publication entries ----------
   Not legacy, despite the label this block carried until now: these styles
   render the six entries on research-publications.html. Verified against
   the built output before the comment was corrected. */
.pub-list{border-top:1px solid var(--line);}
.pub-entry{
  display:grid;grid-template-columns:130px minmax(0,1fr) auto;gap:var(--sp-5);
  padding:var(--sp-6) var(--sp-4) var(--sp-6) 18px;margin:0 -18px;
  border-bottom:1px solid var(--line);border-left:2px solid transparent;
  align-items:start;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.pub-entry:hover{background:var(--pine-wash-soft);border-left-color:var(--brass);}
.pub-entry .pub-date{
  font-family:var(--font-mono);font-size:var(--t-xs);color:var(--sage);
  padding-top:5px;letter-spacing:.06em;text-transform:uppercase;
}
.pub-entry h3{font-size:var(--t-xl);margin-bottom:8px;transition:color var(--dur-fast) ease;}
.pub-entry:hover h3{color:var(--pine-dark);}
.pub-entry .pub-meta{font-size:13.5px;color:var(--sage);margin-bottom:12px;}
.pub-entry .pub-abstract{font-size:15.5px;color:var(--ink-soft);line-height:1.7;max-width:66ch;}
.pub-entry .pub-tag{
  font-family:var(--font-mono);font-size:var(--t-2xs);text-transform:uppercase;
  letter-spacing:.08em;color:var(--pine-dark);background:var(--pine-wash);
  padding:5px 11px;border-radius:100px;white-space:nowrap;height:fit-content;
}
@media (max-width:760px){
  .pub-entry{grid-template-columns:1fr;gap:var(--sp-2);}
  .pub-entry .pub-tag{justify-self:start;margin-top:var(--sp-3);}
}


/* ---------- Status + project ---------- */
.status-pill{
  font-family:var(--font-mono);font-size:var(--t-2xs);letter-spacing:.07em;
  text-transform:uppercase;padding:6px 12px;border-radius:100px;
  display:inline-flex;align-items:center;gap:7px;white-space:nowrap;font-weight:500;
}
.status-pill.ongoing{background:var(--state-active-bg);color:var(--state-active-text);}
.status-pill.completed{background:var(--state-done-bg);color:var(--state-done-text);}
.status-pill .dot{width:5px;height:5px;border-radius:50%;background:currentColor;flex:none;}
.status-pill.ongoing .dot{animation:pulseDot 2.2s ease-in-out infinite;}
@keyframes pulseDot{0%,100%{opacity:1;}50%{opacity:.3;}}

.project-card{
  background:var(--raised);border:1px solid var(--line);border-radius:var(--radius-lg);
  padding:var(--sp-6) var(--sp-5);
  transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}
.project-card:hover{border-color:var(--line-strong);box-shadow:var(--shadow-md);transform:translateY(-3px);}
.project-card .proj-top{
  display:flex;justify-content:space-between;align-items:flex-start;
  margin-bottom:var(--sp-4);gap:var(--sp-4);flex-wrap:wrap;
}
.project-card h3{font-size:var(--t-lg);}
.project-card p{font-size:15px;color:var(--sage);line-height:1.68;margin-bottom:var(--sp-5);}
.project-card .proj-meta{
  font-family:var(--font-mono);font-size:var(--t-xs);color:var(--sage);
  display:flex;gap:var(--sp-5);border-top:1px solid var(--line);padding-top:var(--sp-4);
  flex-wrap:wrap;letter-spacing:.04em;
}

/* ---------- Event ---------- */
.event-card{
  display:grid;grid-template-columns:88px minmax(0,1fr);gap:var(--sp-5);
  padding:var(--sp-5) var(--sp-4) var(--sp-5) 18px;margin:0 -18px;
  border-bottom:1px solid var(--line);border-left:2px solid transparent;align-items:center;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.event-card:hover{background:var(--pine-wash-soft);border-left-color:var(--brass);}
.event-date{
  background:var(--pine-wash);border-radius:var(--radius-md);text-align:center;
  padding:var(--sp-3) 0;
}
.event-date .day{
  font-family:var(--font-serif);font-size:28px;font-weight:500;
  color:var(--pine-dark);line-height:1;font-variant-numeric:tabular-nums;
}
.event-date .mon{
  font-family:var(--font-mono);font-size:var(--t-2xs);letter-spacing:.1em;
  color:var(--sage);text-transform:uppercase;margin-top:5px;
}
.event-card h3{font-size:var(--t-lg);margin-bottom:6px;}
.event-card .event-meta{font-size:13.5px;color:var(--sage);}
.event-card.is-past{opacity:.62;}
.event-card.is-past .event-date{background:var(--state-done-bg);}
.event-card.is-past .day,.event-card.is-past .mon{color:var(--sage);}
.event-card.is-past:hover{opacity:.9;}

/* ---------- Tabs ---------- */
.tab-row{
  display:flex;gap:var(--sp-6);margin-bottom:var(--sp-6);
  border-bottom:1px solid var(--line);
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
}
.tab-row::-webkit-scrollbar{display:none;}
.tab-btn{
  background:none;border:none;font-family:var(--font-mono);font-size:var(--t-xs);
  font-weight:500;letter-spacing:.1em;text-transform:uppercase;
  color:var(--sage);padding:14px 2px;cursor:pointer;white-space:nowrap;
  border-bottom:1.5px solid transparent;position:relative;top:1px;
  transition:color var(--dur) ease,border-color var(--dur) ease;
}
.tab-btn:hover{color:var(--pine-dark);}
.tab-btn[aria-selected="true"]{color:var(--pine-dark);border-bottom-color:var(--brass);}
.tab-panel{display:none;}
.tab-panel.is-active{display:block;}
.tab-panel:focus{outline:none;}

/* ---------- People ---------- */
.people-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-6) var(--sp-5);}
@media (max-width:900px){ .people-grid{grid-template-columns:repeat(3,minmax(0,1fr));} }
@media (max-width:620px){ .people-grid{grid-template-columns:1fr 1fr;gap:var(--sp-5) var(--sp-4);} }
.people-card{text-align:left;}
.people-avatar{
  aspect-ratio:1;background:var(--pine-wash);border-radius:var(--radius-md);
  margin-bottom:var(--sp-4);display:flex;align-items:center;justify-content:center;
  color:var(--pine-mid);font-family:var(--font-serif);font-size:28px;font-weight:500;
  letter-spacing:.04em;position:relative;overflow:hidden;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease);
}
.people-avatar img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform .7s var(--ease-out);
}
.people-card:hover .people-avatar img{transform:scale(1.06);}
.people-avatar::after{
  content:"";position:absolute;inset:0;
  background:url('../img/topo-lines-dark.svg') center/cover no-repeat;
  opacity:0;transition:opacity var(--dur) var(--ease);
}
.people-avatar > span{position:relative;z-index:1;}
.people-card:hover .people-avatar{background:var(--pine);color:#fff;}
.people-card:hover .people-avatar::after{opacity:.3;}
.people-card .p-name{font-size:16px;font-weight:600;line-height:1.4;}
.people-card .p-role{
  font-family:var(--font-mono);font-size:var(--t-2xs);color:var(--sage);
  margin-top:5px;letter-spacing:.05em;text-transform:uppercase;
}

/* ---------- Statistics ---------- */
.stat-grid{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:var(--radius-md);
  overflow:hidden;margin-bottom:var(--sp-8);
}
@media (max-width:820px){ .stat-grid{grid-template-columns:1fr 1fr;} }
@media (max-width:440px){ .stat-grid{grid-template-columns:1fr;} }
.stat-card{
  background:var(--raised);padding:var(--sp-5);
  transition:background var(--dur) var(--ease);
}
.stat-card:hover{background:var(--pine-wash-soft);}
.stat-card .stat-num{
  font-family:var(--font-serif);font-size:44px;font-weight:400;color:var(--pine-dark);
  line-height:1;font-variant-numeric:tabular-nums;letter-spacing:-.025em;
}
.stat-card .stat-label{font-size:13.5px;color:var(--sage);margin-top:var(--sp-3);line-height:1.55;}

/* Badge-tile stat row — the sticker treatment */
.stat-badges{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-4);}
@media (max-width:900px){ .stat-badges{grid-template-columns:1fr 1fr;} }
@media (max-width:480px){ .stat-badges{grid-template-columns:1fr;} }

.chart-block{
  background:var(--raised);border:1px solid var(--line);border-radius:var(--radius-lg);
  padding:var(--sp-6);margin-bottom:var(--sp-5);
}
.chart-block h3{font-size:var(--t-lg);margin-bottom:var(--sp-5);}
.bar-row{
  display:grid;grid-template-columns:190px minmax(0,1fr) 82px;align-items:center;
  gap:var(--sp-4);margin-bottom:var(--sp-4);
}
.bar-row .bar-label{font-size:14px;color:var(--ink-soft);line-height:1.45;}
.bar-track{background:var(--ground-sunk);border-radius:100px;height:10px;overflow:hidden;}
.bar-fill{
  background:var(--pine);height:100%;border-radius:100px;
  transition:width 1.1s var(--ease-out);
}
.bar-fill.is-muted{background:var(--sage-light);}
.bar-row .bar-value{
  text-align:right;font-family:var(--font-mono);font-size:var(--t-xs);color:var(--ink);
  font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:500;
}
/* Stacking the label above the bar beats squeezing a 190px column
   into a 320px screen. */
@media (max-width:640px){
  .bar-row{grid-template-columns:minmax(0,1fr) auto;gap:var(--sp-2) var(--sp-4);}
  .bar-row .bar-label{grid-column:1;grid-row:1;}
  .bar-row .bar-value{grid-column:2;grid-row:1;}
  .bar-track{grid-column:1 / -1;grid-row:2;}
}

/* ---------- Quote block ----------
   An oversized glyph sets the quotation off without a rule or a
   box. The glyph is decorative, so it is hidden from readers. */
.quote-block{
  position:relative;margin:0;max-width:24ch;
  padding-top:clamp(44px,5vw,72px);
}
.quote-block::before{
  content:"\201C";position:absolute;left:-.06em;top:0;
  font-family:var(--font-serif);font-size:clamp(110px,13vw,190px);line-height:.78;
  color:var(--brass);opacity:.22;pointer-events:none;
}
.quote-block .q-text{
  font-family:var(--font-serif);font-size:var(--t-2xl);line-height:1.24;
  letter-spacing:-.02em;font-weight:400;color:var(--ink);position:relative;
}
.section--dark .quote-block .q-text,.section--brand .quote-block .q-text{color:var(--ground);}
.quote-block cite{
  display:block;font-family:var(--font-mono);font-style:normal;font-size:var(--t-2xs);
  color:var(--sage);margin-top:var(--sp-6);text-transform:uppercase;letter-spacing:.12em;
}
.section--dark .quote-block cite{color:var(--brass-pale);}
.quote-block--wide{max-width:34ch;}
@media (max-width:700px){ .quote-block{max-width:none;} }

/* Legacy pull quote */
.pull-quote{
  font-family:var(--font-serif);font-size:var(--t-xl);line-height:1.4;color:var(--ink);
  max-width:34ch;padding-left:var(--sp-6);position:relative;margin:0;
  font-weight:400;letter-spacing:-.015em;
}
.pull-quote::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:1.5px;background:var(--brass);
  transform:scaleY(0);transform-origin:top;transition:transform .9s var(--ease-out);
}
.pull-quote.reveal-visible::before,.pull-quote.is-revealed::before{transform:scaleY(1);}
.pull-quote cite{
  display:block;font-family:var(--font-mono);font-style:normal;font-size:var(--t-2xs);
  color:var(--sage);margin-top:var(--sp-5);text-transform:uppercase;letter-spacing:.1em;
}
@media (max-width:700px){ .pull-quote{font-size:var(--t-lg);max-width:none;} }

/* ---------- Values list (dark) ---------- */
.value-list{border-top:1px solid var(--line-on-dark);}
.value-item{
  display:grid;grid-template-columns:74px minmax(0,1fr);gap:var(--sp-5);
  padding:var(--sp-6) 18px;margin:0 -18px;
  border-bottom:1px solid var(--line-on-dark);border-left:2px solid transparent;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.value-item:hover{background:rgba(255,255,255,.04);border-left-color:var(--brass);}
.value-item .v-idx{
  font-family:var(--font-mono);font-size:var(--t-xs);color:var(--brass-pale);
  padding-top:6px;letter-spacing:.06em;
}
.value-item h3{font-size:var(--t-lg);color:var(--ground);margin-bottom:8px;}
.value-item p{font-size:15.5px;color:var(--paper-on-dark-soft);line-height:1.68;max-width:66ch;}
@media (max-width:560px){
  .value-item{grid-template-columns:1fr;gap:var(--sp-2);}
}

/* ---------- Step list ---------- */
.step-list{position:relative;border-top:1px solid var(--line);}
.step-item{
  display:grid;grid-template-columns:56px minmax(0,1fr);gap:var(--sp-5);
  padding:var(--sp-6) 0;border-bottom:1px solid var(--line);position:relative;
}
.step-item .s-num{
  font-family:var(--font-mono);font-size:var(--t-xs);font-weight:500;color:var(--brass-ink);
  padding-top:6px;letter-spacing:.06em;font-variant-numeric:tabular-nums;
}
.step-item h3{font-size:var(--t-lg);margin-bottom:8px;}
.step-item p{font-size:15.5px;color:var(--sage);line-height:1.68;max-width:70ch;}
.section--tint .step-list,.section--tint .step-item{border-color:var(--line-strong);}
@media (max-width:560px){
  .step-item{grid-template-columns:1fr;gap:var(--sp-2);}
}

/* ---------- Criteria ---------- */
.criteria-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 var(--sp-7);}
@media (max-width:760px){ .criteria-grid{grid-template-columns:1fr;} }
.criteria-item{
  display:flex;gap:14px;align-items:flex-start;padding:var(--sp-4) 12px;margin:0 -12px;
  border-bottom:1px solid var(--line);font-size:15px;line-height:1.6;
  transition:background var(--dur) var(--ease);
}
.criteria-item:hover{background:var(--pine-wash-soft);}
.criteria-item .chk{
  flex:none;width:20px;height:20px;border-radius:50%;background:var(--pine-wash);
  color:var(--pine-dark);display:flex;align-items:center;justify-content:center;
  font-size:10px;margin-top:3px;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease);
}
.criteria-item:hover .chk{background:var(--pine);color:#fff;}

/* ---------- Forms ---------- */
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 var(--sp-5);}
@media (max-width:700px){ .form-grid{grid-template-columns:1fr;} }
.field{display:flex;flex-direction:column;gap:7px;margin-bottom:var(--sp-5);}
.field.full{grid-column:1 / -1;}
.field label{font-size:13.5px;font-weight:600;color:var(--ink);letter-spacing:.01em;}
.field input,.field select,.field textarea{
  font-family:var(--font-sans);font-size:16px;padding:13px 14px;
  border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  background:var(--raised);color:var(--ink);width:100%;
  transition:border-color var(--dur-fast) ease,box-shadow var(--dur-fast) ease;
}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--pine);box-shadow:0 0 0 3px var(--pine-wash);
}
.field input[aria-invalid="true"],.field textarea[aria-invalid="true"]{border-color:var(--danger);}
.field input[aria-invalid="true"]:focus,.field textarea[aria-invalid="true"]:focus{
  box-shadow:0 0 0 3px #F6EAE7;
}
.field .field-error{font-size:12.5px;color:var(--danger);min-height:0;}
.field textarea{resize:vertical;min-height:130px;}
.form-note{font-size:13.5px;color:var(--sage);margin-top:var(--sp-2);line-height:1.6;}
.form-status{
  font-size:14.5px;margin-top:var(--sp-4);padding:13px 15px;border-radius:var(--radius-sm);
  border-left:2px solid var(--brass);background:var(--pine-wash-soft);color:var(--ink-soft);
}
.form-status:empty{display:none;}
.form-status:focus{outline:none;}
.field-error:empty{display:none;}

/* Without the script there is nothing to intercept the submit, and the
   form has no action — so it would silently GET this same page and look
   like it did nothing. Point people at email and take the button away. */
.form-noscript{
  font-size:14.5px;margin-top:var(--sp-4);padding:13px 15px;border-radius:var(--radius-sm);
  border-left:2px solid var(--brass);background:var(--pine-wash-soft);color:var(--ink-soft);
}
.form-noscript a{color:var(--pine-dark);}
.no-js form[data-contact-form] button[type="submit"]{display:none;}

/* ---------- Contact ---------- */
.contact-grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
  gap:clamp(40px,5vw,88px);align-items:start;
}
@media (max-width:860px){ .contact-grid{grid-template-columns:1fr;gap:var(--sp-7);} }
.contact-item{
  padding:var(--sp-5) 12px;margin:0 -12px;
  border-bottom:1px solid var(--line);transition:background var(--dur) var(--ease);
}
.contact-item:hover{background:var(--pine-wash-soft);}
.contact-item .c-label{
  font-family:var(--font-mono);font-size:var(--t-2xs);text-transform:uppercase;
  letter-spacing:.1em;color:var(--brass);margin-bottom:8px;font-weight:500;
}
.contact-item .c-value{font-size:var(--t-md);line-height:1.5;}

/* ---------- Prose ---------- */
.prose{max-width:66ch;}
.prose p{font-size:var(--t-md);line-height:1.78;color:var(--ink-soft);margin-bottom:var(--sp-5);}
.prose p:last-child{margin-bottom:0;}
.prose em{font-style:italic;color:var(--ink);}
.prose a{color:var(--pine-dark);}
/* Opening paragraph of a long read, set larger */
.prose--lead p:first-child{font-size:var(--t-lg);line-height:1.6;color:var(--ink);}

/* ---------- Full-bleed band ----------
   Breaks a section out of the container for an edge-to-edge
   image or colour field. */
.full-bleed{
  position:relative;overflow:hidden;
  min-height:clamp(340px,42vw,520px);
  display:flex;align-items:center;
  background:var(--pine-deep);color:var(--ground);isolation:isolate;
}
.full-bleed-media{position:absolute;inset:0;z-index:-2;overflow:hidden;}
.full-bleed-media img{width:100%;height:100%;object-fit:cover;}
.full-bleed::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(92deg,rgba(7,34,15,.96) 0%,rgba(7,34,15,.89) 46%,rgba(7,34,15,.62) 100%);
}
.full-bleed > .container{position:relative;z-index:1;width:100%;
  padding-top:var(--sp-section-tight);padding-bottom:var(--sp-section-tight);}
.full-bleed h2{font-size:var(--t-3xl);max-width:18ch;color:#FCFDFA;letter-spacing:var(--track-3xl);}
.full-bleed .lede{
  font-size:var(--t-md);max-width:54ch;line-height:1.68;
  color:rgba(241,239,232,.85);margin-top:var(--sp-5);
}
.full-bleed .actions{display:flex;flex-wrap:wrap;gap:16px 26px;align-items:center;margin-top:var(--sp-6);}
.full-bleed .arrow-cta-icon{background:var(--ground);color:var(--ink);}
.full-bleed .arrow-cta:hover .arrow-cta-icon{background:#fff;}
.full-bleed .eyebrow{color:var(--brass-on-photo);}
@media (max-width:700px){
  .full-bleed::before{
    background:linear-gradient(178deg,rgba(7,34,15,.78) 0%,rgba(7,34,15,.86) 100%);
  }
  .full-bleed .actions .btn{width:100%;}
}

/* ---------- Footer ---------- */
.site-footer{background:var(--ink);color:#B6BEB4;padding-top:var(--sp-8);}
.foot-top{
  display:flex;justify-content:space-between;padding-bottom:var(--sp-7);
  border-bottom:1px solid var(--line-on-dark);flex-wrap:wrap;gap:var(--sp-7);
}
.foot-brand{display:flex;align-items:center;gap:12px;}
.foot-brand img{height:34px;width:34px;}
.foot-brand span{font-family:var(--font-serif);color:#fff;font-size:20px;font-weight:500;}
.foot-tag{font-size:14px;color:#858E82;max-width:34ch;margin-top:var(--sp-4);line-height:1.64;}
.foot-links{display:flex;gap:var(--sp-8);flex-wrap:wrap;}
.foot-col span{
  display:block;font-family:var(--font-mono);font-size:var(--t-2xs);letter-spacing:.13em;
  color:var(--brass-pale);margin-bottom:var(--sp-4);text-transform:uppercase;
}
.foot-col a{padding:3px 0;
  display:block;color:#B6BEB4;text-decoration:none;margin-top:10px;font-size:14px;
  transition:color var(--dur-fast) ease;width:fit-content;
}
.foot-col a:hover{color:#fff;}
.foot-bottom{
  display:flex;justify-content:space-between;padding:var(--sp-5) 0
    calc(var(--sp-5) + env(safe-area-inset-bottom));
  font-size:var(--t-xs);color:#828B80;font-family:var(--font-mono);
  flex-wrap:wrap;gap:10px;letter-spacing:.03em;
}
.foot-socials{display:flex;gap:18px;}
.foot-socials a{color:#858E82;text-decoration:none;display:inline-flex;align-items:center;min-height:24px;padding:2px 0;transition:color var(--dur-fast) ease;}
.foot-socials a:hover{color:#fff;}
@media (max-width:700px){
  .foot-top{flex-direction:column;gap:var(--sp-6);}
  .foot-links{gap:var(--sp-6) var(--sp-7);}
}

/* ---------- Small-screen pass ----------
   Everything above is written mobile-safe; this block is for the
   handful of places where a desktop proportion has to be undone
   rather than merely narrowed. */
@media (max-width:600px){
  h2.section-title,h2.section-title--wide{max-width:none;}
  .media-card-body{padding:var(--sp-5) var(--sp-5) var(--sp-6);}
  .arrow-cta{font-size:15px;}
  .arrow-cta-icon{width:42px;height:42px;}
  .badge-num{width:48px;height:48px;font-size:22px;}
  /* Rows that hang into the gutter with negative margins would
     otherwise push a scrollbar onto the page at this width. */
  .pub-entry,.event-card,.editorial-row,.value-item{
    padding-left:0;padding-right:0;margin-left:0;margin-right:0;
  }
  .pub-entry,.value-item{border-left:none;}
  .contact-item,.criteria-item{padding-left:0;padding-right:0;margin-left:0;margin-right:0;}
  .chart-block{padding:var(--sp-5) var(--sp-4);}
  .stat-badge{padding:var(--sp-5);}
}
@media (max-width:380px){
  .brand-word{font-size:19px;}
  .brand img{height:34px;width:34px;}
  .nav-mobile-link{font-size:20px;}
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  .reveal{opacity:1;transform:none;}
  [data-reveal]{opacity:1;transform:none;}
}

/* ---------- Utilities ----------
   A small, closed set backing the handful of one-off overrides that used
   to live in `style` attributes. Naming is by rendered pixel value so a
   value in a mockup maps straight to a class; the token is used wherever
   the scale already has one. Prefer a component class where one fits —
   extend this block only when a page genuinely needs a one-off. */
.u-mt-8{margin-top:var(--sp-2);}
.u-mt-16{margin-top:var(--sp-4);}
.u-mt-24{margin-top:var(--sp-5);}
.u-mt-32{margin-top:var(--sp-6);}
.u-mt-40{margin-top:2.5rem;}
.u-mb-8{margin-bottom:var(--sp-2);}
.u-mb-12{margin-bottom:var(--sp-3);}
.u-mb-16{margin-bottom:var(--sp-4);}
.u-mb-24{margin-bottom:var(--sp-5);}
.u-mb-28{margin-bottom:1.75rem;}
.u-mb-32{margin-bottom:var(--sp-6);}
.u-mb-40{margin-bottom:2.5rem;}
.u-mb-48{margin-bottom:var(--sp-7);}
.u-ml-8{margin-left:var(--sp-2);}
.u-mx-auto-24{margin:0 auto var(--sp-5);}
.u-maxw-640{max-width:640px;}
.u-center{text-align:center;}
.u-inherit{color:inherit;}
.u-inherit-underline{color:inherit;text-decoration:underline;}
.u-grid-2{grid-template-columns:1fr 1fr;}

/* ---------- Paper grain ----------
   The concept is a printed record, and a perfectly flat digital surface is
   the one thing that most gives away that it isn't one. A 128px greyscale
   tile is composited over the whole page under `overlay`, where mid-grey is
   the neutral value — so the tile lightens and darkens the ground rather
   than tinting it, and reads correctly over cream and over the dark green
   bands alike.

   Kept deliberately faint: this should register as tooth in the paper, not
   as noise over a photograph. */
.grain{
  position:fixed;inset:0;z-index:9000;pointer-events:none;
  background-image:url('../img/grain.png');
  background-repeat:repeat;
  background-size:128px 128px;
  mix-blend-mode:overlay;
  opacity:.42;
}
/* Screens above the tile size get a slightly coarser sample so the repeat
   doesn't become legible as a grid. */
@media (min-width:1600px){
  .grain{background-size:160px 160px;opacity:.38;}
}
/* Users who ask for reduced transparency get the flat ground. */
@media (prefers-reduced-transparency: reduce){
  .grain{display:none;}
}
/* Printing a texture overlay wastes ink and muddies the type. */
@media print{
  .grain{display:none;}
}

/* ---------- Icons ----------
   The sprite itself never renders; only its <symbol>s do, via <use>. */
.icon-sprite{position:absolute;width:0;height:0;overflow:hidden;}
.icon{
  width:1em;height:1em;display:block;flex:none;
  fill:none;stroke:currentColor;
}

/* ---------- Events ----------
   A dated record rather than a card grid: the date column is the spine, so
   a list of sessions scans like a calendar. Rendered from events data, and
   absent entirely until the admin adds the first one. */
.event-list{list-style:none;margin:0;padding:0;border-top:1px solid var(--line);}
.event-item{
  display:grid;grid-template-columns:minmax(150px,190px) minmax(0,1fr);
  gap:var(--sp-5) var(--sp-6);
  padding:var(--sp-6) 18px var(--sp-6) 18px;margin:0 -18px;
  border-bottom:1px solid var(--line);border-left:2px solid transparent;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.event-item:hover{background:var(--pine-wash-soft);border-left-color:var(--brass);}
.event-when{display:flex;flex-direction:column;gap:4px;padding-top:4px;}
.event-date{
  font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:.06em;
  text-transform:uppercase;color:var(--pine-dark);font-weight:500;
}
.event-time{font-family:var(--font-mono);font-size:var(--t-2xs);color:var(--sage);letter-spacing:.06em;}
.event-body h3{font-size:var(--t-xl);margin-bottom:8px;}
.event-loc{
  font-family:var(--font-mono);font-size:var(--t-2xs);letter-spacing:.08em;
  text-transform:uppercase;color:var(--sage);margin-bottom:10px;
}
.event-summary{font-size:var(--t-base);color:var(--ink-soft);line-height:1.7;max-width:62ch;}
@media (max-width:700px){
  .event-item{grid-template-columns:1fr;gap:var(--sp-3);}
  .event-when{flex-direction:row;gap:12px;align-items:baseline;padding-top:0;}
}

/* ---------- Charts ----------
   The <table> is the content and the bars are a rendering of it. With the
   script running the table stays in the accessibility tree but off-screen,
   because the bars already carry the same numbers visually. With no script
   the bars would all be zero-width, so the table becomes the visible form
   instead. Neither state ever shows a reader an empty track. */
.chart{
  margin:0;padding:var(--sp-6) 0;border-top:1px solid var(--line);
}
.chart:first-of-type{border-top:none;}
.chart-head :is(h2,h3){font-size:var(--t-lg);margin-bottom:var(--sp-5);max-width:30ch;}
.chart-bars{display:flex;flex-direction:column;gap:var(--sp-4);}

.js .chart-table{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}
.no-js .chart-bars{display:none;}
.no-js .chart-table{
  width:100%;border-collapse:collapse;margin-bottom:var(--sp-4);
}
.no-js .chart-table th,.no-js .chart-table td{
  text-align:left;padding:10px 14px 10px 0;border-bottom:1px solid var(--line);
  font-size:var(--t-base);
}
.no-js .chart-table thead th{
  font-family:var(--font-mono);font-size:var(--t-2xs);letter-spacing:.08em;
  text-transform:uppercase;color:var(--sage);font-weight:500;
}
.no-js .chart-table td{font-variant-numeric:tabular-nums;color:var(--ink);}

.chart-note{
  font-size:13.5px;color:var(--sage);line-height:1.6;margin-top:var(--sp-4);max-width:62ch;
}
.chart-source{
  font-family:var(--font-mono);font-size:var(--t-2xs);letter-spacing:.06em;
  color:var(--sage);margin-top:var(--sp-3);
}

/* ---------- Staggered card run ----------
   Replaces the three-equal-column grid. Three identical cards in a row is
   the single most template-looking arrangement available, and it appeared
   on the homepage and the articles page.

   Instead the run is asymmetric on both axes: unequal spans across a
   12-column field, and unequal vertical offsets, so the eye travels down
   the page rather than scanning a rack. Offsets are positive margins only,
   so nothing overlaps and nothing can be pushed outside the container.

   Collapses to a single column well before the offsets would crowd. */
@media (min-width:901px){
  .card-grid--stagger{
    grid-template-columns:repeat(12,minmax(0,1fr));
    gap:var(--sp-6) var(--sp-6);
    align-items:start;
  }
  /* Rows are assigned explicitly. Left to auto-placement, the offset on
     the second card pushed its box past the end of its implicit row while
     the third card started from the row boundary, so the two overlapped by
     roughly 48x32px from 1024px up. Naming the rows makes the second row
     start after the first row's full outer height, margin included. */
  .card-grid--stagger > *:nth-child(1){grid-column:1 / span 7;grid-row:1;}
  .card-grid--stagger > *:nth-child(2){grid-column:8 / span 5;grid-row:1;margin-top:var(--sp-9);}
  .card-grid--stagger > *:nth-child(3){grid-column:2 / span 6;grid-row:2;margin-top:var(--sp-6);}
  /* A fourth item onward falls back to a sensible half-width rhythm. */
  .card-grid--stagger > *:nth-child(n+4){grid-column:span 6;}
}
@media (min-width:641px) and (max-width:900px){
  .card-grid--stagger{grid-template-columns:repeat(2,minmax(0,1fr));}
  .card-grid--stagger > *:nth-child(2){margin-top:var(--sp-7);}
}
@media (max-width:640px){
  .card-grid--stagger{grid-template-columns:1fr;}
  .card-grid--stagger > *{margin-top:0;}
}

/* ---------- Cross-page view transitions ----------
   A 16-page static site navigating between documents is exactly what the
   View Transitions API was built for. The brand mark, the page title and
   the hero image are named, so they persist across a navigation instead of
   the whole page flashing.

   Where the API is unsupported this is inert and navigation is normal.
   Under reduced motion the transition is suppressed below. */
@view-transition{navigation:auto;}

/* Only the brand mark is named.

   Naming an element lifts it out of the page's normal paint order into its
   own transition layer for the duration of the animation. That is exactly
   what broke the hero: the photograph was named, but its scrim is a
   ::before on the parent, so the image floated above its own darkening
   layer and flashed at full brightness mid-navigation, taking the headline
   contrast with it.

   The title was worse. Morphing between two headlines with different text,
   size and position cannot cross-fade cleanly, so it smeared and collided
   with the lede beneath it while the word-rise animation was also running.

   The mark is the one element genuinely identical on every page, so it is
   the only one that can morph without artefacts. Everything else rides the
   root cross-fade, where the scrim stays composited with its photograph. */
.brand img{view-transition-name:brand-mark;}

::view-transition-old(root),::view-transition-new(root){
  animation-duration:.32s;
  animation-timing-function:var(--ease-out);
}
::view-transition-group(brand-mark){
  animation-duration:.42s;
  animation-timing-function:var(--ease-out);
}

@media (prefers-reduced-motion: reduce){
  /* Suppress the whole cross-document transition rather than merely
     shortening it: a cross-fade is still motion. */
  @view-transition{navigation:none;}
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*){animation:none !important;}
}

/* ---------- Weighted interaction ----------
   Hover feedback uses a spring rather than a symmetrical ease, so a card
   feels like it has mass: it overshoots very slightly on the way up and
   settles. Deliberately small numbers. On a research site the cue should
   register as responsiveness, not as an effect. */
:root{
  --spring-out:cubic-bezier(.34,1.42,.44,1);
}
.media-card,.pub-entry,.event-item,.people-card,.toc-row{
  transition:transform var(--dur) var(--spring-out),
             box-shadow var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             background var(--dur) var(--ease);
}
.media-card:hover{transform:translateY(-3px);}
.people-card:hover{transform:translateY(-2px);}
.arrow-cta:hover .arrow-cta-icon,.arrow-cta:focus-visible .arrow-cta-icon{
  transition:background var(--dur) var(--ease),transform var(--dur) var(--spring-out);
}
.btn{transition:background var(--dur) var(--ease),color var(--dur) var(--ease),
     border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),
     transform var(--dur-fast) var(--spring-out);}
.btn:active{transform:translateY(1px);}

/* Event rows pick up the same brass edge the publication list uses, drawn
   rather than switched, so the two dated lists behave identically. */
.event-item{position:relative;}
.event-item::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:var(--brass);transform:scaleY(0);transform-origin:top;
  transition:transform var(--dur) var(--ease-out);
}
.event-item:hover::before{transform:scaleY(1);}
.event-item:hover{border-left-color:transparent;}

@media (prefers-reduced-motion: reduce){
  .media-card:hover,.people-card:hover,.btn:active{transform:none;}
  .event-item::before{display:none;}
}

/* Breadcrumb links are navigation, not prose, so the WCAG 2.2 inline-link
   exception does not cover them and 15px tall is too small to hit reliably.
   The hit area grows with padding and is pulled back with a matching
   negative margin, so nothing about the visual rhythm moves.
   Inline links inside sentences (.c-value a, .prose a and friends) are
   deliberately left alone: they are exempt, and padding them would break
   the line spacing of the paragraph they sit in. */
.breadcrumb a{display:inline-block;padding:5px 3px;margin:-5px -3px;}

/* ---------- Button label roll ----------
   The primary call to action sits on cream over a photograph, so the old
   hover (#F7F5F0 to #FFFFFF) was a ~3% brightness shift and read as no
   response at all.

   Instead the label itself moves. One copy leaves through the top of a mask
   while an identical copy arrives from the bottom, which is the same masked
   rise the display headings already use for `data-split`. Reusing that
   gesture is the point: the button answers in the site's own vocabulary
   rather than borrowing a generic fill or scale.

   The mask is sized by line-height rather than by the glyph box so that
   descenders in labels like "join" and "message" are never clipped. */
.btn-label{
  position:relative;display:block;overflow:hidden;
  line-height:1.5;
}
.btn-label > span{
  display:block;
  transition:transform .5s var(--ease-out),opacity .5s var(--ease-out);
  will-change:transform;
}
.btn-label > span + span{
  position:absolute;left:0;right:0;top:0;
  transform:translateY(105%);
  opacity:0;
}
.btn:hover .btn-label > span,
.btn:focus-visible .btn-label > span{transform:translateY(-105%);opacity:0;}
.btn:hover .btn-label > span + span,
.btn:focus-visible .btn-label > span + span{transform:translateY(0);opacity:1;}

/* The ground turns brass on hover. Brass is the only accent this palette
   carries besides the pine, so it is the one colour that can signal a state
   change without either repeating the brand green or importing something
   foreign. #B08D45 against pine-deep measures 5.42:1, which clears AA for a
   14.5px label with headroom to spare, and the shift away from cream is
   large enough to be unmistakable where the old cream-to-white was not.

   The button also grows very slightly. 2.5% on a 50px control is about a
   pixel of height: enough to register as the control coming forward, small
   enough that nothing around it appears to move. Transform, so no layout
   is disturbed. */
.btn-primary{
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),
    transform .34s var(--spring-out);
}
.hero .btn-primary{box-shadow:0 1px 2px rgba(7,34,15,.14);}
.btn-primary:hover,.btn-primary:focus-visible,
.hero .btn-primary:hover,.hero .btn-primary:focus-visible{
  background:var(--brass-bright);
  color:var(--pine-deep);
  transform:scale(1.025);
}
.hero .btn-primary:hover,.hero .btn-primary:focus-visible{box-shadow:0 12px 28px rgba(7,34,15,.34);}
.btn-primary:hover,.btn-primary:focus-visible{box-shadow:0 10px 22px rgba(7,34,15,.24);}
/* Pressing settles it back towards its resting size. */
.btn-primary:active{transform:scale(1.008);}

@media (prefers-reduced-motion: reduce){
  /* No roll. The second copy is dropped entirely and the ground carries the
     whole state change, so there is still visible feedback. */
  .btn-label > span + span{display:none;}
  .btn:hover .btn-label > span,
  .btn:focus-visible .btn-label > span{transform:none;opacity:1;}
  .btn-primary:hover,.btn-primary:focus-visible,
  .hero .btn-primary:hover,.hero .btn-primary:focus-visible{transform:none;}
}

/* ---------- Imprint plate ----------
   The whole plate is a single link. The address is set larger than the
   description on purpose: on a colophon the address *is* the content, and
   treating it as display type rather than as a link label is what stops
   this reading as a generic promo card.

   Hover is drawn, not switched. The rules either side of the address run
   out from the centre, the arrow steps diagonally, and the ground lifts a
   shade, so the plate behaves like the rest of the site's dated rows. */
.imprint-section{padding:var(--sp-section) 0;}
.imprint{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,auto);
  grid-template-areas:
    "eyebrow eyebrow"
    "name    meta"
    "address address"
    "go      go";
  gap:var(--sp-5) var(--sp-8);
  align-items:end;
  text-decoration:none;color:var(--paper-on-dark);
  padding:clamp(28px,4vw,56px);
  border:1px solid var(--line-on-dark);
  border-radius:var(--radius-lg);
  background:rgba(255,255,255,.02);
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.imprint:hover,.imprint:focus-visible{
  background:rgba(255,255,255,.05);
  border-color:var(--line-on-dark-strong);
}

.imprint-eyebrow{
  grid-area:eyebrow;
  font-family:var(--font-mono);font-size:var(--t-xs);letter-spacing:.16em;
  text-transform:uppercase;color:var(--brass-pale);
}
.imprint-name{
  grid-area:name;
  font-family:var(--font-serif);font-weight:400;
  font-size:clamp(38px,6vw,86px);line-height:1;
  letter-spacing:var(--track-4xl);
  color:#FCFDFA;
}
.imprint-meta{grid-area:meta;}
.imprint-desc{
  display:block;max-width:34ch;
  font-size:var(--t-base);line-height:1.7;color:var(--paper-on-dark-soft);
}

/* The address, stamped between two rules that draw outward on hover. */
.imprint-address{
  grid-area:address;
  /* The rules take the flexible tracks and the address sizes to its own
     content, so it sits centred between two rules that reach the plate
     edges. With `auto` on the rules they were empty spans at zero width
     and could never have drawn at all. */
  display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
  align-items:center;gap:var(--sp-5);
  margin-top:var(--sp-4);
}
.imprint-address .imprint-rule{
  display:block;height:1px;background:var(--brass);
  transform:scaleX(0);transition:transform .6s var(--ease-out);
}
.imprint-address .imprint-rule:first-child{transform-origin:right;}
.imprint-address .imprint-rule:last-child{transform-origin:left;}
.imprint:hover .imprint-rule,.imprint:focus-visible .imprint-rule{transform:scaleX(1);}
.imprint-url{
  font-family:var(--font-mono);
  font-size:clamp(15px,2.1vw,30px);
  letter-spacing:.06em;color:var(--brass-pale);
  white-space:nowrap;
  transition:color var(--dur) var(--ease);
}
.imprint:hover .imprint-url,.imprint:focus-visible .imprint-url{color:#F3E4BE;}

.imprint-go{
  grid-area:go;
  display:inline-flex;align-items:center;gap:15px;
  margin-top:var(--sp-4);
  font-size:15.5px;font-weight:500;
}
.imprint-go-icon{
  flex:none;width:46px;height:46px;border-radius:50%;
  background:var(--ground);color:var(--ink);
  display:grid;place-items:center;
  transition:transform var(--dur) var(--spring-out),background var(--dur) var(--ease);
}
.imprint-go-icon .icon{width:17px;height:17px;}
.imprint:hover .imprint-go-icon,.imprint:focus-visible .imprint-go-icon{
  background:var(--brass-bright);
  transform:translate(3px,-3px);
}
.imprint-go-label{
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1px;background-position:0 100%;background-repeat:no-repeat;
  padding-bottom:2px;
  transition:background-size var(--dur-slow) var(--ease);
}
.imprint:hover .imprint-go-label,.imprint:focus-visible .imprint-go-label{background-size:100% 1px;}

/* One column below the point where the name and description can sit side
   by side without the address wrapping. */
@media (max-width:820px){
  .imprint{
    grid-template-columns:minmax(0,1fr);
    grid-template-areas:"eyebrow" "name" "meta" "address" "go";
    align-items:start;gap:var(--sp-4);
  }
  .imprint-address{grid-template-columns:minmax(0,1fr);gap:var(--sp-3);}
  /* Stacked, the flanking rules read as clutter; the address keeps one. */
  .imprint-address .imprint-rule:last-child{display:none;}
  .imprint-address .imprint-rule:first-child{transform-origin:left;}
  .imprint-url{white-space:normal;overflow-wrap:anywhere;}
}
/* A touch device never hovers, so the rule would never draw and the
   address would sit unframed. Draw it at rest where there is no pointer. */
@media (hover:none){
  .imprint-address .imprint-rule{transform:scaleX(1);}
}
@media (prefers-reduced-motion: reduce){
  .imprint-address .imprint-rule{transform:scaleX(1);}
  .imprint:hover .imprint-go-icon,.imprint:focus-visible .imprint-go-icon{transform:none;}
}

/* ---------- Contents index ----------
   A journal contents list: number, subject, and the lens it belongs to,
   separated by hairlines. Same dated-row family as .pub-entry and
   .event-item, so the three ruled lists on the site behave identically. */
.toc{list-style:none;margin:0;padding:0;border-top:1px solid var(--line);counter-reset:toc;}
.toc-row{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) minmax(0,auto);
  gap:var(--sp-4) var(--sp-6);
  align-items:baseline;
  padding:var(--sp-6) 18px;margin:0 -18px;
  border-bottom:1px solid var(--line);
  position:relative;
  transition:background var(--dur) var(--ease);
}
.toc-row::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:var(--brass);transform:scaleY(0);transform-origin:top;
  transition:transform var(--dur) var(--ease-out);
}
.toc-row:hover{background:var(--pine-wash-soft);}
.toc-row:hover::before{transform:scaleY(1);}
.toc-num{
  font-family:var(--font-mono);font-size:var(--t-xs);font-weight:500;
  letter-spacing:.08em;color:var(--brass-ink);
  font-variant-numeric:tabular-nums;
}
.toc-title{
  display:block;
  font-family:var(--font-serif);font-size:var(--t-xl);font-weight:500;
  line-height:1.15;letter-spacing:-.015em;color:var(--ink);
  margin-bottom:10px;
}
.toc-note{
  display:block;font-size:var(--t-base);line-height:1.7;
  color:var(--ink-soft);max-width:62ch;
}
.toc-lens{
  font-family:var(--font-mono);font-size:var(--t-2xs);letter-spacing:.08em;
  text-transform:uppercase;color:var(--sage);white-space:nowrap;
  padding-top:4px;
}
@media (max-width:760px){
  .toc-row{grid-template-columns:auto minmax(0,1fr);gap:var(--sp-2) var(--sp-4);}
  .toc-lens{grid-column:2;white-space:normal;padding-top:0;}
}
@media (prefers-reduced-motion: reduce){
  .toc-row::before{display:none;}
}
