/* Westly Group — WordPress markup compatibility.
 * NOT ported from the design. The design's raw JSX renders nav/footer links as bare
 * <a> tags with no list wrapper, so kit.css/site.css never needed a list-style reset.
 * wp_nav_menu() always wraps each item in <li>, even with items_wrap stripping the outer
 * <ul> (see header.php, footer.php) — and a <li> with no <ul>/<ol> ancestor still renders
 * a bullet, because list-style-type's initial value is `disc` regardless of parent.
 * Kept in its own file, separate from the ported sheets, so those stay byte-diffable
 * against export-westly/twg/site.css.
 */
.nav-links li,
.nav-mobile li,
.footer-col li {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Gap between the fixed nav and the hero when logged in and viewing the front end.
 * WordPress's admin bar pushes <html> down with `margin-top: 32px` (46px under 783px,
 * where the admin bar itself goes taller) — but our own `.nav { position: fixed; top: 0 }`
 * is positioned against the true viewport, not affected by that margin, so it stays put
 * while `main`'s padding-top: 74px now starts 32px lower than the nav's actual bottom
 * edge. Never appears for a logged-out visitor; always appears for the owner editing their
 * own site, which is the primary way this theme gets viewed day to day.
 */
body.admin-bar .nav {
  top: 32px;
}
@media screen and (max-width: 782px) {
  body.admin-bar .nav {
    top: 46px;
  }
}

/* Same admin-bar gap, second instance: the Global Syndicate hero's pinned title.
 * `.net-hero-copy { position: sticky; top: 110px }` (site.css, verbatim) is a plain
 * document-flow element, not `position: fixed` like the nav — so WordPress's
 * `html { margin-top: 32px }` for logged-in users DOES push it down along with
 * everything else in the flow. But a sticky element's `top` offset is measured against
 * the scrollport itself, not against that margin, so the "stuck" position lands at
 * 110px from the true viewport top regardless. Meanwhile `.nav` above already gets
 * pushed to `top: 32px` by the fix above, since position:fixed ignores the margin
 * entirely and needs the explicit push. Net effect: nav bottom sits at 32+75=107px,
 * the sticky title sticks at 110px — a 3px gap instead of the ~35px a logged-out visitor
 * (or the deployed design, which has no admin bar to design around at all) actually
 * sees. Same fix shape as the nav: push the sticky offset down by the same amount the
 * admin bar adds, so the gap the design intended stays constant either way.
 */
body.admin-bar .net-hero-copy {
  top: 142px;
}
@media screen and (max-width: 782px) {
  body.admin-bar .net-hero-copy {
    top: 156px;
  }
}

/* Right-edge page overflow on the home page (a horizontal-scroll gutter).
 * site.css sets `body { overflow-x: hidden }` verbatim from the design — that's meant to
 * be the safety net for .home-hero { overflow: visible } (also verbatim), which lets
 * .hero-glow's `right: -10%` deliberately bleed past its own section for the blur effect.
 * The design relies on the BROWSER auto-propagating body's overflow-x to the viewport/
 * <html> box, which only happens when <html> has no overflow of its own. It never did here
 * — until WordPress's admin bar started adding inline rules to <html> for logged-in users
 * (see the admin-bar fix above), which appears to be enough to disqualify that
 * propagation in Chrome, leaving <html> at its default `overflow-x: visible` and the
 * glow's overflow visible as page-level horizontal scroll. Fixed by setting overflow-x
 * explicitly on <html> too, rather than depending on propagation at all.
 *
 * `clip`, not `hidden` — found while fixing the Global Syndicate page's pinned hero.
 * Per the CSS Overflow spec, if overflow-x is anything other than `visible`, the computed
 * overflow-y is forced to `auto` even when left undeclared — there is no way to clip only
 * the X axis with `hidden` and leave Y genuinely `visible`. That silently turned <html>
 * AND <body> (site.css's own verbatim rule has the same effect) into scroll containers,
 * which broke every `position: sticky` element on the site: `.net-hero-copy`'s
 * `top: 110px` never engaged, so the title just scrolled away with the page instead of
 * pinning while the taller logo grid scrolled past beside it. `overflow-x: clip` clips
 * the same horizontal bleed without the overflow-y side effect — confirmed via
 * `getComputedStyle()` that overflow-y reads back `visible` again, and the sticky title
 * holds. Overridden on both elements since site.css's own `body` rule has the same
 * problem and can't be edited (verbatim, byte-diffable against the design reference).
 */
html,
body {
  overflow-x: clip;
}

/* Logo ticker pause/play control — new theme chrome, not in the ported design.
 * site.css's `.ticker:hover .ticker-track { animation-play-state: paused !important }`
 * only stops the scroll on mouse hover, which is a WCAG 2.2.2 gap: no keyboard or touch
 * way to pause continuously-moving content. This button gives one. `!important` matches
 * the specificity the hover rule already uses, so the two don't fight for control.
 */
.ticker {
  position: relative;
}
.ticker.ticker-paused .ticker-track {
  animation-play-state: paused !important;
}
.ticker-toggle {
  position: absolute;
  top: 50%;
  right: 24px;
  z-index: 1;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--color-hairline);
  border-radius: 999px;
  background: var(--color-bg);
  color: var(--color-fg-2);
  cursor: pointer;
}
.ticker-toggle:hover {
  color: var(--color-fg);
  border-color: var(--color-fg-3);
}
.ticker-toggle:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

/* Nav link hover shouldn't get a text-decoration underline.
 * tokens.css carries a verbatim global rule, `.twg a:hover { text-decoration:
 * underline; text-underline-offset: 3px }`, meant for body/prose links. `.nav-link` is
 * an <a> inside `.twg`, so it inherits that too — giving hover a thin underline hugging
 * the text, visually nothing like `.nav-link.active::after`'s thicker 2px bar sitting
 * 2px below the link. Checked against the deployed design
 * (westly-group-website-offline-1.vercel.app): hovering a nav link there shows NO
 * underline at all — `getComputedStyle(link).textDecorationLine` reads `"none"` while
 * `:hover` is genuinely matched. `.twg .nav-link:hover` (3 class-level selectors) beats
 * `.twg a:hover` (2 classes + 1 type) on specificity, so this is enough to suppress it
 * without touching the verbatim global rule or kit.css/site.css.
 */
.twg .nav-link:hover {
  text-decoration: none;
}

/* News titles render blue instead of the design's near-black text.
 * In the original design (pages-news.jsx), `.news-title`/`.news-feature-title` wrap
 * plain text with NO <a> around it at all — data.js's news items have no real URLs, so
 * the mockup cards aren't clickable. This WordPress build correctly makes them real
 * links (news-grid.php wraps the title in <a href="..."> to the live outlet URL, since
 * all 87 posts route out via page-links-to) — but that <a> then falls under the
 * verbatim global rule `.twg a { color: var(--color-primary) }` with nothing more
 * specific reaching it: `.news-feature-title` sets no color at all, and `.news-title`'s
 * own `color: var(--color-fg)` (kit.css) is on the <h3>, which the direct rule on its
 * child <a> overrides rather than inherits from. Fixed by targeting the anchors
 * directly — `--color-fg` is #111418, the design's own "wordmark black, primary text"
 * token. Hover is left alone (still transitions toward the brand blue via the generic
 * `.twg a:hover` rule) — normal link affordance, not what was reported broken.
 */
.news-title a,
.news-feature-title a {
  color: var(--color-fg);
}

/* Flagship-tile logos (Tesla, SentinelOne, Procore) stretch out of proportion.
 * `.mtile-logo { max-width: 62%; width: auto; height: auto; max-height: 56px }`
 * (site.css, verbatim) relies on the browser preserving intrinsic aspect ratio when an
 * `<img>` is constrained by both max-width and max-height with width/height left auto.
 * That holds for wide logos where the width cap alone already lands under the height
 * cap (Luminar: natural ratio 6.4:1 → scales to 321×50, under the 56px cap, so
 * max-height never binds and nothing goes wrong). It breaks down once the height cap is
 * what should bind instead — for a squarer or taller logo, scaling to the 62% width
 * first would blow past 56px tall, so height should take over and width should shrink
 * to match. Measured directly instead of guessing which case this was: Tesla
 * (238×212, ratio 1.12) and SentinelOne (868×496, ratio 1.75) both rendered at exactly
 * 321×56 — the FULL max-width AND the FULL max-height simultaneously, aspect ratio
 * discarded — while Luminar rendered at its correct 321×50. Same root shape as other
 * bugs this project has hit: the design's own logos are all wide enough that this
 * exact edge case never fires for them, so the verbatim CSS never needed to handle it —
 * ours are real, live-sourced assets, some of which are shaped differently than the
 * design assumed.
 *
 * `object-fit: contain` sidesteps the ambiguity entirely: whatever box the width/height
 * calculation lands on, the image content scales to fit inside it without distorting,
 * letterboxed rather than stretched. Verified: Tesla's logo now renders as its actual
 * near-square "T" mark, not stretched into a wide bar.
 */
.mtile-logo {
  object-fit: contain;
}

/* ⚠️ `align-self: flex-start` used to live on `.mtile-logo` above, and that was a bug —
 * fixed 2026-09-11 after the owner reported mosaic logos sitting high in their tiles.
 *
 * It was added for the FLAGSHIP case, where `.mtile-feat-body` is a `flex-direction:
 * column` container so the cross axis is HORIZONTAL and flex-start means flush left.
 * But `.mtile-logo` is on every tile logo, and an ordinary tile wraps its logo in a
 * `flex-direction: row` box — there the cross axis is VERTICAL, so the same declaration
 * pushed the logo to the TOP of the tile instead of centring it. Measured before the fix:
 * every ordinary logo sat 35-50px above its tile's centre, horizontally centred but not
 * vertically.
 *
 * The design has no such conflict because it sets this inline on the featured <img> only
 * (`style={{ ..., alignSelf: 'flex-start' }}` in TWGMosaicTile, export-westly-v2/twg/
 * pages-main.jsx) — so scoping it to the flagship body is what the design actually does. */
.mtile-feat-body .mtile-logo {
  align-self: flex-start;
}

/* Flagship logos should sit flush left within the tile, not centered.
 * `.mtile-feat-body { display: flex; flex-direction: column }` (verbatim) has no
 * `align-items` of its own, so the default `stretch` applies on the cross axis
 * (horizontal, for a column container). For a replaced element with an intrinsic
 * aspect ratio (the logo, especially now `object-fit: contain` is set), browsers exempt
 * it from actually stretching — but where the *leftover* space then goes is left to the
 * browser's stretch-fallback behavior, which isn't consistently flex-start. Every wide
 * logo (Procore, Luminar) already happened to look flush-left simply because they fill
 * most of the available 62% width regardless of alignment — it only became visible once
 * Tesla and SentinelOne were narrow enough (after the object-fit fix above) for the gap
 * to show. `align-self: flex-start` makes it explicit and consistent for every flagship
 * logo regardless of its own width, matching what the wide logos already looked like by
 * coincidence.
 */

/* LP-grid logos with a link render left-aligned instead of centered.
 * `.lp-cell { display: flex; align-items: center; justify-content: center }`
 * (site.css, verbatim) centers its DIRECT flex child. `lp-logo-grid.php` /
 * `network-hero.php` wrap the `<img>` in `<a href="...">` whenever the company has a
 * real URL — which most of them do — making the anchor, not the image, the actual flex
 * item. The anchor auto-blockifies (a flex item always does) and renders at very close
 * to the cell's full width, and the `<img>` inside it — an ordinary inline replaced
 * element with nothing centering it *within its own parent* — sits flush against the
 * anchor's left edge. Logos with no company URL skip the `<a>` wrapper entirely and
 * render as a direct flex child, which is why most of the grid looked fine: only linked
 * logos were ever affected, and only enough to notice on a wide-enough logo (Hitachi
 * Energy, ratio 5.9:1, off by 27px) for the empty space on the right to be obvious.
 * `display: contents` removes the anchor from the box model entirely — the browser
 * treats its child as if it were promoted to be the flex item directly, so `.lp-cell`'s
 * own centering applies to the image with nothing in between. Verified directly in the
 * browser before writing this: Hitachi Energy's offset from center went from -27px to
 * 0px, with no other change.
 */
.lp-cell a {
  display: contents;
}

/* Founder form's Submit button renders as a full-width white bordered box instead of
 * the design's filled blue primary button.
 * The design (pages-rest.jsx) wraps its submit in `<Button variant="primary">`, i.e. the
 * same `.btn.btn-primary` used everywhere else on the site — auto-width, filled
 * `--color-primary` background, white text. But `.cform input` (site.css, verbatim)
 * targets every `<input>` inside `.cform`, submit included, with `width:100%; background:
 * #fff; border:1px solid var(--color-border-strong)`. That selector is class+type
 * (0,1,1) — more specific than `.btn-primary` alone (0,1,0) — so it wins the cascade
 * regardless of source order, leaving the button looking like an empty text field.
 * `.cform` was never designed with a submit INPUT in mind: the original JSX's `.cform`
 * only ever wrapped real `<input type="text">` fields, with the button as a sibling
 * `<Button>` component outside that styling's reach entirely. This form's `[submit]` tag
 * (via Contact Form 7) IS an `<input>`, so it collides with a rule that was never meant
 * to reach it. Fixed with a more specific selector for the submit type specifically.
 */
.cform input[type="submit"] {
  width: auto;
  background: var(--color-primary);
  color: #fff;
  border: none;
  cursor: pointer;
}
.cform input[type="submit"]:hover {
  background: var(--color-primary-hover);
}

/* Fund cards v2 — the "Built to back founders all the way" section, About page.
 * Wholesale redesign to owner spec (not from export-westly/twg/pages-main.jsx, which the
 * old `.fund-card`/`.fund-spec` rules in site.css still mirror verbatim) — a horizontal
 * card: a fixed-width illustration panel with an overlaid headline, and a content panel
 * with an icon badge, title + stage chip, body copy, and a fund-size stat in the footer.
 * New class names rather than editing `.fund-card`, so site.css/kit.css stay
 * byte-diffable against the ported design — those old rules simply go unused now.
 * Markup: render/fund-grid.php. `.fund-grid` itself (the two-column grid + gap on the
 * dark section background) is untouched, verbatim, and still does the outer layout.
 *
 * Font families: mapped to the site's locked tokens (see that file's header comment) —
 * `--font-display` (Montserrat) in place of the spec's Manrope, `--font-body`
 * (Source Sans 3) in place of Inter.
 */
.fund-card2 {
  display: flex;
  height: 100%;
  background: #fff;
  border-radius: 16px;
  border: 1px solid rgba(13, 33, 56, 0.1);
  box-shadow: 0 1px 3px rgba(13, 33, 56, 0.06);
  overflow: hidden;
}
.fund-illo {
  flex: none;
  width: 230px;
  background: #eef2f7;
  overflow: hidden;
  position: relative;
}
.fund-illo svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* `.sect-dark p, .sect-deep p { color: var(--color-fg-2-on-dark) }` (site.css, verbatim)
 * is class+type (0,1,1) — more specific than `.fund-illo-head` alone (0,1,0) — and wins
 * regardless of source order, leaving the headline in the pale "body text on dark
 * background" color instead of the spec's solid navy. `.fund-illo .fund-illo-head`
 * (0,2,0) outranks it.
 *
 * Font-size is 18px, not the spec's 19px. On the Seed card, "Capital for day one" is
 * meant to fit on one line with "founders." wrapping alone to line two (owner's
 * reference). At 19px it measured 197px against the 194px available width (230px panel
 * minus 18px padding each side) and wrapped a word early, splitting the `.hl` highlight
 * pill itself across two lines — ugly, and not what the reference shows. The 3px gap is
 * the Montserrat-for-Manrope substitution noted above: Montserrat's letterforms run
 * wider, so 19px of it doesn't fit where 19px of Manrope would have. Confirmed directly
 * in the browser by sweeping font-size on the live element and checking
 * `Range.getClientRects()` on the `.hl` span for a single rect (one line) vs two — 18.5px
 * was the exact threshold; 18px keeps a safety margin rather than shipping on the edge.
 */
.fund-illo .fund-illo-head {
  position: absolute;
  left: 18px;
  top: 18px;
  right: 18px;
  margin: 0;
  font: 700 18px/1.3 var(--font-display), sans-serif;
  color: #0d2138;
}
.fund-illo-head .hl {
  background: #5b9bd5;
  color: #fff;
  padding: 0 5px;
  border-radius: 3px;
}
.fund-body2 {
  flex: 1;
  min-width: 0;
  padding: 24px 15px;
  display: flex;
  flex-direction: column;
}
.fund-icon2 {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 10px;
  background: #0d2138;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 16px;
}
/* Title + chip must stay on one line (spec) — but "Venture & Growth Fund" +
 * "Series A – Early Growth" don't both fit in the ~294px the content panel had at its
 * original 26px padding/10px gap/10.5px chip/18px title: measured live at 358px content
 * vs 294px available, a 64px overflow clipped by `.fund-card2`'s `overflow:hidden`,
 * cutting the chip off mid-word. `.fund-grid` is a real two-column grid inside the
 * site's normal ~1240px container — widening the container itself risked reintroducing
 * the site-wide horizontal-overflow bug this project hit twice already (see the
 * `overflow-x` gotcha in CLAUDE.md), so the fix trims the row's own footprint instead:
 * tighter side padding (26px→15px), a smaller gap, and a modest chip/title size
 * reduction. Sized empirically, not guessed — swept combinations live against the
 * actual measured content vs. available width until a real double-digit-px margin
 * appeared (10px), not a value that only just clears zero. Deliberately did NOT touch
 * `.fund-illo`'s width to gain more room: that's shared with the illustration headline's
 * text box, and shrinking it re-broke that headline's own line-wrap fix (Round
 * twenty-two) — confirmed by testing and reverting when it did.
 */
.fund-title-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  /* Round 24: was `nowrap`. The Round 22 tuning made "Venture & Growth Fund" + its chip fit
     the panel at 1440px, but the card keeps its two-column shape all the way down to the
     767px breakpoint, and the panel shrinks with it — measured at a 1000px viewport the row
     needed 306px in a 196px panel and the chip was clipped. Wrapping drops the chip under
     the title when it no longer fits, at any width, without re-tuning magic numbers or
     widening the container (which risks the site-wide overflow-x bug). */
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.fund-title-row h3 {
  margin: 0;
  font: 800 16px var(--font-display), sans-serif;
  color: #0d2138;
  /* Round 24: was `nowrap`, which kept "Venture & Growth Fund" on one line at 1440px but
     overflowed its own box by 5px once the panel narrowed to 196px (measured at a 1000px
     viewport). Wrapping changes nothing at full width — the title is 201px in a 346px panel
     there — and lets it take a second line instead of being clipped when it cannot fit. */
  white-space: normal;
}
.fund-chip {
  font: 600 9px var(--font-body), sans-serif;
  background: rgba(13, 33, 56, 0.06);
  color: rgba(13, 33, 56, 0.55);
  padding: 3px 5px;
  border-radius: 20px;
  white-space: nowrap;
}
.fund-body2 > p {
  margin: 0;
  font: 400 13.5px/1.55 var(--font-body), sans-serif;
  color: rgba(13, 33, 56, 0.6);
}
.fund-footer2 {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid rgba(13, 33, 56, 0.08);
  font: 400 13px var(--font-body), sans-serif;
  color: rgba(13, 33, 56, 0.55);
}
.fund-footer2 strong {
  font: 800 13px var(--font-display), sans-serif;
  color: #0d2138;
}
/* Round 24: the footer carries two figures now (fund size, then check size). Wrapping
   each in .fund-figure and laying them out as a wrapping flex row keeps them on one line
   where there is room and breaks cleanly where there is not — the card is width-critical
   (see the Round 22 note above), so this must never force the panel wider. */
.fund-footer2 {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
}
.fund-figure {
  /* Each figure gets its own line. They already stacked at 1440px (the panel is 346px there
     and the two do not fit side by side), so this matches the wide layout exactly while
     removing the overflow that `white-space: nowrap` caused in a narrower panel — measured
     211px of content in a 196px box at a 1000px viewport. */
  flex: 1 1 100%;
}
@media (max-width: 767px) {
  .fund-card2 {
    flex-direction: column;
  }
  .fund-illo {
    width: 100%;
    height: 180px;
  }
}


/* ---------- Reduced motion: deliberately NOT honoured ----------
   Owner decision, 2026-09-15: every animation runs for every visitor, whatever their OS
   "Reduce Motion" setting. A `@media (prefers-reduced-motion: reduce)` block that stopped
   .pf-dot-live, .pf-rule, .gs-word and .gs-underline (added Round 24) was removed. site.css's
   `body.twg-no-motion` rules stay verbatim and inert — nothing sets that class. Do not add
   reduced-motion handling back without asking the owner. */


/* ---------- Team photo alignment (owner request, 2026-09-11) ----------
   Two cases, not one. The first attempt top-aligned EVERY portrait, which the owner
   corrected: short bios should keep the design's centred look.

   - Short bio: the row is taller than the bio, so `.t-bio`'s own `justify-content: center`
     centres the text and `.t-photo { align-self: center }` (site.css, verbatim) centres the
     portrait against it. Nothing to change — that is the default below.

   - Long bio: the bio drives the row height (Steve Westly's is 1483px against a 400px
     photo), so its text starts at the column's `padding-top` while a centred portrait floats
     ~541px down, disconnected from the name. Here the portrait should start level with the
     top of the name — `align-self: start` plus a top margin equal to `.t-bio`'s padding-top,
     which is exactly where the <h3> begins.

   CSS cannot express "taller than my sibling", so js/team-photo-align.js measures each row
   and adds `.t-row-tall`. With JS off, every row keeps the design's centred default — the
   readable outcome, not a broken one.

   Scoped above 767px: below that the row is single-column and site.css already handles the
   stacked case with its own `.t-photo { margin-top: 8px }`. */
@media (min-width: 768px) {
  /* Reversed rows (photo on the right) wrap the photo and bio in `.t-order-photo` /
     `.t-order-bio` — the design's own markup (pages-rest.jsx). Those wrappers become the grid
     items, so `.t-photo { align-self: center }` and `.t-bio`'s vertical centring never reach
     them: every reversed row had its photo pinned to the top and its bio text top-heavy
     (measured 0px above / 20px below the photo, vs 10/10 on normal rows). The design ships
     the same quirk, but it breaks the owner's "short bio = centred photo" rule on every other
     row. Making each wrapper a flex box lets the children align exactly as they do when they
     are grid items themselves. */
  .t-order-photo { display: flex; align-items: center; }
  .t-order-bio { display: flex; }
  .t-order-bio > .t-bio { flex: 1 1 auto; }

  .t-row-tall .t-photo {
    align-self: start;
    /* --t-photo-offset is written by js/team-photo-align.js from the bio's MEASURED
       padding-top plus the heading's top margin — the same number its threshold uses — so
       the offset and the switch point can never drift apart. The token is only a fallback. */
    margin-top: var(--t-photo-offset, var(--space-7));
  }
}


/* ---------- News: featured story image (owner request, 2026-09-11) ----------
   The design's `.news-feature-mark` is built for a company LOGO — a padded blue-50 panel
   with `img { max-width: 78%; max-height: 96px }` (site.css, verbatim, left untouched).
   Live's featured story carries a PHOTOGRAPH instead (85 of 87 posts have one, editorial
   images from square to ~2.2:1), and a photo capped at 96px rendered as a ~128x96 thumbnail
   adrift in a much larger box. render/news-grid.php now marks the panel `--photo` and asks
   for the `large` size, and this lets the image fill it.

   Two columns: the panel stretches to the text column's height and the photo covers it.
   ⚠️ `cover` crops. A ~4:3 photo loses almost nothing; a wide banner pinned as the lead
   (e.g. a 1331x606 image) shows roughly its middle and loses both ends. The alternative is
   `object-fit: contain` on the blue panel, which never crops but letterboxes. */
.news-feature-mark--photo {
  position: relative;
  align-self: stretch;
  min-height: 260px;
  padding: 0;
  overflow: hidden;
}
.news-feature-mark--photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  object-position: center;
}
/* Single column (site.css switches .news-feature at 860px): there is no text column beside
   the panel to take its height from, and an absolutely-positioned image gives the panel no
   height of its own — so it would collapse. A fixed ratio gives it one. */
@media (max-width: 860px) {
  .news-feature-mark--photo {
    min-height: 0;
    aspect-ratio: 4 / 3;
  }
}


/* ---------- Hidden icon swaps (fix, 2026-09-15) ----------
   The nav burger (menu/X) and the ticker pause button (pause/play) each swap two inline SVGs
   with the `hidden` attribute. Browsers only guarantee `[hidden]{display:none}` for HTML
   elements, and site.css/kit.css style these SVGs as blocks, so the "hidden" icon kept
   rendering beside the visible one — both icons showed at once. Scoped to the two buttons. */
.nav-burger svg[hidden],
.ticker-toggle svg[hidden] { display: none; }

/* ---------- Mobile nav logo/burger sizing (owner-reported, 2026-09-15) ----------
   kit.css's `.nav-logo{height:26px}` is a single fixed value used at every width — on a
   phone-width nav there's little else beside it, so the wordmark reads as illegibly small
   next to the 24px burger icon. Bump both together, mobile only, so they stay visually
   matched — desktop is untouched. */
@media (max-width: 767px) {
  .nav-logo { height: 34px; }
  .nav-burger svg { width: 30px; height: 30px; }
}

/* ---------- Blueprint diagram, mobile layout (owner-reported 2026-09-15, matched to a
   client reference mockup 2026-09-16) ----------
   render/blueprint-diagram.php now emits two SVGs: `.bp3-desktop-wrap` (the ported
   1400x530 SVG, unchanged) and `.bp3-mobile-wrap` (a portrait SVG built in the same
   drafting-sheet theme — grid paper, corner brackets, mono-font refs/captions — flowing
   the four criteria top-to-bottom with connecting arrows). Only one is ever visible at a
   time; both are real SVGs so no separate icon/text CSS is needed here. */
.bp3-mobile-wrap { display: none; }
@media (max-width: 767px) {
  .bp3-desktop-wrap { display: none; }
  .bp3-mobile-wrap { display: block; }
}

/* ---------- Home hero headline size (owner-requested, 2026-09-15; desktop value fixed
   2026-09-16 — LOCAL ONLY, not yet pushed) ----------
   A deliberate departure from the design: kit.css's base `.hero h1` rule already sets
   font-size:var(--fs-display) (the largest scale token — tokens.css even comments it
   "44 -> 72 hero"), but site.css's own later, equally-specific `.home-hero h1` rule
   overrides it down to clamp(24px, 3.4vw, 44px) — which computes to a 24px minimum on
   phone widths, smaller than the --fs-h2 heading right below it ("Where we invest").
   Owner asked for the hero to read as the largest text on the page. Using
   var(--fs-display) unscoped (first pass, pushed live 2026-09-16) also grew desktop to
   72px at wide viewports, which was never asked for there — owner settled on a flat 44px
   for desktop (the design's own pre-fix ceiling). The mobile media query below still wins
   under 767px. */
.home-hero h1 { font-size: 44px; }

/* ---------- Home hero headline — mobile scaling (owner-requested, 2026-09-16) ----------
   The unscoped rule above renders var(--fs-display) at its floor (44px) across every phone
   width from ~320 to ~560px — the rem term in --fs-display's own clamp() formula
   (1.6rem + 4.6vw) dominates the vw term that small, so it reads as flat/oversized rather
   than scaling with the viewport the way it visibly does on desktop. Owner asked the hero
   to keep the SAME text-size-to-screen-width ratio mobile has on desktop, this one place
   only. Desktop settles at 72px at a 1440px viewport — a 5% ratio — so `5vw` reproduces
   that same ratio here; the 28px floor keeps it above the mobile --fs-h2 heading nearby
   (never smaller than the "largest on the page" requirement from the previous fix), and
   the 44px ceiling matches the pre-fix mobile value so nothing regresses past it before
   the desktop rule above takes over at 767px. */
@media (max-width: 767px) {
  .home-hero h1 { font-size: clamp(28px, 5vw, 44px); }
}

/* ---------- News pagination (fix, 2026-09-15) ----------
   Fresh styling — home.php renames paginate_links()'s wrapping class to
   .twg-pagination-links precisely so it no longer collides with kit.css's nav `.nav-links`
   rule (see the comment in home.php); nothing in the design ports pagination styling at
   all, since the design's own News is a client-side link roll with no page 2. */
.twg-pagination-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 24px 0 48px;
}
.twg-pagination-links .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  height: 40px;
  padding: 0 12px;
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--color-fg-2);
  text-decoration: none;
  border: 1px solid var(--color-border);
}
.twg-pagination-links .page-numbers.current {
  background: var(--navy-800);
  border-color: var(--navy-800);
  color: #fff;
}
.twg-pagination-links a.page-numbers:hover {
  border-color: var(--navy-800);
  color: var(--navy-800);
}
.twg-pagination-links .page-numbers.dots {
  border: none;
  min-width: auto;
  padding: 0 4px;
}
.twg-pagination-links .prev.page-numbers,
.twg-pagination-links .next.page-numbers {
  padding: 0 16px;
  width: auto;
}
@media (max-width: 767px) {
  .twg-pagination-links { gap: 6px; }
  .twg-pagination-links .page-numbers { min-width: 36px; height: 36px; padding: 0 10px; font-size: 12px; }
}
