/* ---------------------------------------------------------------------------
   Scanventure — direction 4A, whole site.

   Built from two handoffs: design/README-4a.md (home page) and
   design/inner/README-inner.md (everything else). Every colour, size, weight,
   spacing and breakpoint below is taken from those documents.

   Motion comes from a third, design_handoff_scanventure_motion. It is done in
   CSS wherever CSS can do it -- entrances, hovers, the drawn underlines and the
   page transitions are all script-free. /dist/motion.js covers only the three
   things CSS cannot: scroll reveal, parallax and the counting numbers. No
   inline script: the Content-Security-Policy still forbids it, and the mobile
   menu is still <details>/<summary>.
   --------------------------------------------------------------------------- */

@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 300 400;
  font-display: swap;
  src: url(/fonts/newsreader.woff2) format('woff2');
  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: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(/fonts/instrument-sans.woff2) format('woff2');
  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';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/ibm-plex-mono.woff2) format('woff2');
  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;
}

:root {
  --petrol: #0E3346;
  --petrol-line: #255A72;
  --brass: #E2A34C;
  --brass-hover: #F0B45E;
  --brass-on-light: #B0793A;
  --cream-bg: #FFF9F0;
  --cream-fg: #FFF6E8;
  --body-light: #3D5563;
  --muted: #8FA3AE;
  --hero-body: #DCE9EF;
  --card-body: #C7DAE3;
  /* new in the inner-pages handoff, both derived from cream-bg */
  --cream-line: #E8DCCB;
  --cream-hover: #FFF3E2;
  --gutter: 56px;
  /* motion handoff. --masthead-h is the sticky header's height; the aside's own
     sticky offset is derived from it rather than guessed, so the two cannot
     drift apart. It is redefined per breakpoint, like --gutter. */
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --dur-reveal: 900ms;
  --dur-hover: 260ms;
  --dur-zoom: 1200ms;
  --masthead-h: 80px;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--petrol);
  font-family: 'Instrument Sans', system-ui, -apple-system, sans-serif;
}

.page {
  max-width: 1280px;
  margin: 0 auto;
  background: var(--cream-bg);
  color: var(--petrol);
  box-shadow: 0 30px 80px -40px rgba(14, 51, 70, .45);
}

a { color: inherit; text-decoration: none; }
.mono { font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace; }
.display { font-family: 'Newsreader', Georgia, 'Times New Roman', serif; }
img { max-width: 100%; }

/* --- masthead ----------------------------------------------------------- */
.masthead {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 22px var(--gutter); background: var(--petrol); color: var(--cream-fg);
}
.brand { display: flex; align-items: baseline; gap: 14px; }
.brand .name {
  font-family: 'Newsreader', Georgia, serif; font-size: 24px;
  color: var(--cream-fg); transition: color 150ms ease;
}
/* The wordmark is the way home from every page -- it was a link on the old site
   and the artboard drew it as plain text, which quietly lost the affordance. */
a.name:hover { color: var(--brass); }
a.name:focus-visible { outline: 2px solid var(--brass); outline-offset: 4px; }
.brand .est { font-size: 11px; letter-spacing: .14em; color: var(--brass); }

.nav { display: flex; gap: 30px; align-items: center; font-size: 14px; }
/* Scoped away from the Contact button. Unscoped, `.nav a` (two classes) beat
   `.btn-contact` (one), so the button rendered --hero-body on brass -- pale blue
   on gold, about 1.6:1, well under the 4.5:1 AA needs. It had been declaring
   --petrol and losing. */
.nav a:not(.btn-contact) { color: var(--hero-body); }
.nav a:not(.btn-contact):hover { color: var(--cream-fg); }
.nav a:not(.btn-contact)[aria-current="page"] { color: var(--cream-fg); }
.nav a:focus-visible { outline: 2px solid var(--brass); outline-offset: 4px; }
.btn-contact {
  background: var(--brass); color: var(--petrol); padding: 9px 18px;
  font-weight: 600; transition: background 150ms ease;
}
.btn-contact:hover { background: var(--brass-hover); color: var(--petrol); }
.btn-contact:focus-visible { outline: 2px solid var(--cream-fg); outline-offset: 3px; }

/* the mobile menu exists in the markup at every width; only shown under 700px */
.menu { display: none; }
.menu > summary {
  list-style: none; cursor: pointer; display: inline-block;
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--cream-fg);
  border: 1px solid var(--petrol-line); padding: 8px 12px;
}
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }
.menu .rows { margin-top: 16px; }
.menu .rows a {
  display: flex; justify-content: flex-start; align-items: center; gap: 12px;
  padding: 16px 24px; font-size: 17px; color: var(--cream-fg);
  border-top: 1px solid var(--petrol-line);
}
.menu .rows a:last-child { border-bottom: 1px solid var(--petrol-line); }
.menu .rows a.is-contact { color: var(--brass); font-weight: 600; }
/* The current-page marker leads the label instead of trailing it, so where it
   sits no longer depends on how long the page name is. Every row reserves the
   slot and only the current page fills it, which keeps all four labels starting
   at the same x rather than indenting one of them. */
.menu .rows a::before {
  content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%;
  background: transparent;
}
.menu .rows a[aria-current="page"]::before { background: var(--brass); }

/* --- page header -------------------------------------------------------- */
.head { padding: 48px var(--gutter) 0; max-width: calc(820px + 2 * var(--gutter)); }
.head .stack { display: flex; flex-direction: column; gap: 22px; }
.crumb {
  font-family: 'IBM Plex Mono', monospace; font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; display: flex; flex-wrap: wrap; gap: 10px;
  align-items: baseline; color: var(--body-light);
}
.crumb a { color: var(--brass-on-light); border-bottom: 1px solid var(--brass); }
.crumb a:hover { color: var(--petrol); }
.crumb a:focus-visible { outline: 2px solid var(--petrol); outline-offset: 3px; }
.crumb .sep { color: var(--muted); }

h1.title {
  margin: 0; font-family: 'Newsreader', Georgia, serif; font-weight: 300;
  font-size: 64px; line-height: 1.02; letter-spacing: -.025em; color: var(--petrol);
  text-wrap: pretty;
}
.intro {
  margin: 0; font-family: 'Newsreader', Georgia, serif; font-weight: 300;
  font-size: 26px; line-height: 1.38; color: var(--petrol); max-width: 820px;
}
.intro p { margin: 0 0 12px; }
.intro p:last-child { margin-bottom: 0; }

/* --- closer: cover figure, or a rule when there is none ------------------ */
.cover { margin: 40px 0 0; }
.cover img { display: block; width: 100%; height: auto; object-fit: cover; }
.cover figcaption {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .08em;
  color: var(--muted); padding: 10px var(--gutter) 0;
}
/* Attribution for the four openly licensed photographs. It shares the caption
   line rather than taking its own, separated by a middot so the subject still
   reads as the caption and the credit reads as metadata after it. */
.cover figcaption .credit::before { content: "\00B7"; margin: 0 .6em; opacity: .55; }
.cover figcaption a { color: inherit; border-bottom: 1px solid var(--cream-line); }
.cover figcaption a:hover { color: var(--brass-on-light); border-color: var(--brass-on-light); }
.cover figcaption a:focus-visible { outline: 2px solid var(--petrol); outline-offset: 2px; }
.rule { border: 0; border-top: 1px solid var(--petrol); margin: 36px var(--gutter) 0; }

/* --- body: 720px column + 292px aside ----------------------------------- */
.body {
  padding: 48px var(--gutter) 72px;
  display: grid; grid-template-columns: 720px 292px; column-gap: 156px;
  align-items: start;
}
.body.no-cover { padding-top: 40px; }
.prose > * { margin: 0; }
.prose > * + * { margin-top: 22px; }
.prose p { font-size: 17px; line-height: 1.7; color: var(--body-light); }
.prose h2 {
  font-family: 'Newsreader', Georgia, serif; font-weight: 400; font-size: 34px;
  line-height: 1.15; letter-spacing: -.015em; color: var(--petrol);
  margin-top: 48px; margin-bottom: 16px;
}
.prose h2 + * { margin-top: 0; }
.prose h3 {
  font-weight: 600; font-size: 20px; line-height: 1.3; color: var(--petrol);
  margin-top: 36px; margin-bottom: 14px;
}
.prose h3 + * { margin-top: 0; }
.prose ul { padding-left: 22px; font-size: 17px; line-height: 1.7; color: var(--body-light); }
.prose li + li { margin-top: 8px; }
.prose a { color: var(--petrol); border-bottom: 1px solid var(--brass); }
.prose a:hover { color: var(--brass-on-light); border-color: var(--brass-on-light); }
.prose a:focus-visible { outline: 2px solid var(--petrol); outline-offset: 3px; }
.prose figure { margin: 0; }
.prose figure img { display: block; width: 100%; height: auto; }
.prose figcaption {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .08em;
  color: var(--muted); margin-top: 14px;
}

.prose .dl { display: grid; grid-template-columns: 160px 1fr; border-top: 1px solid var(--cream-line); }
.prose .dl > div {
  display: contents;
}
.prose .dl dt, .prose .dl dd {
  margin: 0; padding: 12px 0; border-bottom: 1px solid var(--cream-line);
}
.prose .dl dt {
  font-family: 'IBM Plex Mono', monospace; font-size: 13px; color: var(--muted);
}
.prose .dl dd { font-size: 17px; color: var(--petrol); }
/* The credits list pairs a photograph with its photographer, so its term column
   carries a description rather than a short label like "Held since". */
.prose .dl.credits-dl { grid-template-columns: 300px 1fr; }
.prose .dl.credits-dl dt { font-size: 12px; line-height: 1.5; letter-spacing: .02em; }
.prose .dl.credits-dl dd a { color: var(--petrol); border-bottom: 1px solid var(--brass); }
.prose .dl.credits-dl dd a:hover { color: var(--brass-on-light); border-color: var(--brass-on-light); }

/* --- aside -------------------------------------------------------------- */
.aside { position: sticky; top: calc(var(--masthead-h) + 24px); }
.aside dl { margin: 0; border-top: 1px solid var(--petrol); }
.aside .row {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 14px 0; border-bottom: 1px solid var(--cream-line);
}
.aside dt {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
}
.aside dd { margin: 0; font-size: 15px; color: var(--petrol); text-align: right; }
.back {
  display: inline-block; margin-top: 28px;
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--brass-on-light);
}
.back:hover { color: var(--petrol); }
.back:focus-visible { outline: 2px solid var(--petrol); outline-offset: 3px; }

/* --- section index ------------------------------------------------------ */
.head.index {
  max-width: none; padding: 64px var(--gutter) 40px;
  display: grid; grid-template-columns: 1fr 292px; gap: 56px; align-items: end;
}
.head.index h1.title { font-size: 56px; }
.head.index .intro { font-size: 24px; }
.eyebrow {
  font-family: 'IBM Plex Mono', monospace; font-size: 12px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--brass-on-light);
}
.count {
  font-family: 'IBM Plex Mono', monospace; font-size: 12px; line-height: 1.9;
  color: var(--body-light); border-top: 1px solid var(--petrol); padding-top: 12px;
}

.cards {
  display: grid; grid-template-columns: repeat(4, 292px); gap: 0;
  border-top: 1px solid var(--cream-line); border-left: 1px solid var(--cream-line);
  margin: 0 var(--gutter);
}
.card {
  display: flex; flex-direction: column; min-height: 372px; overflow: hidden;
  border-right: 1px solid var(--cream-line); border-bottom: 1px solid var(--cream-line);
  transition: background 150ms ease;
}
.card:hover, .card:focus-within { background: var(--cream-hover); }
.card:focus-visible { outline: 2px solid var(--petrol); outline-offset: -2px; }
.card .strip { display: block; width: 100%; height: 112px; object-fit: cover; }
.card .strip.empty { background: var(--petrol); }
.card .text { padding: 22px 22px 24px; display: flex; flex-direction: column; gap: 10px; }
.card .name {
  font-family: 'Newsreader', Georgia, serif; font-weight: 400; font-size: 26px;
  line-height: 1.1; color: var(--petrol);
}
.card .meta {
  font-family: 'IBM Plex Mono', monospace; font-size: 12px; color: var(--brass-on-light);
}
.card .desc { font-size: 14px; line-height: 1.6; color: var(--body-light); }

/* --- people ------------------------------------------------------------- */
/* Three across, not the four the card grids use. With five directors, four
   columns leave the fifth alone on his own row; three give 3 + 2. The columns
   stretch rather than staying at 292px so the row still fills the width, and
   the portrait keeps its 248px -- the extra room goes to whitespace, which also
   lets the longest name sit on one line. */
.people {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  border-left: 1px solid var(--cream-line); margin: 40px var(--gutter) 0;
}
.person {
  display: flex; flex-direction: column; gap: 16px;
  padding: 24px 22px 28px; border-right: 1px solid var(--cream-line);
  transition: background 150ms ease;
}
.person:hover, .person:focus-within { background: var(--cream-hover); }
.person:focus-visible { outline: 2px solid var(--petrol); outline-offset: -2px; }
.person img {
  display: block; width: 248px; height: 327px; object-fit: cover; filter: grayscale(1);
}
.person .empty { display: block; width: 248px; height: 327px; background: var(--petrol); }
.person .name { font-family: 'Newsreader', Georgia, serif; font-size: 24px; line-height: 1.1; }

.head.person-head {
  max-width: none; display: grid; grid-template-columns: 720px 292px;
  column-gap: 156px; align-items: start; padding: 48px var(--gutter) 0;
}
.head.person-head .portrait {
  display: block; width: 292px; height: 385px; object-fit: cover; filter: grayscale(1);
}

/* --- 404 ---------------------------------------------------------------- */
.utility {
  padding: 96px var(--gutter) 120px;
  display: grid; grid-template-columns: 720px 292px; column-gap: 156px; align-items: start;
}
.utility h1.title { margin-top: 22px; }
.utility .lead { margin-top: 22px; }
.sections { border-top: 1px solid var(--petrol); }
.sections a {
  display: flex; justify-content: space-between; gap: 16px; align-items: baseline;
  padding: 14px 0; font-size: 16px; border-bottom: 1px solid var(--cream-line);
  transition: color 150ms ease;
}
.sections a:hover { color: var(--brass-on-light); }
.sections a:focus-visible { outline: 2px solid var(--petrol); outline-offset: 3px; }
.sections .n { font-family: 'IBM Plex Mono', monospace; font-size: 12px; color: var(--muted); }

/* --- footer ------------------------------------------------------------- */
.foot {
  padding: 44px var(--gutter); display: flex; justify-content: space-between;
  align-items: flex-end; gap: 40px; flex-wrap: wrap;
  border-top: 1px solid var(--cream-line);
}
.foot .who { display: flex; flex-direction: column; gap: 8px; }
.foot .who .co { font-family: 'Newsreader', Georgia, serif; font-size: 21px; }
.foot .who .addr { font-size: 14px; line-height: 1.6; color: var(--body-light); }
.foot .reach {
  display: flex; gap: 40px; flex-wrap: wrap;
  font-family: 'IBM Plex Mono', monospace; font-size: 12px; color: var(--body-light);
}
.foot .reach a { transition: color 150ms ease; }
.foot .reach a:hover { color: var(--brass-on-light); }
.foot .cvr { color: var(--muted); }


/* =========================================================================
   Home page (direction 4A). Merged in when the site collapsed to one
   stylesheet -- these are the only blocks home-4a.css had that the inner
   pages do not: hero, best-owner, holdings and the photo placeholders.
   ========================================================================= */

/* --- hero --------------------------------------------------------------- */
.hero { position: relative; height: 620px; }
.hero .photo { position: absolute; inset: 0; overflow: hidden; }
.hero .photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero .scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(14,51,70,.94) 0%, rgba(14,51,70,.82) 45%, rgba(14,51,70,.15) 100%);
}
.hero .copy {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  justify-content: center; gap: 28px; padding: 0 var(--gutter);
  max-width: 820px; color: var(--cream-fg);
}
/* Scoped to .hero. Unscoped, this re-declaration of .eyebrow won on every page by
   source order, so section-index and 404 eyebrows rendered --brass on cream
   instead of --brass-on-light -- too pale to read. */
.hero .eyebrow { color: var(--brass); }
.hero h1 { margin: 0; font-weight: 300; font-size: 78px; line-height: 1.03; letter-spacing: -.025em; }
.hero p { margin: 0; max-width: 52ch; font-size: 17px; line-height: 1.65; color: var(--hero-body); }
.actions { display: flex; flex-wrap: wrap; gap: 14px; }
.btn-primary {
  background: var(--brass); color: var(--petrol); padding: 15px 26px;
  font-size: 15px; font-weight: 600; transition: background 150ms ease;
}
.btn-primary:hover { background: var(--brass-hover); }
.btn-ghost {
  border: 1px solid rgba(255,246,232,.45); padding: 15px 24px; font-size: 15px;
  transition: border-color 150ms ease;
}
.btn-ghost:hover { border-color: var(--cream-fg); }

/* --- best-owner --------------------------------------------------------- */
.best-owner {
  padding: 72px var(--gutter); display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 56px; align-items: center;
}
.best-owner .lede { display: flex; flex-direction: column; gap: 22px; }
.best-owner .eyebrow { font-size: 11px; letter-spacing: .14em; color: var(--brass-on-light); }
.best-owner h2 { margin: 0; font-weight: 300; font-size: 46px; line-height: 1.12; letter-spacing: -.02em; }
.best-owner p { margin: 0; font-size: 17px; line-height: 1.7; color: var(--body-light); max-width: 48ch; }
.tiles { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 18px; }
.tile { height: 210px; border-radius: 4px; overflow: hidden; }
.tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tile-note {
  height: 210px; background: var(--petrol); color: var(--cream-fg); padding: 24px;
  display: flex; flex-direction: column; justify-content: space-between;
}
.tile-note .eyebrow { font-size: 11px; letter-spacing: .12em; color: var(--brass); }
.tile-note .figure { font-size: 30px; font-weight: 300; line-height: 1.15; }

/* --- selected holdings -------------------------------------------------- */
.holdings {
  background: var(--petrol); color: var(--cream-fg); padding: 64px var(--gutter);
  display: flex; flex-direction: column; gap: 32px;
}
/* Named .bar, not .head. It used to be .head, which collided with the inner-page
   header rule above and inherited `padding: 48px 56px` and `max-width: 932px`
   from it -- so the brass rule stopped short of the grid it captions. */
.holdings .bar {
  display: flex; align-items: baseline; justify-content: space-between; gap: 24px;
  border-bottom: 1px solid var(--brass); padding-bottom: 18px;
}
.holdings h2 { margin: 0; font-weight: 300; font-size: 40px; }
.holdings .all {
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--brass); white-space: nowrap; transition: color 150ms ease;
}
.holdings .all:hover { color: var(--brass-hover); }
.holdings .grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 1px; background: var(--petrol-line); }
.holding { background: var(--petrol); padding: 26px 24px; display: flex; flex-direction: column; gap: 10px; }
.holding .co { font-size: 26px; }
.holding .meta { font-size: 12px; color: var(--brass); }
.holding .blurb { font-size: 14px; line-height: 1.6; color: var(--card-body); }

/* The .ph photo-placeholder block lived here. Every placeholder was replaced by
   real photography, so it was dead CSS referenced by no HTML. */


/* =========================================================================
   Motion layer — design_handoff_scanventure_motion.

   CSS does everything it can: entrances, hovers, the drawn underlines and the
   page transitions are all script-free. /dist/motion.js adds only scroll
   reveal, parallax and the counting numbers, and every state that depends on
   it is gated behind `html.js`, so with scripting off the page is complete and
   nothing is stuck invisible.
   ========================================================================= */

@keyframes sv-rise  { from { transform: translateY(110%); opacity: 0 } to { transform: none; opacity: 1 } }
@keyframes sv-fade  { from { transform: translateY(14px);  opacity: 0 } to { transform: none; opacity: 1 } }
@keyframes sv-drift { 0%, 100% { transform: scale(1.06) } 50% { transform: scale(1.1) translate(-1.2%, -.8%) } }
@keyframes sv-scrim { from { opacity: 0 } to { opacity: 1 } }

/* --- page transitions ---------------------------------------------------- */
/* The prototype fades out by intercepting the click and waiting 280ms before
   navigating. That is free in a single-page React app; here it would put a real
   280ms tax on every internal link. Cross-document view transitions give the
   same fade-lift, driven by the browser, with no delay and no JavaScript --
   and browsers without support simply navigate, which is the right degrade. */
@view-transition { navigation: auto; }
@keyframes sv-vt-out { to   { opacity: 0; transform: translateY(-10px) } }
@keyframes sv-vt-in  { from { opacity: 0; transform: translateY(14px) } }
::view-transition-old(root) { animation: 200ms ease both sv-vt-out; }
::view-transition-new(root) { animation: 280ms var(--ease-out) both sv-vt-in; }

/* --- masthead ------------------------------------------------------------ */
.masthead { position: sticky; top: 0; z-index: 20; box-shadow: 0 1px 0 var(--petrol-line); }

/* A drawn underline rather than a border. The border version applied
   `border-bottom: 2px` + `padding-bottom: 5px` to the active link only, making
   it 7px taller than its siblings -- so the whole row shifted as you moved
   between sections. Every link now carries the same padding and only the
   gradient's width changes. */
.nav a:not(.btn-contact) {
  padding-bottom: 5px;
  background: linear-gradient(var(--brass), var(--brass)) no-repeat 0 100% / 0 2px;
  transition: color 200ms ease, background-size 320ms var(--ease-out);
}
.nav a:not(.btn-contact):hover,
.nav a[aria-current="page"] { background-size: 100% 2px; }

.brand .est { display: inline-block; font-variant-numeric: tabular-nums; }

/* --- buttons ------------------------------------------------------------- */
/* These are inline <a>, so every transform in the spec was a no-op until they
   became inline-block. */
.btn-contact, .btn-primary, .btn-ghost, .back { display: inline-block; }
.arrow { display: inline-block; transition: transform 300ms var(--ease-out), opacity 400ms ease; }

.btn-contact { transition: background var(--dur-hover) ease, transform 300ms var(--ease-out); }
.btn-contact:hover { transform: translateY(-1px); }
.btn-contact:hover .arrow { transform: translateX(4px); }

.btn-primary {
  transition: background var(--dur-hover) ease, transform 300ms var(--ease-out),
              box-shadow 300ms var(--ease-out);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 12px 24px -12px rgba(226, 163, 76, .6); }
.btn-primary:hover .arrow { transform: translateX(4px); }
.btn-ghost {
  transition: border-color var(--dur-hover) ease, background var(--dur-hover) ease,
              transform 300ms var(--ease-out);
}
.btn-ghost:hover { background: rgba(255, 246, 232, .06); transform: translateY(-2px); }

.back { transition: color var(--dur-hover) ease; }
.back:hover .arrow { transform: translateX(-4px); }

/* --- hero ---------------------------------------------------------------- */
/* .photo keeps overflow:hidden; the drift wrapper bleeds 6% top and bottom so
   there is something to pull into frame when it parallaxes. */
.hero .photo-drift { position: absolute; inset: -6% 0; will-change: transform; }
.hero .photo-drift img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transform-origin: 60% 50%; animation: sv-drift 26s ease-in-out infinite;
}
.hero .scrim { animation: sv-scrim var(--dur-reveal) ease both; }

/* The two headline lines are authored in index.html rather than split by
   script: the copy is fixed, so splitting it at runtime would buy nothing and
   would not work with JS off. */
.hero h1 .line { display: block; overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.hero h1 .line > span { display: block; animation: sv-rise var(--dur-reveal) var(--ease-out) both; }
.hero h1 .line:nth-of-type(1) > span { animation-delay: 250ms; }
.hero h1 .line:nth-of-type(2) > span { animation-delay: 370ms; }
.hero .eyebrow { animation: sv-fade 700ms var(--ease-out) 150ms both; }
.hero p         { animation: sv-fade 800ms var(--ease-out) 600ms both; }
.hero .actions  { animation: sv-fade 800ms var(--ease-out) 760ms both; }

/* --- page-header entrances ----------------------------------------------- */
/* padding-bottom and the matching negative margin cancel out, so masking the
   rise does not clip descenders or change the .stack gap. */
.head h1.title { overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.head h1.title > span { display: block; animation: sv-rise var(--dur-reveal) var(--ease-out) 160ms both; }
.head .crumb   { animation: sv-fade 700ms var(--ease-out) 60ms both; }
.head .intro   { animation: sv-fade 800ms var(--ease-out) 340ms both; }
.head.index .eyebrow { animation: sv-fade 700ms var(--ease-out) 80ms both; }
.head.index .intro   { animation-delay: 360ms; }
.count  { animation: sv-fade 800ms var(--ease-out) 480ms both; }
.cover  { animation: sv-fade var(--dur-reveal) var(--ease-out) 500ms both; }

/* --- cover parallax ------------------------------------------------------ */
/* The frame clips; the figcaption stays outside it, so it is not clipped too.
   aspect-ratio reserves the space, so the taller image costs no layout shift. */
.cover .frame { display: block; overflow: hidden; aspect-ratio: 1280 / 620; }
.cover .frame img {
  display: block; width: 100%; height: 112%; margin-top: -6%;
  object-fit: cover; will-change: transform;
}

/* --- scroll reveal ------------------------------------------------------- */
/* `data-reveal="fade"` is opacity only. It is used on .card, .person and
   .holding because .cards, .people and .holdings .grid draw their grids as
   hairline lattices -- 1px borders and a 1px gap showing petrol through -- and
   translating a cell tears those seams open while it animates. */
html.js [data-reveal] {
  opacity: 0; transform: translateY(24px);
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
}
html.js [data-reveal="fade"] { transform: none; }
html.js [data-reveal].is-in { opacity: 1; transform: none; }

/* --- hover: images ------------------------------------------------------- */
.tile img, .card .strip, .holding .strip img, .person .shot img {
  transition: transform var(--dur-zoom) var(--ease-out), filter 600ms ease;
}
.tile:hover img          { transform: scale(1.06); }
.card:hover .strip       { transform: scale(1.06); }
.holding:hover .strip img { transform: scale(1.06); filter: saturate(1); }
.person:hover .shot img, .person:focus-within .shot img { transform: scale(1.04); filter: grayscale(0); }

.card { transition: background 300ms ease; }
.person { transition: background 300ms ease; }

/* --- hover: the arrow that appears on a card ----------------------------- */
.card .name .arrow, .person .name .arrow {
  color: var(--brass-on-light); opacity: 0; transform: translateX(-6px);
  transition: opacity 400ms ease, transform 400ms var(--ease-out);
}
.card:hover .name .arrow, .card:focus-within .name .arrow,
.person:hover .name .arrow, .person:focus-within .name .arrow { opacity: 1; transform: none; }

/* --- holdings ------------------------------------------------------------ */
/* The padding moved from .holding onto .holding .text so the strip can run
   full-bleed to the cell edge, the way .card .strip already does. */
.holding { padding: 0; transition: background 300ms ease; }
.holding:hover { background: #123D53; }
.holding .strip { position: relative; height: 150px; overflow: hidden; }
.holding .strip img { width: 100%; height: 100%; object-fit: cover; display: block; filter: saturate(.85); }
.holding .go {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 10px 24px;
  background: linear-gradient(transparent, rgba(14, 51, 70, .85));
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--brass);
  transform: translateY(100%); opacity: 0;
  transition: transform 500ms var(--ease-out), opacity 400ms ease;
}
.holding:hover .go, .holding:focus-visible .go { transform: none; opacity: 1; }
.holding .text { padding: 26px 24px; display: flex; flex-direction: column; gap: 10px; }
.holding:focus-visible { outline: 2px solid var(--brass); outline-offset: -2px; }

/* --- case highlight tiles ------------------------------------------------ */
/* Modelled on .holding .go, with one deliberate difference: this caption is
   always visible. Hiding it until hover would leave the block reading as three
   mute photographs, which was the whole complaint. */
.tile { position: relative; display: block; }
/* The gradient is fully opaque from 55% down, and the padding puts every glyph
   below that line. A plain transparent-to-dark fade is not safe here: the
   photographs are chosen for the page, not for carrying text, and over
   Nørhaven's near-white book edges the caption measured 1.02:1. On the solid
   band it is 10:1. */
.tile .cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: baseline; gap: 8px;
  padding: 30px 14px 11px;
  background: linear-gradient(rgba(14, 51, 70, 0) 0%, rgba(14, 51, 70, .97) 55%,
                              rgba(14, 51, 70, .97) 100%);
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--cream-fg);
}
.tile .cap i { font-style: normal; color: var(--brass); }
.tile .cap .arrow { margin-left: auto; color: var(--brass); }
.tile:hover .cap .arrow, .tile:focus-visible .cap .arrow { transform: translateX(4px); }
.tile:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }

/* The note tile gains a third line, so space-between spreads all three. */
.tile-note { text-decoration: none; transition: background 300ms ease; }
a.tile-note:hover { background: #123D53; }
a.tile-note:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }
.tile-note .more {
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--brass);
}
a.tile-note:hover .more .arrow { transform: translateX(4px); }

/* The holdings count, moved out of the tile block. */
.holdings .barleft { display: flex; align-items: baseline; gap: 20px; flex-wrap: wrap; }
.holdings .note { font-size: 12px; color: var(--card-body); }

/* --- people -------------------------------------------------------------- */
/* The portrait needed a frame before it could scale: it had no wrapper, so a
   zoom spilled across the 1px lattice border into the next person. */
.person .shot {
  display: block; width: 248px; aspect-ratio: 248 / 327;
  overflow: hidden; background: var(--petrol);
}
.person .shot img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1); }

/* --- numbers ------------------------------------------------------------- */
/* Tabular figures so a counting number does not reflow the line it sits in. */
[data-count] { font-variant-numeric: tabular-nums; }

/* --- footer -------------------------------------------------------------- */
.foot .reach a {
  padding-bottom: 3px;
  background: linear-gradient(var(--brass-on-light), var(--brass-on-light)) no-repeat 0 100% / 0 1px;
  transition: color var(--dur-hover) ease, background-size 320ms var(--ease-out);
}
.foot .reach a:hover { color: var(--brass-on-light); background-size: 100% 1px; }


/* --- responsive --------------------------------------------------------- */
@media (max-width: 900px) {
  .body, .utility, .head.person-head { grid-template-columns: minmax(0, 1fr); }
  .body .aside, .utility .sections-wrap { position: static; }
  .aside { position: static; margin-bottom: 32px; order: -1; }
  .aside dl { display: flex; flex-wrap: wrap; gap: 0 32px; }
  .aside .row { border-bottom: 0; padding: 8px 0; gap: 10px; }
  .head.index { grid-template-columns: minmax(0, 1fr); gap: 28px; align-items: start; }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .people { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .person .shot, .person .empty { width: 100%; height: auto; aspect-ratio: 3 / 4; }
  .head.person-head .portrait { width: 100%; max-width: 292px; height: auto; aspect-ratio: 292 / 385; }
}

@media (max-width: 700px) {
  :root { --gutter: 24px; }
  .nav { display: none; }
  .menu { display: block; }
  h1.title { font-size: 44px; }
  .head.index h1.title { font-size: 40px; }
  .intro, .head.index .intro { font-size: 22px; }
  .prose h2 { font-size: 28px; }
  .masthead { flex-direction: column; align-items: flex-start; gap: 18px; }
  /* The masthead stacks with align-items: flex-start here, so <details> was
     shrinking to its content -- rows and rules spanning 122px of a 390px
     screen. Stretch it so the menu is as wide as the page. The summary stays
     inline-block, so the MENU button keeps its own size. */
  .menu { align-self: stretch; }
  .foot { flex-direction: column; align-items: flex-start; gap: 28px; }
  .foot .reach { gap: 12px; flex-direction: column; }
}

@media (max-width: 600px) {
  .cards { grid-template-columns: minmax(0, 1fr); }
  .prose .dl { grid-template-columns: minmax(0, 1fr); }
  .prose .dl dt { padding-bottom: 0; border-bottom: 0; }
}

/* The old rule zeroed transition-duration only, which was enough when nothing
   here animated. With keyframes, scroll reveal and view transitions in play it
   has to cover all of them -- including forcing revealed content visible, in
   case motion.js is what gets skipped. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0s !important;
    scroll-behavior: auto !important;
  }
  html.js [data-reveal] { opacity: 1 !important; transform: none !important; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
    animation: none !important;
  }
}

@media (max-width: 1100px) {
  .hero h1 { font-size: 62px; }
  .best-owner h2 { font-size: 38px; }
}

@media (max-width: 900px) {
  .hero { height: auto; min-height: 560px; }
  .hero .copy { position: relative; padding: 64px var(--gutter); max-width: none; }
  .hero h1 { font-size: 46px; }
  .best-owner { grid-template-columns: minmax(0,1fr); gap: 40px; padding: 56px var(--gutter); }
  .tile-note { height: auto; min-height: 210px; }
  .tile-note .figure { font-size: 26px; }
  .holdings .grid { grid-template-columns: repeat(2,1fr); }
}

@media (max-width: 700px) {
  .hero h1 { font-size: 38px; }
  .best-owner h2 { font-size: 32px; }
  .tiles { grid-template-columns: minmax(0,1fr); }
  .tile-note .figure { font-size: 24px; }
  .holdings h2 { font-size: 32px; }
  .holdings .grid { grid-template-columns: minmax(0,1fr); }
}
