/* ============================================================
 * Tiptree site stylesheet (2026-09-11).
 * The homepage's page-level CSS, moved out of home_v1.html verbatim so a
 * second page (research) can share the chrome: tokens, glass buttons, the
 * nav, the band system, the lattice, the heading register, the ruled-frame
 * grammar, the people cards, the door, the footer and the mobile pass.
 * Relative url() paths were page-relative and are rewritten to this file's
 * location. Page-specific sections keep their homepage names; the research
 * page's own rules are at the end.
 * ============================================================ */
/* ============================================================
 * Homepage layout v1 — page-level CSS.
 * Consumes design-system tokens; additions marked EVOLUTION are
 * proposed marketing-scale extensions of the heading register.
 * ============================================================ */

:root {
    --section-gap: 5rem; /* 80px per side -> a single 160px gap between bands */
    /* docs-hub var aliases for the imported card scenes */
    --brand-teal-light: var(--brand-light-blue);
    --brand-teal-dark: var(--brand-dark-blue);
    --color-text-secondary: var(--text-secondary);
    /* Body text dropped page-wide from 17px to 16px (EVOLUTION 2026-08-10). */
    --text-large-size: 1rem;
    /* Page surface. #171717 until 2026-09-09; now the tone the old well
     * reached at its centre, so nothing on the page is darker than it
     * already was at its darkest (Ivan: "make it darker"). */
    --surface-canvas: #0e0e0e;
    /* Alternate band surface: same family, darker, for section alternation. */
    --surface-canvas-alt: #0b0b0b;
    /* Mockup-placeholder surface (Ivan 2026-08-11): hero-frame stroke, lifts
       one step off the page. Off the stone scale on purpose; fold into
       brand.css if it stays. */
    --surface-mock: #121212;   /* one step above the canvas, as before (+4) */
    /* Primary buttons: brand dark-blue instead of the off-white invert pill. */
    --action-primary-bg: #47696b;
    --action-primary-bg-hover: #3a5759;   /* darkens on hover */
    --action-primary-bg-pressed: #2d4345;
    --action-primary-fg: var(--brand-white);
}

/* The design-system .button-primary hardcodes color:var(--surface-canvas)
   (dark text for its default off-white pill) — override to white to match
   our teal fill (auth-btn-primary already uses --action-primary-fg). */
.button-primary { color: var(--action-primary-fg); }

/* ---------- Buttons in glass (Ivan 2026-08-24) ----------
 * The page's actions join the material the demos are built from: a flat
 * tint over a blurred, saturated backdrop, a rim lit from the top-left,
 * and layered shadows instead of a border. Same recipe as the demo
 * surfaces, at button scale — the tint carries the register (deep teal =
 * primary, near-black = secondary) and the rim does the lifting.
 *
 * PAGE-LOCAL on purpose: .button comes from the vendored design system,
 * which three products consume. Promote upstream only on a deliberate
 * version bump. */
.button-primary, .button-secondary, .auth-btn-primary, .auth-btn-secondary {
    position: relative;
    isolation: isolate;
    border: 0;
    backdrop-filter: blur(20px) saturate(1.5);
    -webkit-backdrop-filter: blur(20px) saturate(1.5);
    box-shadow:
        0 1px 2px rgba(0, 0, 0, 0.28),
        0 6px 18px rgba(0, 0, 0, 0.22);
}
/* the rim: a 1px ring, brightest at the top-left, masked to the edge only */
.button-primary::after, .button-secondary::after,
.auth-btn-primary::after, .auth-btn-secondary::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    pointer-events: none;
    background:
        radial-gradient(38% 60% at 22% 6%,
            rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0) 76%),
        rgba(255, 255, 255, 0.13);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
    transition: background 0.15s linear;
}
/* PRIMARY: deeper teal than the old flat fill, and translucent so the
 * page reads through it */
.button-primary, .auth-btn-primary {
    background: rgba(46, 88, 90, 0.82);
    color: var(--action-primary-fg);
}
.button-primary::after, .auth-btn-primary::after {
    background:
        radial-gradient(38% 60% at 22% 6%,
            rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0) 76%),
        rgba(167, 215, 214, 0.3);   /* the rim takes the teal */
}
/* SECONDARY: darker than the surface it sits on, so it reads as a well
 * rather than a raised chip */
.button-secondary, .auth-btn-secondary {
    background: rgba(28, 30, 30, 0.72);
    color: var(--text-primary);
}
@media (any-hover: hover) {
    .button-primary:hover, .auth-btn-primary:hover { background: rgba(58, 104, 106, 0.9); }
    .button-secondary:hover, .auth-btn-secondary:hover { background: rgba(40, 43, 43, 0.82); }
    .button-primary:hover::after, .button-secondary:hover::after,
    .auth-btn-primary:hover::after, .auth-btn-secondary:hover::after {
        background:
            radial-gradient(38% 60% at 22% 6%,
                rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 76%),
            rgba(255, 255, 255, 0.2);
    }
}
.button-primary:active, .auth-btn-primary:active { background: rgba(38, 76, 78, 0.86); }
.button-secondary:active, .auth-btn-secondary:active { background: rgba(20, 22, 22, 0.78); }
@media (prefers-reduced-transparency: reduce) {
    .button-primary, .button-secondary, .auth-btn-primary, .auth-btn-secondary {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
    .button-primary, .auth-btn-primary { background: #2e585a; }
    .button-secondary, .auth-btn-secondary { background: #1c1e1e; }
}

html { scroll-behavior: smooth; scroll-padding-top: 84px; }

body {
    /* Flat. The reverse vignette that darkened the centre line (the "well")
     * went with the darker canvas on 2026-09-09: it was fixed to the
     * viewport and centred at 44%, so on a phone it sat behind the hero demo
     * as a dark blob, and once the whole page is that tone it has no job. */
    background: var(--surface-canvas);
    color: var(--text-primary);
    font-family: var(--font-family-sans);
    font-size: var(--text-large-size);
    line-height: var(--text-large-line-height);
    letter-spacing: var(--text-regular-letter-spacing);
    margin: 0;
}

.frame {
    max-width: 1440px;
    margin-inline: auto;
    padding-inline: max(env(safe-area-inset-left), 24px) max(env(safe-area-inset-right), 24px);
}

/* ---------- top nav: the docs TopNav organism, ported verbatim.
 * Marketing deltas are content-only (label text, link set, primary CTA);
 * classes, geometry, and behavior contracts stay the docs' own.
 * Marketing-only layout delta: the bar stays full-bleed (bg + border),
 * but its CONTENT is capped to the page frame (1024px) so the logo and
 * CTA align with the hero's edges. ---------- */
.top-nav { display: block; position: sticky; top: 0; z-index: 20; padding-inline: 0; height: auto; border-bottom: none; background: transparent; transition: background-color 0.2s ease; }
/* Background fades in once the page starts scrolling. */
/* the bar spans the viewport; only its CONTENT holds the 1160 frame.
 * It repaints the page's own fixed gradient, so the bar and the page
 * read as one surface — plus a whisper of a bottom stroke. */
.top-nav.is-scrolled {
    background: var(--surface-canvas);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.045);
}
.top-nav .top-nav-ghost-link { color: var(--text-primary); }

.top-nav-inner {
    max-width: 1204px;
    margin-inline: auto;
    padding-inline: max(env(safe-area-inset-left), 24px) max(env(safe-area-inset-right), 24px);
    /* 12-col grid matching the hero: logo at col 1, right group ends at col 12. */
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    column-gap: 24px;
    align-items: center;
    height: 64px;
}
.top-nav-inner > .top-nav-left { grid-column: 1 / 7; }
.top-nav-inner > .top-nav-right { grid-column: 8 / 13; justify-self: end; }
@media (width <= 940px) {
    .top-nav-inner { grid-template-columns: 1fr auto; column-gap: 16px; }
    .top-nav-inner > .top-nav-left { grid-column: 1; }
    .top-nav-inner > .top-nav-right { grid-column: 2; }
}

/* ---------- band system ----------
 * The live site's section-color story, rebuilt on tokens: canvas bands,
 * a citron band (brand yellow, the live "why" band), and ink bands
 * (brand black in BOTH themes; token scope re-declared locally).
 * Transitions are hard edges; the band's own padding carries the rhythm. */
/* Bands are transparent; the body carries the dark canvas so the fixed
 * dot-field shows through every section. */
.band { background: transparent; padding-block: var(--section-gap); position: relative; }
/* 128px BELOW every divider, matching the 128px above it. A divider closes a
 * section, so whatever opens next — a heading in the same band, a heading in
 * the next band, or the footer — starts 128px under the line and nothing
 * stacks its own section padding on top. */
.band:has(.diff-concessions-row) + .band,
.band:has(.team-quote-row) + .band,
footer:has(.footer-row) { padding-top: 0; }
.ruled:has(#show-h) .ruled-heading,
.band:has(#who-h) .ruled-heading,
.band:has(.door-cta-row) .ruled-heading { padding-top: 128px; }

/* No dividers between sections (2026-08-19). Every section that needs closing
 * already closes on its own framed row — a tapered rule with a dot at each
 * end, sitting on the grid. A second hairline in the gap between sections
 * only restated what the frame had already said. */
footer { position: relative; }
.band-alt { background: transparent; } /* EVOLUTION: sections transparent so the dot field shows through */

/* Full-height hero (claude.ai/login): fills the viewport under the 64px
 * sticky nav. Hero content centers; the institutions strip pins to the
 * bottom edge of the fold. */
.band-hero {
    --nav-h: 64px;                          /* sticky navbar height */
    --hero-pad: clamp(1.25rem, 4vh, 3rem);  /* shrinks on shorter screens */
    --peek: 88px;                           /* room left for the next band to peek */
    display: flex;
    padding-top: var(--hero-pad);
    padding-bottom: 0;
}
.band-hero > .frame {
    flex: 1;
    display: flex;
    flex-direction: column;
}
/* Althea dot-field: a filled disc of dots (the logomark), FIXED to the
 * viewport and scroll-reactive (blooms + fades as you scroll past the hero).
 * Sits behind all content; sections are transparent so it shows through. */
.hero-bg {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    z-index: 0;               /* the page's background layer (fills dark + dots) */
    pointer-events: none;
    display: none;            /* dot-field parked for now, to be reused differently */
}
/* Rail dots: Althea's stippled dots drift in the side margins (outside the
 * 1160 rails) and bump the vertical rails. Fixed, full-viewport, behind
 * content; the content column stays clear (dots are spawned in the margins). */
.rail-dots { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; height: 100lvh; z-index: 0; pointer-events: none; }
/* The lattice is VECTOR (2026-09-04): a CSS dot pattern the browser rasterizes
 * at native resolution on every screen, never resampled. It replaced a canvas
 * blit that was drawn at innerHeight but displayed at 100vh, which on iOS are
 * different heights, so the field was stretched ~1.14x from the moment it
 * appeared and every dot on the page was soft ("still a bit blurry", Ivan).
 * The same recipe as the diagram field: 1px dot, 1.4px stop, 10px module,
 * FAINT x CENTER_DIM = 0.05 x 0.72. The outer mask reproduces gfade: 92px
 * fades at the viewport's top and bottom, and the outer 6% of the width
 * dimmed to 30%. FIXED to the viewport (Ivan 2026-09-04: "I see the grid
 * scrolls now. Can we make it fixed?"): content moves over a still field.
 * The trade-off is that page rules sit exactly on a dot row only at scroll
 * positions that are multiples of the 10px module, invisible at this
 * alpha. The canvas above keeps only the sparse pool, the accent pools and
 * the lit dots, in the same fixed phase. */
.rail-lattice { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; height: 100lvh; z-index: 0; pointer-events: none;
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 92px, #000 calc(100% - 92px), transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0, #000 92px, #000 calc(100% - 92px), transparent 100%); }
.rail-lattice > i { display: block; position: absolute; inset: 0;
    background-image: radial-gradient(circle, rgba(255, 255, 255, 0.024) 1px, transparent 1.4px);   /* 0.036 until 2026-09-09: subtler on the darker canvas */
    background-size: 10px 10px;
    -webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.3) 0, #000 6%, #000 94%, rgba(0, 0, 0, 0.3) 100%);
    mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.3) 0, #000 6%, #000 94%, rgba(0, 0, 0, 0.3) 100%); }
/* Content sits above the fixed dot-field. */
main, footer { position: relative; z-index: 1; }


/* EVOLUTION 2026-08-10: the hero adopts the Althea section layout
 * (section-split header + showcase). Content-sized, standard band padding. */
.band-hero { display: block; position: relative; padding-block: 4rem 2rem; } /* the logos strip follows close beneath */
/* Swirling dot ring (ported from tiptreesystems.com hero). Page-level layer
 * behind all content; only the bottom half renders (equator at the showcase
 * middle) and it extends into the lower sections. */
.swirl-dots { position: absolute; left: 0; top: 0; width: 100%; z-index: 0; pointer-events: none; }
.band-hero > .frame { position: relative; z-index: 2; } /* above the z-index:1 rails so the showcase dots sit on top of both side rails */
/* The hero content uses the full 12 columns at the former 10-col width
 * (1160px, centered). STACKED, not split (Ivan 2026-08-25): the headline
 * runs the whole measure, the subheading sits under it, and the buttons and
 * the two stated facts share the row beneath. row-gap is the heading-to-sub
 * step, so the button row re-opens its own space with a margin. */
.hero-althea .section-split { max-width: 1160px; margin: 0 auto 4rem; align-items: center; row-gap: 1.5rem; }   /* 1rem -> 1.5rem: heading to sub, settled by eye (Ivan 2026-09-09) */
.hero-althea .showcase { max-width: 1160px; margin-inline: auto; }
.hero-althea .show-frame { grid-column: 1 / 13; }
/* Heading: the full measure, grid row 1. Literata's thinnest weight is 200.
 * 3rem, one register with every other section heading. */
.hero-althea .section-split > .section-head { grid-column: 1 / 13; grid-row: 1; font-size: 3rem; font-weight: 300; line-height: 1.1; margin: 0; text-align: left; }
/* The two entry buttons, on row 2 beside the subheading rather than on a
 * row of their own, and pushed to the right END of the measure (Ivan
 * 2026-08-25). The cell runs to column 13 and the row justifies to its end,
 * so they stay flush right whatever the labels are. */
.section-head-col { grid-column: 7 / 13; grid-row: 2; margin-top: 0; align-self: center; }   /* 6 -> 7: the sub took a sixth column (2026-09-09) */
/* the shared .hero-auth caps itself at 384px, which held the buttons 245px
 * short of the measure's right edge — released here so flex-end actually
 * reaches it (Ivan 2026-08-25) */
.section-head-col .hero-auth { text-align: right; max-width: none; width: 100%; }

/* Two entry buttons in a row, each hugging its content. */
.section-head-col .auth-oauth-row { display: flex; grid-template-columns: none; gap: 12px; justify-content: flex-end; }
.section-head-col .auth-oauth-row .auth-btn { width: auto; padding: 0 24px; }
/* Row 2 shares one line: the subheading, and the buttons beside it to its
 * right, the two centred against each other (Ivan 2026-08-25). Left-aligned
 * as a block — the right of the measure is deliberately left open. */
.section-sub-col { grid-column: 1 / 7; grid-row: 2; margin: 0; text-align: left; align-self: center; }   /* 5 -> 6 columns (2026-09-09): two sentences in two lines, no widow */
.section-sub-col .section-sub { margin: 0; text-align: left; }
/* Row 3: two stated facts, UNDER the buttons rather than beside them (Ivan
 * 2026-08-25). The list gap is zero because the DOT owns the spacing — a
 * flex gap on top of it would push the dot off centre between the facts. */
.hero-althea .section-split > .auth-points {
    grid-column: 1 / 13; grid-row: 3;
    display: flex; flex-flow: row wrap; justify-content: flex-start; column-gap: 0; row-gap: 8px;
    margin: 1rem 0 0; padding: 0; list-style: none; max-width: none;
}
/* Stated facts, not UI (2026-08-19): the pills are gone — the tick and
 * the control register carry the guarantee, and nothing up here competes
 * with the two real buttons beside it. */
.hero-althea .section-split > .auth-points li {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    color: var(--citron-300);
    background: none;
    border: 0;
    border-radius: 0;
    padding: 0;
}
/* No ticks (2026-08-19): a tick asks to be read as a checklist item. These
 * are two stated facts, so they are separated the way the rest of the page
 * separates facts — by a dot on the module. */
.hero-althea .section-split > .auth-points li::before { display: none; }
.hero-althea .section-split > .auth-points li + li::before {
    display: inline-block;
    content: '';
    width: 3px;
    height: 3px;
    border-radius: 999px;
    background: var(--citron-300);
    opacity: 0.55;
    margin: 0 14px;   /* equal both sides: the dot sits centred between the facts */
    flex: none;
}
/* The stage-native demo fills the whole cell (no card; the exchange is
 * written directly on the ruled stage). Mockup content, badge "Product
 * mockup"; verbatim strings swap in when the item-7 capture lands. */
/* the stage runs wider than the content column so the answer's side
 * plumes and the field's lift carry on past it and fade out */
.stage-main .hd-stage { width: calc(100% + 320px); margin-inline: -160px; height: 100%; }
/* Mobile: hero stacks to one column in DOM order (heading, subheading,
 * checks, then buttons under the checks). */
@media (width <= 940px) {
    .hero-althea .section-split { grid-template-columns: 1fr; row-gap: 28px; margin-bottom: 3rem; }
    .hero-althea .section-split > .section-head { grid-column: 1; grid-row: auto; }
    .hero-althea .section-sub-col { grid-column: 1; grid-row: auto; align-self: start; margin-top: 0.5rem; }   /* +0.5rem heading to sub on phones; the desktop row-gap does not apply here */
    /* stacked and left-aligned: the right-flush treatment only makes sense
     * while the buttons share a row with the subheading */
    .section-head-col { grid-column: 1; grid-row: auto; margin-top: 0; }
    .section-head-col .hero-auth { text-align: left; }
    .section-head-col .auth-oauth-row { justify-content: flex-start; }
    .hero-althea .section-split > .auth-points { column-gap: 0; }
.hero-althea .section-split > .auth-points { grid-column: 1; grid-row: auto; }
}

/* Institutions strip — its own band below the fold. */
 /* standard 80px each side -> 160px gaps */

/* Single dark colour across the whole page: band classes remain in the
 * markup as section seams, but all render on the same canvas. Rhythm and
 * hierarchy are carried by spacing and type, not background changes. */
.band-ink { background: transparent; margin: 0; padding: 0; }   /* footer rails continue straight from the section above */

/* Stack two sections inside one band: inner gap without band-break. */
.band .frame + .frame { margin-top: var(--section-gap); }

main { display: flex; flex-direction: column; }

.section-head {
    font-family: var(--heading-section-family);
    font-size: 1.75rem; /* EVOLUTION: marketing step between section (1.375) and page (2.5) */
    line-height: 1.25;
    letter-spacing: -0.015em;
    font-weight: 300; /* Literata's thinnest, matching the hero heading */
    margin: 0 0 12px;
    text-align: center;
}

/* Headings take the material's light: the letterforms are lit from the
 * top like the glass, falling to a cooler tone at the baseline, with a
 * faint shadow so they read as cut from the surface rather than painted
 * on it. (Excludes .door-close, whose per-letter reveal owns its color.) */
.section-head:not(.door-close),
.hero-althea .section-split > .section-head {
    background-image: linear-gradient(
        178deg,
        #ffffff 0%,
        color-mix(in srgb, var(--text-primary) 92%, transparent) 42%,
        color-mix(in srgb, var(--text-primary) 62%, transparent) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    text-shadow: 0 1px 14px rgba(0, 0, 0, 0.35);
    /* the clip's paint box must reach under the descenders, or the
     * tails of g/y/q get shaved at tight line-heights */
    padding-bottom: 0.16em;
    margin-bottom: -0.16em;
}

/* The hero's second line takes the citron in the same top-lit glass:
 * the span's own clip repaints just its line, so the light still falls
 * from a bright top to a dimmer baseline. */
.section-head .head-citron {
    background-image: linear-gradient(
        178deg,
        var(--citron-100) 0%,
        var(--citron-300) 42%,
        color-mix(in srgb, var(--citron-300) 62%, transparent) 100%);
    -webkit-background-clip: text;
    background-clip: text;
}


.m-br { display: none; }   /* phone-only line break; shown in the <=700 block */
.measure { max-width: 620px; }

.muted { color: var(--text-secondary); }


/* Section header split: heading (cols 1-5) · gap · body (cols 7-12). */
.section-split {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    column-gap: 24px;
    align-items: start;
    margin-bottom: 6rem;   /* 96px between the heading+subheading block and the content/mockup below */
}
.section-split > .section-head { grid-column: 2 / 7; font-size: 3rem; line-height: 1.1; margin: 0; text-align: left; }


/* ported from docs-new CardIllustrations.module.css (dark theme values) */


/* ---------- showcase: Althea capabilities as tabs ---------- */
.section-split > .section-sub { grid-column: 8 / 12; margin: 0; text-align: left; }
.section-split > .section-sub + .section-sub { margin-top: 1.25em; }
/* banner variant: the heading runs the full row, the two subs sit side by
 * side beneath it, top-aligned (the shared rule centers, which staggers
 * columns of unequal length) */
.section-split.split-banner { align-items: start; }
.section-split.split-banner > .section-head { grid-column: 1 / 13; grid-row: 1; }
.section-split.split-banner > .section-sub { grid-row: 2; margin-top: 2.5rem; }
.section-split.split-banner > .section-sub:nth-of-type(1) { grid-column: 1 / 6; }
.section-split.split-banner > .section-sub + .section-sub { grid-column: 7 / 12; }
/* the 3-column variant (team section): the subs sit in thirds, mimicking
 * the adv-grid below */
.section-split.split-3 > .section-sub:nth-of-type(1) { grid-column: 1 / 5; }
.section-split.split-3 > .section-sub:nth-of-type(2) { grid-column: 5 / 9; }
.section-split.split-3 > .section-sub:nth-of-type(3) { grid-column: 9 / 13; }


/* Network section: asymmetric split, heading left / stacked column right. */


/* 2026-08-11 (take two): sections share the hero's 1160px centered
   container, contents flush to its edges. Headings/subs mirror the hero's
   5·2·5; full-width stages span all 12. Mockups keep or gain width. */
.section-split { max-width: 1160px; margin-inline: auto; align-items: center; }
.section-split > .section-head { grid-column: 1 / 6; }
.section-split > .section-sub { grid-column: 7 / 13; }


.showcase { display: grid; grid-template-columns: repeat(12, 1fr); column-gap: 24px; }
/* Base showcase (the lower "Althea turns a question" section keeps this). */
.show-tabs-wrap { grid-column: 2 / 12; display: flex; justify-content: flex-start; margin-bottom: 24px; }
.show-tabs {
    display: inline-flex;
    gap: 4px;
    padding: 4px;
    border: var(--border-hairline) solid var(--border-default);
    border-radius: 999px;
}
.show-tab {
    border: 0;
    background: transparent;
    color: var(--text-secondary);
    font-family: var(--font-family-sans);
    font-size: var(--text-small-size);
    font-weight: var(--font-weight-medium);
    padding: 9px 18px;
    border-radius: 999px;
    cursor: pointer;
    transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.show-tab:hover { color: var(--text-primary); }
.show-tab[aria-selected='true'] { background: var(--stone-100); color: var(--brand-black); }
.show-panel[hidden] { display: none; }
.show-panel {
    grid-column: 2 / 12;
    aspect-ratio: 16 / 9;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 20px;
    background: var(--stone-900);
    padding: 32px;
}

/* Hero showcase only (scoped to .show-frame): tabs as a full-width header
 * row inside a 600px container. EVOLUTION 2026-08-10. */
.hero-althea .show-frame {
    grid-column: 1 / 13;
    height: 600px;
    display: flex;
    flex-direction: column;
    position: relative;
    background: none;
    border: 0;
    border-radius: 0;
    padding: 0;
}
/* Corner dots at the four outer crossings of the showcase frame. */
.show-frame .show-tabs-wrap { grid-column: auto; flex: none; display: block; position: relative; margin-bottom: 0; }
/* Tabs (2026-08-19): an Apple-style segmented control in the site's
 * CONTROL register — mono micro labels, short track — and the selection
 * sits RECESSED in a well rather than raised, so it reads as a position
 * the instrument is in, never as a button to press. */
.show-frame .show-tabs-wrap { padding-top: 22px; }
.show-frame .show-tabs {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    width: max-content;
    max-width: 100%;
    margin: 0 auto;
    gap: 0;
    padding: 4px;
    position: relative;
    border-radius: 16px;
    background: rgba(255, 255, 255, 0.035);
    backdrop-filter: blur(24px) saturate(1.3);
    -webkit-backdrop-filter: blur(24px) saturate(1.3);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
}
.show-frame .show-tab {
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 20px;
    border: 0;
    border-radius: 12px;   /* 16 minus the track's 4px padding: the well nests true */
    position: relative;
    z-index: 1;
    white-space: nowrap;
    text-align: center;
    background: none;
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    color: var(--text-quaternary);
    transition: color .25s ease;
}
.show-frame .show-tabs-wrap .show-step { display: none; }   /* the phone stepper's arrows; the <=700 block shows them. Specificity beats .lac-flip-btn's own display: grid, which sits later in the sheet */
.show-frame .show-tab:hover { color: var(--text-secondary); }
/* the selected segment: a well the light falls into, not a raised pill */
.show-frame .show-tab[aria-selected='true'] {
    color: var(--text-primary);
    background: rgba(0, 0, 0, 0.3);
    box-shadow:
        inset 0 1px 2px rgba(0, 0, 0, 0.55),
        inset 0 -1px 0 rgba(255, 255, 255, 0.07);
}

/* The mockup has NO container (2026-08-19, Linear-style): an opaque
 * GROUND that dissolves into the page at every edge. The fade lives on
 * that ground alone — the demo's panes and type stay crisp on top of it.
 * (The dot board carries its own edge falloff in the canvas engine.) */
.show-frame .show-panel {
    grid-column: auto;
    flex: 1 1 auto;
    min-height: 0;
    aspect-ratio: auto;
    background: none;
    padding: 0;
    position: relative;
    border-radius: 0;
    box-shadow: none;
    overflow: visible;   /* the stage runs past the column; nothing clips it */
}
.show-frame .show-panel::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    background: #0d0f0f;
    pointer-events: none;
    -webkit-mask-image:
        linear-gradient(to right, transparent 0, #000 9%, #000 91%, transparent 100%),
        linear-gradient(to bottom, transparent 0, #000 7%, #000 60%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
        linear-gradient(to right, transparent 0, #000 9%, #000 91%, transparent 100%),
        linear-gradient(to bottom, transparent 0, #000 7%, #000 60%, transparent 100%);
    mask-composite: intersect;
}
/* The ruled frame is back around the instruments (2026-08-19): side rails
 * at the content edges, full-width rules top and bottom, corner dots on the
 * four crossings. The mockup inside stays container-less — the frame reads
 * as measurement marks on the page, not as a box the demo lives in. */
.show-frame .show-cell {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}
.show-frame .show-cell > .show-panel { flex: 1 1 auto; min-height: 0; }
/* The demo badge: bottom-right of the cell, the tab track's own glass and
 * the control register's mono micro type, so it reads as an instrument
 * marking rather than a caption. Never intercepts the pointer. */
.show-badge {
    position: absolute;
    right: 16px;
    bottom: 12px;
    z-index: 6;
    pointer-events: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    /* exactly the tab's type: same family, size, and the selected tab's white */
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    line-height: 1;
    color: var(--text-primary);
    padding: 6px 10px 6px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.035);
    backdrop-filter: blur(24px) saturate(1.3);
    -webkit-backdrop-filter: blur(24px) saturate(1.3);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
}
/* the recording dot */
.show-badge::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 999px;
    background: var(--citron-300);
    box-shadow: 0 0 0 2px rgba(207, 212, 120, 0.18);
    flex: none;
}
@media (width <= 700px) { .show-badge { right: 8px; bottom: 8px; } }

.stage-main {
    position: relative;
    z-index: 1;   /* the demo rides above the fading ground */
    overflow: visible;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}


@media (width <= 940px) {
    .show-panel { aspect-ratio: auto; }
    .show-tabs { flex-wrap: wrap; border-radius: 20px; }
}

/* ---------- infra: 10-col zone, mockup 6 + pillar stack 4 ---------- */
/* Althea showcase, stacked (Ivan 2026-08-11): full-width stage, the
   moment/prompt/return cards as a 4-point row beneath it. */


/* Block 2 bento (Ivan 2026-08-11): diagram + Althea on top (7/5),
   Lacuna · Network · Runtime thirds below. Cards share the mock surface. */


/* Bottom cells (Ivan 2026-08-12): bare mark top-aligned, heading + text
   pushed to the bottom edge, body at the small token size (14px). */


.bento-diagram-frame { width: 100%; height: 100%; border: 0; }
/* Althea card now an equal second-row cell (inherits n+2 rules). */
/* Large animated Althea mark (Ivan 2026-08-12): slow orbit, the stippled
   disc turning; static under reduced motion. Auto margins center it and
   pin the text block to the bottom edge. */

/* Motion lives inside the SVG: each dot drifts on its own slow path;
   the file honors prefers-reduced-motion internally. */


/* Flipped variant: text on the left (4 cols), mockup on the right (5 cols).
   Sits on the darker band, so the mockup lifts to stone-900 for contrast. */


.pillar-icon {
    flex: none;
    width: 44px;
    height: 44px;
    border-radius: 12px;
    background: var(--stone-900);
    border: var(--border-hairline) solid rgba(255, 255, 255, 0.06);
    display: flex;
    align-items: center;
    justify-content: center;
}
.pillar-mark { display: block; }


/* ---------- map section: 10-col stage ---------- */


@media (width <= 940px) {
    .section-split { grid-template-columns: 1fr; row-gap: 20px; }
    .section-split > .section-head {
    margin-top: 4rem; grid-column: 1; }
    .section-split > .section-sub { grid-column: 1; }
    .section-split.split-banner > .section-head { grid-column: 1; }
    .section-split.split-banner > .section-sub,
    .section-split.split-banner > .section-sub:nth-of-type(1),
    .section-split.split-banner > .section-sub + .section-sub { grid-column: 1; grid-row: auto; margin-top: 0; }
    .section-split.split-3 > .section-sub:nth-of-type(1),
    .section-split.split-3 > .section-sub:nth-of-type(2),
    .section-split.split-3 > .section-sub:nth-of-type(3) { grid-column: 1; grid-row: auto; margin-top: 0; }
}


/* ---------- Literata cut pin ----------
 * The docs hub ships STATIC Literata instances (text cut, fixed opsz).
 * Our design-system file is Literata VARIABLE: at display sizes,
 * font-optical-sizing:auto engages the thin display cut and drifts from
 * the docs' rendering. Pin the text cut everywhere serif display runs.
 * (Design-system follow-up: encode this in brand.css.) */
/* Chrome's `none` freezes opsz at the font default (14, the text cut);
 * WebKit ignores `none` and keeps size-driven optical sizing, so Safari
 * headings rendered the thin display cut. Pinning the AXIS explicitly is
 * honored identically by both engines (measured: 613.0px vs 613.0px on the
 * hero headline probe). */
h1, h2, h3, .stat-n { font-optical-sizing: none; font-variation-settings: 'opsz' 14; }

/* ---------- hero: ElevenLabs structural pattern, Tiptree register ----------
 * Headline left / standfirst right (end-aligned), CTA pair, then the
 * full-width product panel: product tabs on top, one live frame per
 * product, capability rail + contextual CTA at the panel foot. */
/* Simple hero (claude.com pattern): 12-col grid, 32px gutters, two equal
 * halves. Left: centered stack (headline, subline, CTAs, microline).
 * Right: one product card. */
/* Hero (claude.ai/login pattern): on the 1440 / 12-col / 32px-gutter grid,
 * [1 empty][4 inputs][1 empty][6 mockup]. Inputs and the two empty spacers
 * are fixed; only the mockup (last track) is fluid, so it shrinks first and
 * the inputs never move. Below 940px it stacks (mockup slides under). */
/* ---------- Hero: heading + subhead/CTAs across the top, a full-width
 * product demo below. No full-height; the institutions band peeks. */
/* Two-column hero: text content left, product mockup right, full height. */


/* Mockup slot: fills the right column, image cropped to cover. */


/* Empty 16:9 placeholder block (product-dark surface, matches the mockup). */


/* Spec note shown inside an empty placeholder until the real mockup lands. */
.ph-note {
    max-width: 460px;
    margin: 0;
    padding: 24px;
    text-align: center;
    color: var(--stone-500);
    font-size: var(--text-mini-size);
    line-height: 1.55;
}
.ph-note b { color: var(--stone-400); font-weight: var(--font-weight-medium); }


.demo-sub { font-size: var(--text-mini-size); color: var(--text-tertiary); margin: 0; }


/* Bar chart — drift by model scale; the two smallest fall off (warn). */


/* Donut — where the answer came from. */


/* Side rail — dark cards keep the page's default (dark-context) tokens. */


/* Auth box — bordered card holding the sign-up options. */
.hero-auth {
    position: relative;
    width: 100%;
    max-width: 24rem;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.auth-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    height: 44px;
    border-radius: 999px;
    font-family: var(--font-family-sans);
    font-size: var(--text-regular-size);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    cursor: pointer;
    border: 0;   /* the glass rim replaces the stroke (see the glass-button block) */
    position: relative;
    transition: background-color 0.12s ease;
}

.auth-btn img, .auth-btn svg { width: 18px; height: 18px; flex: none; }

/* OAuth buttons stacked full-width (each carries its own "Continue with" label). */
.auth-oauth { display: grid; grid-template-columns: 1fr; gap: 12px; }

/* Left-aligned label above the sign-up box. */


/* Fill, rim, hover and active for the hero's pair live in the glass-button
 * block near the top of this sheet, beside .button-primary/.button-secondary
 * — ONE source for both button families. They used to be restated here, and
 * because these rules sit later at equal specificity they quietly won: the
 * hero kept the old flat fills while every other button went to glass. */
.auth-btn-primary img { filter: none; }

/* "or" divider between OAuth and email */


/* Email field with the submit button tucked inside. */


/* Notes under the auth box: same register as the .auth-or divider. */


/* The three comfort points: left-aligned to the auth box's edge, checked. */
/* The three comfort points as neutral pills, between subheading and auth box.
 * A wrapping row (never a forced stack); pills flow to the next line as needed. */
/* Borderless checked facts: no container, so they never read as controls. */
.auth-points { display: flex; flex-wrap: wrap; justify-content: center; column-gap: 18px; row-gap: 6px; margin: 0 0 36px; padding: 0; list-style: none; max-width: 30rem; }  /* two per row; the third wraps */
.auth-points li {
    margin: 0;
    white-space: nowrap;
    font-size: var(--text-mini-size);
    color: var(--text-secondary);
}
.auth-points li::before { content: "\2713"; color: var(--teal-400); margin-right: 7px; }


/* Right: product card spanning the 6-col track. */


/* Product panel: full-height light card (claude.com contrast move) — the
 * warm off-white, never pure white. Light-context tokens scoped inside. */


/* Mock composer pinned to the panel foot. */


@keyframes chat-pulse {
    0%, 60%, 100% { opacity: 0.25; }
    30% { opacity: 0.9; }
}


@media (width <= 940px) {
    .band-hero { min-height: 0; }
    
    
    
}


/* product panel */


/* proof frame */


/* logos strip — ElevenLabs pattern: quiet label + a wall of marks.
 * Ours are typographic wordmarks (real text: extractable, and precise —
 * "researchers at", never implied institutional endorsement). */


.hero-logos-label {
    grid-column: 2 / 12;
    font-size: var(--text-large-size);
    color: var(--text-secondary);
    margin: 0 0 14px;
    text-align: center;
}
.hero-logos-label.engine-label { text-align: center; }   /* beats .engine-label's left */

/* Technical line/dot grid framing the logos (EVOLUTION 2026-08-11).
 * Vertical side-lines at the content edges; horizontal lines run full-bleed;
 * corner dots are centered on the intersections with a 0.5rem clear halo. */
/* Ruled-grid line color: a touch more subtle than the default hairline
 * (blended toward the canvas), shared by every rail, rule, and divider. */
:root {
    --rule-line: color-mix(in srgb, var(--border-default) 55%, var(--surface-canvas));
    /* Solid hairlines that taper out at both ends (2026-08-19), the same
     * grammar as the section dividers: a rule states its span, then dissolves
     * into the field rather than stopping on a hard terminal. The rules land
     * ON the lattice because the lattice is anchored to them — the canvas
     * engine offsets its dot origin by railL mod 10 (see buildGrid). */
    --rule-h-taper: linear-gradient(90deg, transparent 0, var(--rule-line) 18%, var(--rule-line) 82%, transparent 100%);
    --rule-v-taper: linear-gradient(180deg, transparent 0, var(--rule-line) 18%, var(--rule-line) 82%, transparent 100%);
}

/* The taper is a soft edge on a long line and a defect on a short one. Below
 * 940px the three-column blocks stack, so those rules lie down INSIDE a cell
 * and run to its own terminal dots: an 18% fade then eats 135px a side of an
 * 892px line and reads as the line stopping short of its dots (Ivan, twice).
 * Horizontal rules go solid from the stacking point down. The vertical rails
 * keep their taper here, because those still run a full section height and
 * are what lets one section dissolve into the next. */
@media (width <= 940px) {
    :root {
        --rule-h-taper: linear-gradient(90deg, var(--rule-line) 0, var(--rule-line) 100%);
    }
}


/* Vertical side lines at the content edges. */


/* Horizontal lines extend the full viewport width, beyond the max-width. */
.logos-hline {
    position: absolute;
    /* the lattice nudge rides the INDEPENDENT translate property, never the
     * transitioned `transform`: the reveal animates transform for 1.05s, so a
     * nudge composed into it could not be zeroed instantly for measurement —
     * snapRules would read its own previous correction and re-correct it every
     * pass, and the rules visibly hunted for their row (2026-08-24) */
    translate: 0 var(--rule-nudge, 0px);
    /* the rule is CENTRED on the edge it marks (the corner dots are too), so
     * both measure the same document position and snap to the same row */
    margin-top: calc(var(--border-hairline) / -2);
    left: 0;
    width: 100%;                       /* contained to the 1160 max-width container (rail to rail) */
    height: var(--border-hairline);
    background: var(--rule-h-taper);
}
.logos-hline.top { top: 0; }
.logos-hline.bot { bottom: 0; margin-top: 0; margin-bottom: calc(var(--border-hairline) / -2); }
/* Corner dots centered on the intersections (lines enter the middle); the
 * box-shadow halo clears 0.5rem of the lines around each circle. */
.logos-tick {
    position: absolute;
    width: 5px;
    height: 5px;
    border-radius: 999px;
    background: var(--text-tertiary);
    transform: translate(-50%, -50%);
    translate: var(--rule-nudge-x, 0px) var(--rule-nudge, 0px);   /* nudges kept off `transform`, as on .logos-hline */
    z-index: 5;              /* always above the rails/rules at every crossing */
}
.logos-tick.tl { top: 0; left: 0; }
.logos-tick.tr { top: 0; left: 100%; }
.logos-tick.bl { top: 100%; left: 0; }
.logos-tick.br { top: 100%; left: 100%; }

/* ============================================================
 * Engine grid (EVOLUTION 2026-08-12): the logos frame's ruled
 * motif carried down through "Inside the infrastructure" as one
 * continuous system. The vertical side-lines now span the whole
 * block; horizontal lines stay full-bleed (.logos-hline); corner
 * and crossing dots reuse .logos-tick. The four cards are divided
 * by hairlines instead of sitting in separate surfaces.
 * ============================================================ */
.engine { max-width: 1160px; margin-inline: auto; }

/* ---- Front frame (EVOLUTION 2026-08-12): the ruled side-lines run as one
 * continuous system from the navbar, through the hero, and down through the
 * engine, all at the shared 1160 content edges (50% ± 580px, clamped to a
 * 24px gutter on narrow screens). Rails live on .top-nav and on .front and
 * meet at the nav/hero seam. ---- */
.front { position: relative; }
/* Vertical rails, strategic (2026-08-18): the full-height side rails are
 * retired; verticals appear only where they frame an instrument — the
 * navbar, and the hero demo cell below its tabs. */
/* Nav content aligns to the 1160 frame so the logo + links sit inside the rails. */
.top-nav-inner { max-width: 1160px; padding-inline: 2rem; }


/* Hero heading sits 2rem off the rails; the showcase spans to the rails so its
 * cell frame aligns with them (content padded inside, like the engine diagram). */
.band-hero .hero-althea .section-split { padding-inline: 2rem; }

/* End the front rails at the cards, not in the band's trailing padding. */
.engine-band { padding-top: 2rem; padding-bottom: 0; }

/* The label sits above the frame (no side-lines beside it), aligned
 * to the engine's 1160 content box. */
.engine-label { max-width: 1160px; margin: 0 auto 44px; padding-inline: 2rem; text-align: left; }

/* Each row anchors its own full-bleed hlines + corner dots. */
.engine-row { position: relative; }

/* Strategic verticals (2026-08-18): framed instruments get side rails —
 * the logo strip, the infra diagram, and the four cards under it. */


/* Interior column dividers. A border cannot taper and cannot be
 * nudged (moving it would move the cell's content), so the divider becomes an
 * absolutely positioned rule on the cell's leading edge: same tapered stroke
 * as every other line in the system, and free to shift up to half a module
 * onto a lattice column without touching layout. */
.stat-ruled .stat + .stat, .lac-col + .lac-col, .adv-grid .adv-card:not(:nth-child(3n + 1)), .door-fact + .door-fact { position: relative; }
.stat-ruled .stat + .stat::before, .lac-col + .lac-col::before, .adv-grid .adv-card:not(:nth-child(3n + 1))::before, .door-fact + .door-fact::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: var(--border-hairline);
    margin-left: calc(var(--border-hairline) / -2);
    background: var(--rule-v-taper);
    transform: translateX(var(--rule-nudge-x, 0px));
    pointer-events: none;
    z-index: 4;
}
@media (width <= 940px) {
    /* stacked: the divider lies down and runs across the top edge instead */
    .stat-ruled .stat + .stat::before, .lac-col + .lac-col::before, .adv-grid .adv-card:not(:nth-child(3n + 1))::before, .door-fact + .door-fact::before {
        top: 0; bottom: auto; left: 0; right: 0;
        width: auto; height: var(--border-hairline);
        margin-left: 0; margin-top: calc(var(--border-hairline) / -2);
        background: var(--rule-h-taper);
        transform: none;
    }
}

/* .vruled: the same side rails as a utility, for instrument rows inside
 * ruled sections (stage cards, Lacuna grids, diagrams, quote, door). */
.vruled::before, .vruled::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: var(--border-hairline);
    background: var(--rule-v-taper);
    pointer-events: none;
    z-index: 4;
}
.vruled::before { left: 0; margin-left: calc(var(--border-hairline) / -2); }
.vruled::after { right: 0; margin-right: calc(var(--border-hairline) / -2); }

.engine-logos { padding-block: 8px 128px; position: relative; }
/* a subtle divider closing the strip, fading out at both ends */
.engine-logos::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent 0,
        rgba(255, 255, 255, 0.055) 18%,
        rgba(255, 255, 255, 0.055) 82%,
        transparent 100%);
    pointer-events: none;
}

/* 1rem side-gutter keeps content off the rails; the hlines + corner dots
 * stay pinned to the row edges (rails), so the frame is unchanged. */
.engine-heading { padding: 8rem 2rem 4rem; }   /* 128px below the logos divider; 64px of air before the diagram */
.engine-heading .section-split { max-width: none; margin: 0; }

/* The model sits in the same glass slab as the hero showcase, with its
 * own pool of shadow beneath it. */
/* The model has no container either (2026-08-19): D1's own field is
 * switched off in the embed, so the PAGE grid runs straight through it —
 * one continuous field, same as the hero. The diagram just floats. */
.engine-diagram {
    position: relative;
    padding: 0.5rem 1rem 3rem;
    min-height: 520px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    overflow: visible;
}
/* it breathes past the column like the hero stage, so the model's own
 * edges dissolve instead of stopping at the frame */
.engine-diagram .bento-diagram-frame {
    width: calc(100% + 240px);
    margin-inline: -120px;
}
.engine-diagram .bento-diagram-frame { width: 100%; height: 100%; min-height: 520px; border: 0; }

/* Four cards divided by hairlines + dots (no separate surfaces). */
/* No divider under the four cards (2026-08-27): with the diagram now
 * directly below, the rule clashed with the diagram's own frame. */
.engine-cards-row::after { display: none; }
.engine-row.engine-cards-row { padding-bottom: 112px; }   /* 112 to the diagram's rule, down from the shared 128 */
.engine-cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: 40px; row-gap: 40px; padding: 56px 2rem 0; }
/* Sections that end on bare content rather than a framed instrument close
 * with a divider instead, 128px of air on both sides. The infra notes and the
 * differential's concessions share this treatment. */
.engine-cards-row,
.diff-concessions-row,
.team-quote-row,
.door-map-row { padding-bottom: 128px; position: relative; }
.engine-cards-row::after,
.diff-concessions-row::after,
.team-quote-row::after,
.door-map-row::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--border-hairline);
    background: var(--rule-h-taper);
    pointer-events: none;
}
/* Dividers between the four notes: hairlines that fade at both ends. */
.engine-card + .engine-card { position: relative; }
.engine-card + .engine-card::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: -20px;
    width: 1px;
    background: linear-gradient(to bottom,
        transparent 0,
        rgba(255, 255, 255, 0.055) 16%,
        rgba(255, 255, 255, 0.055) 84%,
        transparent 100%);
    pointer-events: none;
}
.engine-card {
    padding: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

/* Tilt on hover (2026-08-27, Ivan's ask; survives the Martin-batch rollback).
 * The ivank.work specimen gesture: pointer position normalised to -1..1
 * drives a small rotation. Perspective is per element (inside `transform`),
 * or every card in a row would share one vanishing point and the outer
 * ones would read as sheared. Centre pivot: a card in a row has no floor,
 * and hinging low reads as only the top edge moving. */
.engine-card, .art-plate, .adv-card {
    --tilt-amp: 3;
    transform:
        perspective(1600px)
        rotateX(calc(var(--tilt-y, 0) * var(--tilt-amp) * -1.2deg))
        rotateY(calc(var(--tilt-x, 0) * var(--tilt-amp) * 1.5deg));
    transform-origin: 50% 50%;
    transition: transform 360ms cubic-bezier(0.22, 0.86, 0.34, 1);
}
/* The demo surfaces cannot take a tilt on `transform`: they drive their own
 * entrances and exits with it. They take the INDEPENDENT `rotate` property,
 * which composes instead of replacing. Perspective must sit on the DIRECT
 * parent (.hd-log-track), or the rotation renders orthographically. */
.hd-chatlog, .hd-log-track, .hd-route { perspective: 1600px; }
.hd-chatlog .hd-bubble-user, .hd-chatlog .hd-response, .hd-chatlog .hd-doc,
.hd-chatlog .hd-table, .hd-chatlog .hd-verdict, .hd-chatlog .hd-reply,
.hd-chatlog .hd-trace, .hd-chatlog .hd-step {
    transition: rotate 360ms cubic-bezier(0.22, 0.86, 0.34, 1);
}
@media (hover: none), (prefers-reduced-motion: reduce) {
    .engine-card, .art-plate, .adv-card { transform: none; transition: none; }
    .hd-chatlog, .hd-log-track, .hd-route { perspective: none; }
}

.engine-card .pillar-icon {
    margin-bottom: 18px;
    background: none;
    border: none;
    width: auto;
    height: auto;
    border-radius: 0;
    padding: 0;
}
.engine-card h3 {
    margin: 0 0 0.5rem;
    font-family: var(--font-family-sans);
    font-size: 0.875rem;  /* 14px */
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}
.engine-card p { margin: 0 0 1.5rem; font-size: 0.875rem; line-height: var(--text-small-line-height); }   /* the button never sits flush to the copy */
/* Card CTA pinned to the bottom edge, so all four links line up. */
/* the four CTAs are secondary buttons, bottom-aligned so they line up */
.engine-card-link { margin-top: auto; }
.engine-cards .engine-card-link { margin-top: auto; align-self: center; }

@media (width <= 940px) {
    .engine-cards { grid-template-columns: 1fr; row-gap: 32px; padding-inline: 1rem; }
    .engine-card + .engine-card::before { display: none; }
    .engine-card { min-height: 0; }
    .engine-diagram, .engine-diagram .bento-diagram-frame { min-height: 0; }
}
/* Tablet (700..940): the embed is still LANDSCAPE here (its own portrait flip
 * is at 670px of iframe width), and a landscape stage sized 100% of an iframe
 * sized to its content collapses to nothing. Give the row a floor. */
@media (700px < width <= 940px) {
    .engine-diagram, .engine-diagram .bento-diagram-frame { min-height: 460px; }
    /* four notes as a 2x2 rather than one long column */
    .engine-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 40px; row-gap: 48px; }
}
@media (width <= 940px) {
    /* stacked cards have no vertical dividers, so drop the 1/4-mark dots */
    .logos-tick.mid { display: none; }
}

/* ---- Ruled section: the infrastructure-lines approach applied to a
 * standalone section (own 1160 rails, a rule under the heading, and cells
 * divided by hairlines + dots instead of separate surfaces). ---- */
.ruled { position: relative; max-width: 1160px; margin-inline: auto; }
/* Diagonal hatch: the standard "intentionally empty" fill (same recipe as the active tab). */

/* Section-level side rails retired (2026-08-18, strategic verticals):
 * headings and prose stay unruled; only instrument rows carry verticals
 * (see the engine-logos / engine-diagram / engine-cards-row pattern). */
/* A ruled section governs its own spacing via the frame's 160px heading
 * padding, so its band wrapper drops the section-gap padding (no extra
 * dead space above the heading). */
.band:has(.ruled) { padding-block: 0; }
.ruled-heading { position: relative; padding: 10rem 2rem 3.5rem; } /* 160px top, matches .engine-heading */
.ruled-heading .section-split { max-width: none; margin: 0; }
/* Circles always above the lines: lift the dot-bearing rows over the z-index:1
 * rails so reveal-transform stacking contexts can't trap dots beneath them. */
.engine-row, .ruled-heading, .hero-althea .showcase { position: relative; z-index: 2; }

.stage-ruled { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stage-rcell {
    position: relative;
    min-height: 0;
    padding: 56px 16px;   /* 32px between neighboring plates */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 36px;
    text-align: center;
}

/* ---- The specimen shelf: one glass material, three preparations. The
 * plates reuse the hero's Liquid Glass recipe (flat tint, deep blur, lit
 * top-left rim, layered depth); the meter and chips reuse its registers. ---- */
.stage-flow-canvas { position: absolute; top: 0; left: 0; z-index: 4; pointer-events: none; }   /* sized and offset by its script: it bleeds 120px past the host for the halos */
/* The origin: the hero's question, quoted. It hangs over the report column —
 * the section is that sitting's epilogue, so it opens with the same words. */
.stage-ask { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); padding: 56px 16px; }   /* 24 -> 56: more air above and below the question (Ivan 2026-09-09) */   /* 16px: the plates' own gutter, so the question's right edge meets the one-pager's */
.art-ask-wrap { grid-column: 1 / -1; justify-self: center; position: relative; }   /* centred on the section's axis, like the demo's question (Ivan 2026-09-09) */
.art-ask {
    margin: 0;
    max-width: 440px;
    text-align: left;
    font-size: var(--text-regular-size);   /* the hero bubble's own size */
    line-height: 1.55;
    padding: 32px 36px;      /* the demo bubble's own padding and radius (Ivan 2026-09-09) */
    border-radius: 24px;
}
@media (width <= 940px) { .art-ask-wrap { grid-column: 1 / -1; } }
/* Everything stands visible from the first paint (2026-08-26: the staged
 * reveal is gone); the canvas ferry dots are the only motion here. */
.stage-art { position: relative; width: 100%; }   /* fill the cell: the 16px gutters set the 32px gap */
.art-plate {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-height: 350px;   /* the reference: stage 2's natural height; 1 and 3 fill it with detail */
    max-width: none;
    padding: 22px 22px 20px;
}
/* chips pin to the plate's foot, so the shelf's bottom line is level */
.art-plate .art-chips { margin-top: auto; }
/* The static plumes (an SVG cone off each plate's flank and off the
 * question's speaking corner) went on 2026-09-09: the blocks wear the
 * demo's breathing halo instead (see the stage-flow script). */

.art-title {
    margin: 0;
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    letter-spacing: 0.02em;
    color: var(--text-primary);
}
/* the report's body: dim ruled lines, not fake words */
.art-lines { display: flex; flex-direction: column; gap: 7px; }
.art-lines i { height: 5px; border-radius: 3px; background: rgba(255, 255, 255, 0.07); }
.art-lines i:nth-child(2) { width: 92%; }
.art-lines i:nth-child(3) { width: 96%; }
.art-lines i:nth-child(4) { width: 58%; }
/* the LED meter, straight from the hero answer */
.art-fig { margin: 0; display: flex; flex-direction: column; gap: 8px; }
.art-figcap {
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    color: var(--text-primary);
}
.art-frow {
    display: grid;
    grid-template-columns: 52px 1fr auto;
    align-items: center;
    gap: 10px;
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    color: var(--text-primary);
}
.art-fdots {
    justify-self: start;
    width: calc(var(--n) * 8px);
    height: 4px;
    background-image: radial-gradient(circle, rgba(167, 215, 214, 0.8) 1.5px, transparent 1.9px);
    background-size: 8px 4px;
    background-repeat: repeat-x;
    background-position: left center;
}
.art-fval { color: var(--text-primary); }
.art-frow.art-hot .art-fdots { background-image: radial-gradient(circle, rgba(207, 212, 120, 0.9) 1.5px, transparent 1.9px); }
.art-frow.art-hot .art-fval { color: var(--citron-300); }
/* the comparison table, in the ruled grammar */
.art-table { display: flex; flex-direction: column; }
.art-trow {
    position: relative;
    display: grid;
    grid-template-columns: 48px 1fr auto;
    gap: 10px;
    padding: 6px 0;
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    color: var(--text-primary);
}
.art-trow + .art-trow::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: var(--border-hairline);
    background: var(--rule-h-taper);
}
.art-thead { color: var(--text-primary); }
.art-trow.art-hot span { color: var(--citron-300); }
/* the interactive figure: an embedded widget slot with a control row */
.art-widget, .art-embed {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 12px;
    border-radius: 8px;
    box-shadow: inset 0 0 0 1px rgba(167, 215, 214, 0.18);
}
.art-emblab {
    margin: 0;
    display: flex;
    justify-content: space-between;
    gap: 10px;
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    color: var(--text-primary);
}
.art-live { color: #a7d7d6; }
.art-wctrl { display: flex; align-items: center; gap: 10px; }
.art-wtrack { position: relative; flex: 1; height: 2px; border-radius: 1px; background: rgba(255, 255, 255, 0.14); }
.art-wknob {
    position: absolute;
    top: 50%;
    left: 38%;
    width: 10px;
    height: 10px;
    border-radius: 999px;
    transform: translate(-50%, -50%);
    background: var(--citron-300);
    box-shadow: 0 0 0 3px rgba(207, 212, 120, 0.18);
}
.art-wlab { font-family: var(--font-family-label-mono); font-size: var(--text-micro-size); color: var(--text-primary); }
/* the small mono facts inside documents: address, doc meta, attachments */
.art-to, .art-meta, .art-att { margin: 0; font-family: var(--font-family-label-mono); font-size: var(--text-micro-size); color: var(--text-primary); }
/* the one-pager's prose line + sent state */

.art-sent {
    margin: 0;
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    color: #a7d7d6;
}
/* the citation chips: pixel-identical in all three cells, on purpose */
.art-chips { display: flex; flex-wrap: wrap; gap: 8px; }
/* the source pills are the demo's glass chip, verbatim (Ivan 2026-08-31):
 * this had invented its own flat ring instead of reusing .hd-chip */
.art-chip {
    position: relative;
    background: rgba(255, 255, 255, 0.055);
    backdrop-filter: blur(6px) saturate(1.3);
    -webkit-backdrop-filter: blur(6px) saturate(1.3);
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    color: var(--text-primary);
    border: 0;
    border-radius: 999px;
    padding: 4px 11px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22), inset 0 0 0 1px rgba(255, 255, 255, 0.10);
}
/* captions in the engine-card register, verbatim (h3 + p.muted, same
 * sizes, weights, and spacing as the four notes under the infra diagram) */
.art-cap { margin: 0; max-width: 300px; order: -1; }   /* above the plates (Martin, 2026-08-27; the question bubble is gone, so they read as column heads) */
.art-cap h3 {
    margin: 0 0 0.5rem;
    font-family: var(--font-family-sans);
    font-size: 0.875rem;  /* 14px */
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
}
.art-cap p { margin: 0; font-size: 0.875rem; line-height: var(--text-small-line-height); }


@media (width <= 940px) {
    .stage-ruled { grid-template-columns: 1fr; }
    .stage-rcell { min-height: 320px; }

}

/* Lacuna: stats row + directions row as one 3-col ruled grid (shared vertical
 * dividers + dots). Stats are left-aligned; direction cards lose their separate
 * surfaces and are divided by hairlines instead. */
/* the Lacuna CTA row: desktop sits under the heading (row 2, left cols);
 * phones put it after the sub (order), full width */
.lac-cta { grid-column: 1 / 6; grid-row: 2; display: flex; align-items: center; gap: 12px; margin-top: 28px; }
@media (width <= 940px) { .lac-cta { grid-column: 1; grid-row: auto; order: 3; margin-top: 8px; flex-wrap: wrap; } }
.stat-ruled { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stat-ruled .stat { align-items: flex-end; text-align: right; padding: 4rem 2rem 2.5rem; } /* 64px above the numbers, right-aligned */


/* animation top-center, title bottom-left */


/* (2026-08-27) two dangling selectors used to sit here, ".stat-ruled .stat +
 * .stat," with nothing after them. The first fused with the @media below and
 * the parser dropped the whole block, so the stats never stacked on phones. */
@media (width <= 940px) {
    .stat-ruled, .feat-ruled { grid-template-columns: 1fr; }
    .feat-ruled .feat-card { aspect-ratio: auto; }  /* one column: don't force tall squares */
    /* stacked stats read left-to-right like text, not right-aligned columns */
    .stat-ruled .stat { align-items: flex-start; text-align: left; }
}

/* Lacuna flip panel: three fixed columns — Papers · Directions · Authors —
 * each paging its own top-5 with caret arrows. Fixed heights (no jumping). */
.lac-flip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.lac-col { position: relative; display: flex; flex-direction: column; }

.lac-col-list { list-style: none; margin: 0; padding: 0; height: 256px; position: relative; }  /* fixed: paging never shifts height */
.lac-item { display: none; height: 100%; margin: 0; }  /* margin: 0 beats base.css's global li { margin-left: 24px } */
.lac-item.is-active { display: block; }
/* the whole card is one clickable link; full-bleed background hover, like the stats above */
.lac-card { display: flex; flex-direction: column; gap: 10px; height: 100%; box-sizing: border-box; padding: 1.75rem 2rem; text-decoration: none; }

.lac-card h4 { margin: 0; font-family: var(--font-family-sans); font-size: var(--text-small-size); font-weight: 400; line-height: 1.35; color: var(--text-primary); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; transition: color .2s; }
.lac-card:hover h4 { color: var(--citron-300); }
.lac-card-sub { margin: 0; font-size: var(--text-small-size); font-weight: 400; line-height: 1.5; color: var(--text-tertiary); display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
.lac-card-stats { margin: auto 0 0; display: flex; flex-wrap: wrap; gap: 6px 14px; }
.lac-card-stats span { font-family: var(--font-family-label-mono, inherit); font-size: var(--text-mini-size); letter-spacing: .02em; color: #cfd478; }
/* final slide: Lacuna logo centered, label beneath, no arrow */
.lac-card-all { flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 14px; color: var(--text-secondary); font-size: var(--text-small-size); }
.lac-all-logo { width: 40px; height: auto; opacity: .92; }
/* nav isolated below a line + dots, so the card above stays clickable-whole */
/* Both pseudo-elements here are already the terminal dots, so the rule above
 * the pager is painted as a background instead — same tapered stroke. */
.lac-col-nav {
    position: relative; display: flex; align-items: center; gap: .6rem;
    padding: 1.25rem 2rem 1.5rem;
    background-image: var(--rule-h-taper);
    background-size: 100% var(--border-hairline);
    background-repeat: no-repeat;
    background-position: top;
}
.lac-col-nav::before, .lac-col-nav::after { content: ""; position: absolute; top: 0; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; border-radius: 50%; background: var(--text-tertiary); z-index: 5; }
.lac-col-nav::before { left: 0; }
.lac-col-nav::after { left: 100%; }
.lac-col-label { margin-right: auto; font-family: var(--font-family-label-mono, inherit); font-size: var(--text-mini-size); letter-spacing: .05em; text-transform: uppercase; color: var(--text-secondary); }
.lac-flip-btn { width: 34px; height: 34px; border-radius: 50%; border: var(--border-hairline) solid var(--rule-line); background: transparent; color: var(--text-secondary); font-size: 17px; line-height: 1; display: grid; place-items: center; cursor: pointer; transition: border-color .2s, color .2s, background-color .2s; }
.lac-flip-btn:hover { border-color: color-mix(in srgb, #82a7a9 55%, transparent); color: var(--text-primary); background: color-mix(in srgb, var(--surface-mock) 55%, transparent); }
@media (width <= 940px) {
    .lac-flip { grid-template-columns: 1fr; }

    .lac-col-list { height: 240px; }
}

/* Infinite looping logo marquee — fades at the edges. */
.logo-marquee {
    overflow: hidden;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.logo-track {
    display: flex;
    align-items: center;
    width: max-content;
    animation: logo-marquee 38s linear infinite;
}
/* Hover pause removed and the loop distance measured (--loop-w, set by the
 * script at the page foot): translateX(-50%) resolved against the 1440px
 * layout width rather than the content, so every cycle jumped mid-set. */
@keyframes logo-marquee {
    from { transform: translateX(0); }
    to { transform: translateX(calc(var(--loop-w, 0px) * -1)); }
}

/* Institution marks: white, muted; per-mark heights for optical balance.
 * Symmetric margins (not gap) so the -50% loop lands exactly on one set. */
.logo-track img {
    flex: none;
    width: auto;
    height: auto;
    margin: 0 72px;
    filter: brightness(0) invert(1);
    opacity: 0.72;
}
.logo-track img[data-mark='mila'] { max-height: 34px; }
.logo-track img[data-mark='mpi'] { max-height: 34px; }
.logo-track img[data-mark='mit'] { max-height: 30px; }
.logo-track img[data-mark='oxford'] { max-height: 38px; }
.logo-track img[data-mark='waterloo'] { max-height: 28px; }

@media (prefers-reduced-motion: reduce) {
    .logo-track { animation: none; flex-wrap: wrap; justify-content: center; }
    .logo-dupe { display: none; }
    .logo-track img { margin: 12px 40px; }
}

@media (width <= 860px) {
    
    
    :root { --heading-display-size: 2.5rem; --section-gap: 72px; }
}

/* ---------- loop diagram ---------- */


/* ---------- stations ---------- */


/* session artifact frame */


/* direction excerpt frame */
.direction {
    background: var(--surface-raised);
    border: var(--border-hairline) solid var(--border-default);
    border-radius: 12px;
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}


.stat a { text-decoration: none; }


/* consent micro-diagram */
.consent {
    display: flex;
    align-items: center;
    gap: 0;
    margin-top: 24px;
    flex-wrap: wrap;
}


/* ---------- differential: two trajectories ---------- */
.diff-traj { margin: 0; display: grid; grid-template-columns: repeat(12, 1fr); column-gap: 24px; }
/* Stage: same panel as the Lacuna map / Althea showcase placeholders. */
.traj-stage {
    grid-column: 1 / 13;         /* use the full width */
    aspect-ratio: 800 / 382;     /* match the viewBox so the canvas maps 1:1, no letterbox */
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
.diff-row { padding: 0 2rem 2rem; }   /* 2rem gutters; its bottom rule is the top line of the concessions row */
/* ambient grid behind the graph (same field as the network diagram) */
.traj-stage { position: relative; }
.traj-field { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
.diff-concessions-row { padding: 0 2rem; }   /* empty since the concessions left; the shared rule keeps 128px to the divider */
/* the divider is the band's last mark, and the next section opens 128px below */
.band:has(.diff-concessions-row) { padding-bottom: 0; }
@media (width <= 940px) { .traj-stage { grid-column: 1 / 13; } }   /* keeps the 800/382 aspect: scaled landscape down to 700px */
@media (width <= 940px) { .traj-stage { aspect-ratio: 360 / 450; width: 100%; max-width: 480px; margin-inline: auto; } }   /* width: a grid item with auto margins otherwise shrinks to its (absolute) content: 0px, and the chart vanished */   /* portrait composition (script switches on the same query) */


/* ---------- trust ---------- */
/* Founders: 12-col row, [2 empty][4 card][4 card][2 empty]. */
/* Picture slot: real portrait. */


/* Advisors: 4-col ruled grid (no slider). Rows equalized so the internal
 * rule (cells 5+ border-top) lands exactly on the 50% dot line. */
.adv-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: 1fr; }
.adv-grid .adv-card { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 3rem 1.5rem; }

.grid-rule { top: auto; }   /* positioned inline at the 1/3 lines; full-width like any hline */
.adv-role { font-size: var(--text-mini-size); color: var(--text-tertiary); margin-bottom: 10px; }
@media (width <= 940px) {
    .adv-grid { grid-template-columns: 1fr; }
    .adv-grid .adv-card { border-left: 0 !important; }
    .adv-grid .adv-card + .adv-card::after {
        content: '';
        position: absolute;
        top: 0; left: 0; right: 0;
        height: var(--border-hairline);
        margin-top: calc(var(--border-hairline) / -2);
        background: var(--rule-h-taper);
        pointer-events: none;
    }
    /* the stacked divider ends in a dot on each rail, as the row's own rules
     * do, so the tapered line reads as reaching the rails (Ivan 2026-09-17) */
    .adv-grid .adv-card + .adv-card { z-index: 5; }   /* the card's tilt transform makes its own stacking context; lifted above the rails so the dots sit on them */
    .adv-grid .adv-card + .adv-card::before {
        content: ''; position: absolute; top: 0; bottom: auto; left: -2.5px; right: -2.5px; width: auto; height: 5px;
        margin: -2.5px 0 0; transform: none; pointer-events: none; z-index: 5;
        background: radial-gradient(circle at center, var(--text-tertiary) 2.5px, transparent 2.5px) left center / 5px 5px no-repeat,
                    radial-gradient(circle at center, var(--text-tertiary) 2.5px, transparent 2.5px) right center / 5px 5px no-repeat;
    }
    .grid-rule { display: none; }
}

/* Backer quote row */
.team-quote-row { padding: 128px 2rem; }   /* padding-bottom becomes 128px to the divider */
.band:has(.team-quote-row) { padding-bottom: 0; }
.team-quote-row .quote-center { max-width: 860px; margin: 0 auto; }
.team-quote-row .quote-center p:last-child { margin-bottom: 0; }   /* a quote without a cite (paper pages) ends on its own line */
/* the paper pages' question: the quote's face at the section-heading size,
 * two columns, no quote marks (Ivan 2026-09-17) */
.team-quote-row .quote-center.res-quote-cols { max-width: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 24px; text-align: left; }
.quote-center.res-quote-cols p { font-family: var(--font-family-sans); font-optical-sizing: auto; font-variation-settings: normal; font-weight: 400; letter-spacing: normal; font-size: var(--text-large-size); line-height: var(--text-large-line-height); color: var(--text-secondary); margin: 0; text-wrap: pretty; }   /* the body text register (.section-sub): 17px is the nearest token to 16 */
@media (width <= 940px) { .team-quote-row .quote-center.res-quote-cols { grid-template-columns: minmax(0, 1fr); row-gap: 1rem; } }

.adv-photo { width: 72px; height: 72px; border-radius: 999px; object-fit: cover; display: block; margin: 0 0 24px; }

.adv-name {
    margin-bottom: 0.375rem;   /* 2px + 0.25rem */
    font-family: var(--heading-sub-family);
    font-size: var(--heading-sub-size);
    line-height: var(--heading-sub-line-height);
    letter-spacing: var(--heading-sub-letter-spacing);
    font-weight: var(--heading-sub-weight);
    color: var(--text-primary);
}
.adv-name .link { color: inherit; }

.adv-line { font-size: var(--text-large-size); line-height: var(--text-large-line-height); color: var(--text-secondary); }


/* ---------- door ---------- */
/* The door: the whole closing band is brand yellow, dark-on-light tokens scoped inside. */
.band-door { background: transparent; }   /* dark, like the rest of the page */
.door { text-align: center; }
/* The membership cell sits on the page field like everything else. It used to
 * paint its own citron lattice, held in phase by background-attachment:fixed —
 * which worked only while the page field was fixed too. Now that the field is
 * document-anchored it scrolls and that layer does not, so it had become a
 * genuine second grid. Removed, along with the veil whose only job was to dim
 * those dots. */
.door-cta-row { padding: 48px 2rem; }
.door-map-row { padding: 128px 1rem; }   /* 128px above the divider and below the CTA rule */
.band:has(.door-map-row) { padding-bottom: 0; }
.door-map { margin: 0; }
.door-map canvas { display: block; width: 100%; height: auto; }
.door-uni-list { list-style: none; margin: 4rem 0 0; padding: 0 1rem; columns: 4; column-gap: 24px; text-align: left; }
.door-uni-list li { font-size: var(--text-mini-size); color: var(--text-tertiary); line-height: 1.9; break-inside: avoid; cursor: default; transition: color .15s; }
.door-uni-list li:hover, .door-uni-list li.is-lit { color: #cfd478; }
@media (width <= 940px) { .door-uni-list { columns: 2; } }
@media (width <= 480px) { .door-uni-list { columns: 1; } }

/* Backer quote: its own quiet band, centered serif, 8 cols wide. */

.quote-center { grid-column: 3 / 11; margin: 0; text-align: center; }
@media (width <= 940px) { .quote-center { grid-column: 1 / 13; } }
.quote-center p {
    font-family: var(--heading-section-family);   /* same face as section headings */
    font-optical-sizing: none;
    font-variation-settings: 'opsz' 14;   /* Safari: see the h1 pin */
    font-size: 2.5rem;
    line-height: 1.4;
    font-style: normal;
    letter-spacing: -0.015em;
    font-weight: 300;   /* Literata's thinnest */
    color: var(--text-primary);
    margin: 0 0 28px;
    text-wrap: balance;
}
.quote-center cite { font-style: normal; display: block; }
.quote-name {
    display: block;
    font-family: var(--heading-sub-family);
    font-size: var(--heading-sub-size);
    line-height: var(--heading-sub-line-height);
    letter-spacing: var(--heading-sub-letter-spacing);
    font-weight: var(--heading-sub-weight);
    color: var(--text-primary);
}
.quote-role { display: block; margin-top: 4px; font-size: var(--text-regular-size); color: var(--text-tertiary); }

.door-close {
    font-family: var(--heading-section-family);
    font-optical-sizing: none;
    font-variation-settings: 'opsz' 14;   /* Safari: see the h1 pin */
    font-size: 3rem;
    line-height: 1.15;
    letter-spacing: -0.015em;
    font-weight: 300;   /* the register's thinnest, like the hero + quote */
    color: var(--text-primary);
    text-wrap: balance;
    max-width: 16em;
    margin: 0 auto;
}


/* ---------- footer ---------- */
footer {
    /* border-top removed (2026-08-18): it ran the full viewport width;
     * horizontal rules stay contained to the 1160 frame */
    padding-block: 28px 40px;
}

.footer-row { padding: 128px 2rem 96px; }   /* 128px under the map's divider */
.footer-inner { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: var(--text-mini-size); color: var(--text-tertiary); }

.footer-inner a { color: var(--text-tertiary); text-decoration: none; margin-right: 18px; }

.footer-inner a:hover { color: var(--text-primary); }

/* ---------- Althea coda: a serif statement moment, revealed letter by letter ---------- */
/* Grid row so the coda's left edge lines up with the section headings (col 2). */




/* ===== Story-flow layouts (Ivan 2026-08-12): content-first rebuild below infra ===== */
/* Althea: three equal stages, 1rem gaps */

/* the divider closing the artifact section: 128px of air both sides. It sits
 * on the SECTION, not the instrument row — the row's own frame (rails, rule,
 * corner dots) has to stay tight around the cells. */
.ruled:has(.stage-ruled) { padding-bottom: 88px; position: relative; }   /* 88: the captions' ragged text already reads as air */
.ruled:has(.stage-ruled)::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent 0,
        rgba(255, 255, 255, 0.055) 18%,
        rgba(255, 255, 255, 0.055) 82%,
        transparent 100%);
    pointer-events: none;
}
.band:has(.stage-ruled) + .band::before { display: none; }   /* it draws its own */
.band:has(.stage-ruled) + .band .ruled-heading { padding-top: 8rem; }   /* 128px below the divider */


/* Lacuna: featured directions */


.stat { display: flex; flex-direction: column; align-items: center; gap: 1rem; text-decoration: none; }
/* Hover lights the FIGURE, not a panel behind it (2026-08-19). A background
 * fill has to match the cell exactly to look right, and the cell is not the
 * shape the eye reads — the number is. */
.stat-ruled .stat:hover .stat-n { color: var(--citron-300); }
/* serif stat numbers (replaced the dot-matrix LED panels, 2026-08-17):
 * Literata above the display step, thinnest weight, citron. */
.stat-n {
    font-family: var(--font-family-serif);
    font-size: 4rem;   /* display step (3.25) + 1: the stats are the section's exhibit */
    font-weight: 300;
    line-height: 1;
    letter-spacing: -0.01em;
    color: var(--text-primary);
    transition: color .2s;
}
.stat-l { font-family: var(--font-family-sans); font-size: var(--text-small-size); color: var(--text-tertiary); }


/* Network: infra-style field */
.net-row { padding: 3rem 1rem; }
.netfield { max-width: 1160px; margin-inline: auto; min-height: 480px; }
/* below the desktop rails the canvas scales down and the 480px floor left a dead band under the caption */
@media (width <= 940px) { .netfield { min-height: 0; } }
/* the illustration names its own parts: unlabelled it read as decoration */
.net-cap {
    max-width: 46rem;
    margin: 1.5rem auto 0;
    text-align: center;
    font-family: var(--font-family-label-mono);
    font-size: var(--text-micro-size);
    line-height: 1.6;
    color: var(--citron-300);
}
.netfield canvas { display: block; width: 100%; height: auto; }
@media (width <= 700px) {   /* portrait composition: the script rebuilds at container size */
    .netfield { min-height: 0; }
    .netfield canvas { max-width: 480px; margin-inline: auto; }
}


/* Differential: concessions as content */
.concessions { max-width: none; margin: 0; display: grid; grid-template-columns: repeat(12, 1fr); column-gap: 0; row-gap: 20px; }
.concessions p { margin: 0; color: var(--text-secondary); }
.concessions p:nth-of-type(1) { grid-column: 1 / span 5; grid-row: 1; }
.concessions p:nth-of-type(2) { grid-column: 7 / span 5; grid-row: 1; }

/* Trust: origin as a letter */


/* Door: the three facts + membership */
.door-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.door-fact { padding: 2.5rem 2rem; text-align: center; }

.door-fact span { display: block; color: var(--text-tertiary); font-size: var(--text-mini-size); margin-bottom: 6px; }
.door-fact p { margin: 0; font-size: var(--text-large-size); color: var(--text-secondary); }   /* 16px */
.door-member { max-width: 760px; margin: 0 auto 22px; color: var(--text-secondary); font-size: var(--text-large-size); }   /* 16px; wide enough to set in two lines */
@media (width <= 860px) {
    .door-facts { grid-template-columns: 1fr; }

}
@media (width <= 940px) {
    
    
    .concessions { grid-template-columns: 1fr; }
    .concessions p:nth-of-type(1), .concessions p:nth-of-type(2) { grid-column: 1; grid-row: auto; }
}

/* ---------- Mobile pass (2026-08-14) ---------- */
/* Burger overlay: the design system collapses nav links under 1000px; this is
 * the menu the burger opens. Ruled language: hairline-divided serif rows.
 * z 1000 sits just under the bar (--z-header 1001) so the rule + dots stay. */
.top-nav-menu { position: fixed; inset: 0; z-index: 1000; background: var(--surface-canvas); display: flex; flex-direction: column; padding: 96px 2rem 2rem; }
.top-nav-menu[hidden] { display: none; }
.top-nav-menu a {
    font-family: var(--font-family-serif);
    font-size: var(--heading-section-size);
    font-weight: 300;
    color: var(--text-primary);
    text-decoration: none;
    padding: 18px 0;
    border-top: var(--border-hairline) solid var(--rule-line);
}
.top-nav-menu a:first-child { border-top: 0; }
.top-nav-menu a:hover { color: var(--color-accent, #82a7a9); }
.top-nav-menu .top-nav-menu-cta { color: var(--color-accent, #82a7a9); }
html.nav-menu-open { overflow: hidden; }
.top-nav-menu-close {
    /* sits exactly where the burger was, so the control does not jump as the
     * menu opens: same 40x40 box at the same offsets (Ivan 2026-08-31) */
    position: absolute; top: 12px; right: 8px;
    width: 40px; height: 40px;
    display: grid; place-items: center;
    border: 0; background: none; cursor: pointer;
    color: var(--text-secondary); font-size: 30px; line-height: 1;
    font-family: var(--font-family-sans);
}
.top-nav-menu-close:hover { color: var(--text-primary); }
/* the brand stays in the open menu, at the bar's own position (Ivan 2026-09-17) */
.top-nav-menu .top-nav-menu-brand {
    position: absolute; top: 0; left: 0; right: 0; height: 64px; box-sizing: border-box;
    max-width: 1160px; margin-inline: auto; padding: 0 2rem; border: 0;
    display: flex; align-items: center; gap: 0.75rem;
    font-family: var(--font-family-sans); font-size: 18px; font-weight: var(--font-weight-medium);
}
.top-nav-menu .top-nav-menu-brand:hover { color: var(--text-primary); }
@media (width <= 700px) {
    /* Compact margins (Ivan 2026-08-19): screen -> rail 0.5rem, rail -> content
     * 0.5rem, so a 360px phone keeps 328px of usable width. The rails ride on
     * .vruled rows at the 1160 container edge, which .frame's padding places;
     * each row then holds its content 0.5rem inside them. */
    .frame { padding-inline: max(env(safe-area-inset-left), 1rem) max(env(safe-area-inset-right), 1rem); }   /* 16px screen gutter for the ruled frames (Ivan 2026-08-31) */
    /* content that has no rail of its own still lines up with railed content */
    .top-nav-inner { padding-inline: max(env(safe-area-inset-left), 1rem) max(env(safe-area-inset-right), 1rem); }
    .top-nav-menu .top-nav-menu-brand { padding-inline: max(env(safe-area-inset-left), 1rem) max(env(safe-area-inset-right), 1rem); }
    .engine-label { padding-inline: 1rem; }
    .band-hero .hero-althea .section-split { padding-inline: 0; }
    /* the badge leaves the demo window on phones (Ivan 2026-08-31): it sat
     * over content; below the frame's bottom rule it costs nothing */
    .show-badge { bottom: auto; top: calc(100% + 20px); right: 0; }   /* +0.5rem down (Ivan) */
    /* the badge now sits below the frame, so the strip needs clearance for it */
    .hero-logos-label { margin-top: 0.5rem; }   /* 1rem clear of the badge pill above (Ivan) */
    /* Horizontal rules already went solid at the 940px stacking point. On a
     * phone the vertical rails are short too, so they follow. */
    :root {
        --rule-v-taper: linear-gradient(180deg, var(--rule-line) 0, var(--rule-line) 100%);
    }
    /* section rhythm: the ruled heading's 128px top plus the band's own 64px
     * put ~192px above every heading; 96px total on phones (Ivan) */
    .band { padding-block: 3rem; }
    /* the four notes read left on a phone, like the prose around them */
    .engine-card { align-items: flex-start; text-align: left; }
    .engine-card .engine-card-link { align-self: flex-start; }
    .engine-cards .engine-card-link { align-self: flex-start; }
    /* the three counts: right-aligned as on desktop, one step down in size */
    .stat-ruled .stat { align-items: flex-end; text-align: right; }
    .stat-n { font-size: 3rem; }
    /* section headings step 3rem -> 2.5rem on phones (Ivan 2026-08-31) */
    .section-split > .section-head,
    .hero-althea .section-split > .section-head { font-size: 2.5rem; }
    .m-br { display: inline; }   /* the frame already gives the 16px screen gutter; doubling it squeezed the hero (Ivan 2026-08-31) */

    /* rows: 0.5rem off the rails, and the desktop vertical rhythm eased down */
    .engine-row { padding-inline: 0.5rem; }
    .engine-heading { padding: 3rem 0.5rem 2.5rem; }
    .ruled-heading { padding: 3rem 0.5rem 2.5rem; }
    /* two desktop rules add extra above specific headings; on a phone the
     * band's own 48px already carries the separation (Ivan: 96px total) */
    .band:has(.stage-ruled) + .band .ruled-heading,
    .ruled:has(#show-h) .ruled-heading,
    .band:has(#who-h) .ruled-heading,
    .band:has(.door-cta-row) .ruled-heading { padding-top: 3rem; }
    .engine-cards { padding: 40px 0.5rem 0; column-gap: 0; row-gap: 48px; }
    .stage-ask { padding: 16px 0.5rem; }
    /* the question sat at 15px against the plates' 13px (Ivan) */
    .art-ask { font-size: 13px; line-height: 1.55; padding: 18px 16px; }
    .art-plate { font-size: 13px; }
    /* same reason as the demo bubbles: the blurred backdrop is what flashed
     * the plate contents in and out while scrolling */
    .art-plate, .art-chip { backdrop-filter: none; -webkit-backdrop-filter: none; }
    .art-plate { background: rgba(11, 23, 23, 0.94); }
    .diff-row { padding: 0 0.5rem 1.5rem; }
    .diff-concessions-row { padding: 40px 0.5rem 88px; }
    .team-quote-row { padding: 88px 0.5rem; }
    .door-cta-row { padding: 40px 0.5rem; }
    .door-map-row { padding: 88px 0.5rem; }
    .footer-row { padding: 88px 0.5rem 72px; }

    /* cell interiors: 2rem of inner padding is a desktop luxury */
    .stat-ruled .stat { padding: 2.5rem 1rem 1.75rem; }
    .lac-card { padding: 1.25rem 1rem; }
    .lac-col-nav { padding: 1rem 1rem 1.25rem; }
    .door-fact { padding: 1.75rem 1rem; }
    .stage-rcell { padding: 40px 1rem; min-height: 0; }
    .adv-grid .adv-card { padding: 2rem 1rem; }
    /* the row keeps 0.5rem off the rails on phones: the divider and its dots
     * bleed that far to meet them */
    .adv-grid .adv-card + .adv-card::after { left: -0.5rem; right: -0.5rem; }
    .adv-grid .adv-card + .adv-card::before { left: calc(-0.5rem - 2.5px); right: calc(-0.5rem - 2.5px); }
    /* the quote at 2.5rem ran ten lines on a phone */
    .quote-center p { font-size: 1.625rem; }
    /* institution marks: a text logo at 34px fills a phone; scale is visual only, the loop distance holds */
    .logo-track img { scale: 0.78; margin: 0 44px; }

    /* Hero showcase: the tab track outgrows a phone, so the row scrolls
     * sideways instead of overflowing the page. Taps get a 40px target. */
    .show-frame .show-tabs-wrap {
        overflow-x: auto;
        overscroll-behavior-inline: contain;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }
    .show-frame .show-tabs-wrap::-webkit-scrollbar { display: none; }
    .show-frame .show-tabs { margin: 0; max-width: none; }
    .show-frame .show-tab { height: 40px; padding: 0 14px; }
    /* the demo panel is a fixed window by design (.hd-chat clips + masks).
     * Taller on phones (2026-08-31): the settled answer ran 504px in a
     * 448px cell, so its head was permanently clipped. */
    /* A FIXED height in px, sized to the tallest settled answer (590px) plus
     * the track's padding and the tab row. Not svh: on a real phone that is
     * the viewport minus Safari's chrome, so the log came out far shorter
     * than any headless test showed and every answer overflowed. Not auto
     * either: the frame would jump between the question and the answer. */
    .hero-althea .show-frame { height: 640px; }
    /* one demo at a time (Ivan): the track shows only the active tab and
     * the Lacuna carets step through them */
    .show-frame .show-tabs-wrap { display: flex; align-items: center; justify-content: space-between; gap: 10px; overflow: visible; padding: 16px 16px 0; margin-bottom: 16px; }   /* 16px from the frame on all sides (Ivan) */
    .show-frame .show-tabs-wrap .show-step { display: grid; flex: none; }
    /* the track sheds its glass on phones: with one tab visible, track pill
     * plus selected well read as a double box with a glow. The tab's own
     * well is the whole control, wrapping its label; arrows hold the edges. */
    .show-frame .show-tabs {
        flex: 1 1 auto;
        margin: 0 auto;
        display: flex;
        justify-content: center;
        padding: 0;
        border: 0;   /* the base track border painted a ghost box around the pill */
        background: none;
        box-shadow: none;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
    .show-frame .show-tab { display: none; }
    /* standalone, the nested-well dress breaks: its 12px radius and inset
     * top shadow were cut for sitting INSIDE the track. As its own capsule
     * it wears the track's glass instead: full radius, one hairline ring. */
    /* the counter is pinned to the pill's left edge so the NAME stays centred
     * in the capsule; it takes the citron the page uses for signals */
    .show-frame .show-tab[aria-selected='true']::before {
        content: attr(data-pos);
        position: absolute;
        left: 16px;
        color: var(--citron-300);
        font-variant-numeric: tabular-nums;
    }
    .show-frame .show-tab[aria-selected='true'] {
        display: flex; height: 40px; padding: 0 22px;
        flex: 1 1 auto; justify-content: center; align-items: center;
        position: relative;
        border-radius: 999px;
        background: rgba(255, 255, 255, 0.035);
        box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
    }

    /* Side bleeds are wider than a phone and nothing clips them, so they
     * would scroll the whole page sideways. Both stay in their column here.
     * (.stage-main .hd-stage outranks the rule in hero-demo.css, so the
     * override has to live at the same specificity.) */
    .stage-main .hd-stage { width: 100%; margin-inline: 0; }
    .engine-diagram .bento-diagram-frame { margin-inline: 0; }

    /* touch targets: the Lacuna carets and the map's institute list are
     * tap-driven on a phone, so they need more than a mouse's precision */
    .lac-flip-btn { width: 40px; height: 40px; }
    .door-uni-list li { padding-block: 5px; }
}
@media (width <= 480px) {
    :root { --heading-display-size: 2.25rem; }
    .door-close { font-size: 2.25rem; }
}


/* ============================================================
 * Research page (2026-09-11). Shares everything above; these are the
 * page's own grids, in the same grammar: cells divided by the tapered
 * rule, the fact register for tags, the advisors' portrait for people.
 * ============================================================ */
/* the hero: copy on the left six columns, the disc on the right six,
 * then the three counts in a ruled row beneath (the homepage's stat register) */
.res-hero .section-split { margin-bottom: 0; align-items: center; }
.res-hero .res-hero-copy { grid-column: 1 / 7; grid-row: 1; }
.res-hero .section-split > .res-hero-copy > .section-head { font-size: 3rem; font-weight: 300; line-height: 1.1; margin: 0; text-align: left; }
.res-hero .res-hero-copy { text-align: left; }
.res-hero .section-split > .res-hero-copy > .section-sub { margin: 1.5rem 0 0; }
.res-hero .res-orb { grid-column: 7 / 13; grid-row: 1; justify-self: end; margin-top: 5rem; }
/* the three counts sit under the sub, a hairline above them, in the
 * homepage's stat register two steps smaller */
.res-facts { display: flex; gap: 3.5rem; margin-top: 4rem; }
.res-facts .stat { align-items: flex-start; text-align: left; gap: 1rem; }
.res-facts .stat-n { font-size: 3rem; color: var(--citron-300); }
.res-facts .stat-l { font-size: var(--text-large-size); line-height: var(--text-large-line-height); color: var(--text-secondary); }   /* the sub's type and ink */
.res-facts .stat:hover .stat-n { color: var(--text-primary); }

/* the circle: fifteen portraits packed into a disc, five on an inner
 * ring and ten interleaved on the outer, nearly touching (the disc is 4.6
 * portrait radii across; the optimum for fifteen is 4.52). Each floats a
 * few pixels on its own slow loop, leans toward the pointer (--lx/--ly
 * from the script), grows on hover, and is a link to the person's card.
 * Still under reduced motion. */
.res-orb {
    --orb: 440px;
    position: relative; width: var(--orb); max-width: 100%; aspect-ratio: 1; margin: 0;
}
.res-orb-halo { position: absolute; top: 0; left: 0; z-index: 0; pointer-events: none; }   /* sized and offset by its script: bleeds 120px past the disc */
.res-orb-ring { position: absolute; inset: 0; z-index: 1; }
.res-orb-p {
    position: absolute; left: var(--x); top: var(--y); width: var(--w, 19.77%); aspect-ratio: 1;   /* 87px at 440: the portraits kept their size when the disc grew from 400 */
    translate: calc(-50% + var(--lx, 0px)) calc(-50% + var(--ly, 0px));
    transition: translate .6s cubic-bezier(.2, .7, .2, 1);
    border-radius: 999px;
    outline: none;
}
.res-orb-p:hover, .res-orb-p:focus-visible { z-index: 3; }
.res-orb-p > i {
    display: block; width: 100%; height: 100%; border-radius: 999px; overflow: hidden; background: #1a1a1a;
    animation: res-float var(--fd, 9s) var(--fdl, 0s) ease-in-out infinite;
    transition: scale .3s cubic-bezier(.2, .7, .2, 1), box-shadow .3s;
    box-shadow: 0 0 0 0 var(--surface-canvas);
}
.res-orb-p:hover > i, .res-orb-p:focus-visible > i { scale: 1.28; box-shadow: 0 0 0 3px var(--surface-canvas), 0 12px 32px rgba(0, 0, 0, 0.5); }
.res-orb-p img { display: block; width: 100%; height: 100%; object-fit: cover; }
@keyframes res-float {
    0%, 100% { transform: translate(0, 0); }
    30% { transform: translate(var(--fa, 3px), calc(var(--fa, 3px) * -0.6)); }
    65% { transform: translate(calc(var(--fa, 3px) * -0.7), calc(var(--fa, 3px) * 0.8)); }
}
/* the name and title of the hovered face, as a tip beside it (placed by
 * the script; flips to the left past the disc's midline) */
.res-orb-cap {
    position: absolute; z-index: 4; margin: 0; width: max-content; max-width: 260px;
    translate: 0 -50%; text-align: left;
    display: flex; flex-direction: column; gap: 5px;
    padding: 12px 16px; border-radius: 12px;
    background: rgba(18, 18, 18, 0.92);
    -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 8px 24px rgba(0, 0, 0, 0.4);
    opacity: 0; transition: opacity .2s; pointer-events: none;
}
.res-orb-cap.is-left { translate: -100% -50%; }   /* the text stays left-aligned on both sides */
.res-orb-cap-name { font-size: var(--text-regular-size); color: var(--text-primary); }
.res-orb-cap-title { font-size: var(--text-mini-size); line-height: 1.6; color: var(--citron-300); white-space: pre-line; }   /* role, then each affiliation on its own line */
.res-orb.is-naming .res-orb-cap { opacity: 1; }
.res-person { scroll-margin-top: 96px; }
@media (prefers-reduced-motion: reduce) {
    .res-orb-p > i { animation: none; }
    .res-orb-p, .res-orb-p > i { transition: none; }
}
@media (width <= 940px) {
    .res-hero .res-hero-copy, .res-hero .res-orb { grid-column: 1 / 13; }
    .res-hero .res-hero-copy { grid-row: 1; }
    .res-hero .res-orb { grid-row: 2; justify-self: center; --orb: min(100%, 360px); margin-top: 2rem; }
    .res-facts { gap: 2rem; }
}

/* a ruled grid of cells: 2 or 3 across, hairline + dots between them */
.res-grid { display: grid; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); }
.res-cell { position: relative; display: flex; flex-direction: column; gap: 14px; padding: 2.5rem 2rem 2.75rem; min-width: 0; }
.res-cell + .res-cell::before {
    content: ''; position: absolute; top: 0; bottom: 0; left: 0;
    width: var(--border-hairline); margin-left: calc(var(--border-hairline) / -2);
    background: var(--rule-v-taper); pointer-events: none; z-index: 4;
}
.res-title {
    margin: 0;
    font-family: var(--heading-section-family);
    font-size: 1.375rem; line-height: 1.33; font-weight: 300; letter-spacing: -0.01em;
    color: var(--text-primary);
    text-wrap: balance;
}
.res-sum { margin: 0; font-size: var(--text-large-size); line-height: var(--text-large-line-height); color: var(--text-secondary); }
.res-authors { margin: 0; font-size: var(--text-mini-size); color: var(--text-tertiary); }
.res-tags { display: flex; flex-wrap: wrap; gap: 6px 0; margin: 2px 0 0; padding: 0; list-style: none; }
.res-tags li { display: inline-flex; align-items: center; font-family: var(--font-family-label-mono); font-size: var(--text-micro-size); color: var(--citron-300); white-space: nowrap; }
.res-tags li + li::before { content: ''; display: inline-block; width: 3px; height: 3px; border-radius: 999px; background: var(--citron-300); margin: 0 12px; }
.res-link { margin-top: auto; padding-top: 6px; font-size: var(--text-mini-size); color: var(--text-primary); text-decoration: none; }
.res-link::after { content: ' \2192'; }
.res-link:hover { color: var(--citron-300); }

/* the paper cards: the whole cell is the link, in the homepage's card
 * grammar (sans title that lights citron on hover, muted summary, citron
 * mono tags), a figure on top and the coauthors as a stack of portraits */
.res-paper { color: inherit; text-decoration: none; gap: 12px; padding-top: 0.75rem; }   /* the figures carry ~36px of their own air at the top; 12 + 36 reads as the 44px below the byline */
/* the two cards share rows (subgrid), so title, summary, tags and byline
 * sit at the same height in both even when one title wraps */
@supports (grid-template-rows: subgrid) {
    .res-paper { display: grid; grid-template-rows: subgrid; grid-row: span 5; align-content: start; row-gap: 12px; }
}
.res-paper:hover .res-title, .res-paper:focus-visible .res-title { color: var(--citron-300); }
.res-paper .res-title { font-family: var(--font-family-sans); font-size: var(--text-large-size); font-weight: 400; line-height: 1.35; letter-spacing: 0; transition: color .2s; }
.res-paper .res-sum { font-size: var(--text-small-size); line-height: 1.5; color: var(--text-tertiary); }
.res-paper .res-tags { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 10px 0 0; }
.res-paper .res-tags span { font-family: var(--font-family-label-mono, inherit); font-size: var(--text-mini-size); letter-spacing: .02em; color: #cfd478; }
.res-fig { margin: 0 0 8px; position: relative; aspect-ratio: 4 / 3; }   /* no panel: the figure sits on the field like the homepage diagrams */
.res-fig-canvas { display: block; width: 100%; height: 100%; }
/* the Lacuna figure's tiles are the infra diagram's, verbatim (the embed's
 * Liquid Glass recipe): 48px, radius 14, a flat tint, a lit top-left rim
 * and real depth; a light icon; an 11px name beneath. Placed in percent
 * over the canvas so they track the wires at any width. */
.res-fig-units .res-fig-canvas { position: absolute; inset: 0; }
.res-unit { position: absolute; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 8px; translate: -50% -24px; pointer-events: none; }
.res-tile {
    display: flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 48px; height: 48px; border-radius: 14px;
    background: rgba(255, 255, 255, 0.055);
    -webkit-backdrop-filter: blur(26px) saturate(1.4); backdrop-filter: blur(26px) saturate(1.4);
    box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.16), inset 0 0 0 1px rgba(255, 255, 255, 0.055), inset 0 -1px 0 rgba(255, 255, 255, 0.05), 0 6px 18px rgba(0, 0, 0, 0.28), 0 18px 44px rgba(0, 0, 0, 0.22);
    color: var(--text-secondary);
    transition: box-shadow .25s, color .25s;
}
.res-tile svg { display: block; }
.res-unit[data-hot="true"] .res-tile { color: var(--citron-300); box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.16), inset 0 0 0 1px rgba(207, 212, 120, 0.45), inset 0 -1px 0 rgba(255, 255, 255, 0.05), 0 6px 18px rgba(0, 0, 0, 0.28), 0 18px 44px rgba(0, 0, 0, 0.22), 0 0 24px rgba(207, 212, 120, 0.12); }
.res-unit-name { font-size: 11px; font-weight: 500; line-height: 1.25; color: var(--text-primary); }
@media (width <= 700px) { .res-tile { width: 40px; height: 40px; border-radius: 12px; } .res-unit { translate: -50% -20px; } }
.res-paper .res-authors { display: flex; align-items: center; gap: 10px; margin: 20px 0 0; font-size: var(--text-small-size); color: var(--text-secondary); }
.res-stack { display: inline-flex; flex-shrink: 0; }
.res-stack img { width: 26px; height: 26px; border-radius: 999px; object-fit: cover; background: #1a1a1a; box-shadow: 0 0 0 2px var(--surface-canvas); }
.res-stack img + img { margin-left: -8px; }

/* ongoing projects: stacked rows divided by the tapered rule, the tags
 * and the team on the left, title and summary on the right, in the paper
 * cards' type */
.res-rows { display: flex; flex-direction: column; }
.res-row { position: relative; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; padding: 5rem 2rem; }   /* 80px above and below (1rem under the homepage's 88 section air, Ivan 2026-09-17); the 2rem inset aligns the text with the headings */
/* between rows: the homepage's faint section divider (edge-faded, 5.5%
 * white), with section-like air on either side */
.res-row + .res-row::before {
    content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
    background: linear-gradient(90deg, transparent 0, rgba(255, 255, 255, 0.055) 18%, rgba(255, 255, 255, 0.055) 82%, transparent 100%);
    pointer-events: none;
}
.res-row { grid-template-rows: auto auto; row-gap: 12px; }
/* both columns share the row's two tracks (subgrid), so the tags sit on the
 * title's line and the byline on the summary's first line */
.res-row-side { grid-column: 1 / 5; grid-row: 1 / 3; display: grid; grid-template-rows: subgrid; row-gap: 12px; align-items: start; min-width: 0; }
.res-row-main { grid-column: 5 / 13; grid-row: 1 / 3; display: grid; grid-template-rows: subgrid; row-gap: 12px; align-items: start; min-width: 0; }
.res-row .res-title, .res-row .res-sum, .res-row .res-tags, .res-row .res-authors { margin: 0; }
/* the tag shares the title's baseline; the byline centres on the summary */
.res-row .res-tags, .res-row .res-title { align-self: baseline; }
.res-row .res-authors, .res-row .res-sum { align-self: center; }
.res-row .res-title { font-family: var(--font-family-sans); font-size: var(--text-large-size); font-weight: 400; line-height: 1.35; letter-spacing: 0; }
.res-row .res-sum { font-size: var(--text-small-size); line-height: 1.5; color: var(--text-tertiary); }
.res-row .res-tags { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 0; }
.res-row .res-tags span { font-family: var(--font-family-label-mono, inherit); font-size: var(--text-mini-size); letter-spacing: .02em; color: #cfd478; }
.res-row .res-authors { display: flex; align-items: center; gap: 10px; font-size: var(--text-small-size); line-height: 1.5; color: var(--text-tertiary); }   /* the summary's type */
@media (width <= 940px) {
    .res-row { grid-template-rows: auto auto auto auto; }
    .res-row-side { grid-column: 1 / 13; grid-row: 1 / 3; }
    .res-row-main { grid-column: 1 / 13; grid-row: 3 / 5; margin-top: 0.5rem; }
}

/* the group label: a sans sub-heading (Title Case) outside the framed
 * row, in the headings' glass */
.res-group {
    margin: 0; padding: 4rem 2rem 2.25rem; width: fit-content;
    font-family: var(--font-family-sans); font-size: var(--heading-section-size, 1.375rem); font-weight: 400; line-height: 1.3; letter-spacing: 0;
    background-image: linear-gradient(178deg, #ffffff 0%, color-mix(in srgb, var(--text-primary) 92%, transparent) 42%, color-mix(in srgb, var(--text-primary) 62%, transparent) 100%);
    -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
    text-shadow: 0 1px 14px rgba(0, 0, 0, 0.35);
}
/* people: the homepage's advisor cards (centred, 72px portrait, sub
 * heading name, mini role, large line), two across with the tapered rule
 * between the columns and the homepage's grid rules between rows */
.res-people { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; }
.res-person { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0; padding: 3rem 1.5rem; min-width: 0; }
.res-person:nth-child(even)::before {
    content: ''; position: absolute; top: 0; bottom: 0; left: 0;
    width: var(--border-hairline); margin-left: calc(var(--border-hairline) / -2);
    background: var(--rule-v-taper); pointer-events: none; z-index: 4;
}
/* an odd last card sits alone in column 1: it gets the column divider on its
 * right, and the row's frame stops at it (.res-row-half on the engine-row):
 * the right rail ends at the grid rule, the bottom rule runs to the half
 * mark, the bottom-right corner dot goes */
.res-person:last-child:nth-child(odd)::after {
    content: ''; position: absolute; top: 0; bottom: 0; right: 0;
    width: var(--border-hairline); margin-right: calc(var(--border-hairline) / -2);
    background: var(--rule-v-taper); pointer-events: none; z-index: 4;
}
.res-row-half.vruled::after { bottom: 50%; }
.res-row-half > .logos-hline.bot { width: 50%; }
.res-row-half > .logos-tick.br { display: none; }
.res-person .adv-photo { margin-bottom: 24px; }
.res-initials {
    width: 72px; height: 72px; border-radius: 999px; margin-bottom: 24px;
    display: inline-flex; align-items: center; justify-content: center;
    background: rgba(255, 255, 255, 0.06); color: var(--citron-300);
    font-family: var(--font-family-label-mono); font-size: var(--text-mini-size); letter-spacing: 0.04em;
}
.res-person .res-name { margin-top: 0; }
.res-person .res-aff { margin: 0 0 10px; color: var(--citron-300); }   /* the affiliation line in the fact register's citron */
.res-person .res-bio { margin: 0; max-width: 34em; }
/* contributions as secondary glass buttons under a small label; the
 * profile link as the primary glass button at the foot of every card */
.res-contrib-label { margin: 20px 0 8px; font-size: var(--text-mini-size); color: var(--text-tertiary); }
.res-contrib { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 0; }
/* a contribution with no page yet: the small button's shape as a dashed
 * outline, quieter ink, no hover, so it reads as a label rather than a link */
.res-pill {
    display: inline-flex; align-items: center; box-sizing: border-box;
    height: var(--button-small-height, 32px); padding: 0 12px; border-radius: 999px;
    font-size: var(--text-small-size); line-height: 1; color: var(--text-tertiary);
    border: 1px dashed rgba(255, 255, 255, 0.22); cursor: default; user-select: none;
}
/* the card's foot: the homepage's card-nav strip (a tapered rule with a
 * dot at each end, its own padding), full-bleed inside the card, holding
 * the profile button */
.res-person-foot {
    position: relative; margin: auto -1.5rem -3rem; padding: 1.25rem 1.5rem; align-self: stretch;
    display: flex; justify-content: center;
    background-image: var(--rule-h-taper); background-size: 100% var(--border-hairline); background-repeat: no-repeat; background-position: top;
}
.res-person-foot::before, .res-person-foot::after { content: ''; position: absolute; top: 0; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; border-radius: 50%; background: var(--text-tertiary); z-index: 5; }
.res-person-foot::before { left: 0; }
.res-person-foot::after { left: 100%; }
.res-person > :nth-last-child(2) { margin-bottom: 32px; }   /* the air above the strip */
@media (width <= 940px) {
    .res-grid { grid-template-columns: minmax(0, 1fr); }
    .res-cell + .res-cell::before {
        top: 0; bottom: auto; left: 0; right: 0; width: auto; height: var(--border-hairline);
        margin-left: 0; margin-top: calc(var(--border-hairline) / -2); background: var(--rule-h-taper);
    }
    .res-hero .section-split > .section-sub { grid-column: 1 / 13; }
}
@media (width <= 700px) {
    .res-people { grid-template-columns: minmax(0, 1fr); }
    /* the row keeps 0.5rem off the rails on phones, so the divider, its dots
     * and the foot strip bleed that far to meet the rails */
    .res-person::before, .res-person:nth-child(even)::before {
        content: ''; position: absolute; top: 0; bottom: auto; left: -0.5rem; right: -0.5rem; width: auto; height: var(--border-hairline);
        margin-left: 0; margin-top: calc(var(--border-hairline) / -2); background: var(--rule-h-taper); pointer-events: none; z-index: 4;
    }
    .res-person:first-child::before { content: none; }
    /* the stacked divider ends in a dot on each rail, as the row's own rules
     * do, so the tapered line reads as reaching the rails (Ivan 2026-09-17) */
    .res-person::after, .res-person:last-child:nth-child(odd)::after {
        content: ''; position: absolute; top: 0; bottom: auto; left: calc(-0.5rem - 2.5px); right: calc(-0.5rem - 2.5px); width: auto; height: 5px;
        margin: -2.5px 0 0; pointer-events: none; z-index: 5;
        background: radial-gradient(circle at center, var(--text-tertiary) 2.5px, transparent 2.5px) left center / 5px 5px no-repeat,
                    radial-gradient(circle at center, var(--text-tertiary) 2.5px, transparent 2.5px) right center / 5px 5px no-repeat;
    }
    .res-person:first-child::after, .res-person:first-child:last-child::after { content: none; }
    .res-row-half.vruled::after { bottom: 0; }
    .res-row-half > .logos-hline.bot { width: 100%; }
    .res-row-half > .logos-tick.br { display: block; }
    .res-people .grid-rule { display: none; }
    .res-cell { padding-inline: 1rem; }
    .res-person { padding: 2rem 1rem; }
    .res-person-foot { margin: auto -1.5rem -2rem; padding-inline: 1.5rem; }
}


/* ============================================================
 * Paper pages (research-<slug>.html)
 * Two papers from one template, on the research page's grammar: the
 * same ruled frames, cells, tags and people cards. These are the few
 * registers a paper page needs and the research page does not: the
 * hero's trail, byline and action row, the two-column prose, the
 * figure cell, the stage and metric cells, the limitation notes, the
 * benchmark table, the resource list, the citation block and the PDF
 * frame. Everything is scoped to .res-paper-page so the research page
 * and the homepage are untouched.
 * ============================================================ */
/* the hero: the trail back to the research page, the paper's full name,
 * its one-line description, tags, byline and entry points. The disc of
 * this paper's authors takes the research hero's six right columns. */
.res-crumbs {
    margin: 0 0 1.5rem;
    font-family: var(--font-family-sans); font-size: var(--text-small-size);
    color: var(--text-tertiary);
}
.res-crumbs a { color: var(--text-secondary); text-decoration: none; }
.res-crumbs a:hover, .res-crumbs a:focus-visible { color: var(--text-primary); }
.res-crumb-sep { margin: 0 8px; }
.res-paper-page .res-hero .section-split > .res-hero-copy > .section-head + .section-sub { margin-top: 1rem; }
.res-paper-page .res-tags { gap: 6px 14px; }
.res-paper-page .res-tags span {
    display: inline-flex; align-items: center;
    font-family: var(--font-family-label-mono); font-size: var(--text-mini-size); letter-spacing: .02em;
    color: var(--citron-300); white-space: nowrap;
}
.res-paper-page .res-hero-copy .res-tags { margin: 1.5rem 0 0; }
.res-paper-page .res-hero-copy .res-authors {
    display: flex; align-items: center; gap: 10px; margin: 1.25rem 0 0;
    font-size: var(--text-small-size); color: var(--text-secondary);
}
.res-hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin: 2rem 0 0; }
.res-hero-actions .auth-btn { width: auto; padding: 0 24px; }   /* the homepage hero's pair, each hugging its label */

/* the method's first row: the paper's own diagram across the left cell,
 * its caption under it, and the worked aside centred in the right cell */
.res-cell-fig .res-fig { width: 100%; margin: 0; }
.res-cell-center { justify-content: center; }

/* two columns of prose in the row's own grid, the section's text inset */
.res-prose { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; padding: 0 2rem 4rem; }
.res-prose > p { margin: 0; font-size: var(--text-large-size); line-height: var(--text-large-line-height); color: var(--text-secondary); }
.res-prose > p:first-child { grid-column: 1 / 7; }
.res-prose > p:nth-child(2) { grid-column: 7 / 13; }
/* the results caveat and its source link: one narrower column, quieter ink */
.res-prose > .res-sum { grid-column: 1 / 9; font-size: var(--text-small-size); line-height: 1.5; color: var(--text-tertiary); }
.res-prose > .res-link { grid-column: 1 / 9; }
.res-paper-page .engine-row.vruled + .engine-row > .res-prose { padding-top: 2rem; }
@media (width <= 940px) {
    .res-prose { grid-template-columns: minmax(0, 1fr); row-gap: 1rem; }
    .res-prose > p, .res-prose > p:first-child, .res-prose > p:nth-child(2),
    .res-prose > .res-sum, .res-prose > .res-link { grid-column: 1; }
}

/* the cells: every title in the cards' sans register, the stage number in
 * the fact register's citron mono */
.res-paper-page .res-cell .res-title {
    font-family: var(--font-family-sans); font-size: var(--text-large-size);
    font-weight: 400; line-height: 1.35; letter-spacing: 0;
}
.res-stage-n { font-family: var(--font-family-label-mono); font-size: var(--text-mini-size); letter-spacing: .02em; color: var(--citron-300); }
/* the limitations: a citron dot per line, in the summary's quieter ink */
.res-notes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 24px; margin: 0; padding: 0; list-style: none; }
@media (width <= 940px) { .res-notes { grid-template-columns: minmax(0, 1fr); } }
.res-notes li { position: relative; margin: 0; padding-left: 16px;   /* base.css indents every li by 24px */ font-size: var(--text-small-size); line-height: 1.5; color: var(--text-tertiary); }
.res-notes li::before { content: ''; position: absolute; left: 0; top: 0.55em; width: 5px; height: 5px; border-radius: 999px; background: var(--citron-300); }
/* the metrics: the homepage's stat register, the number two steps down */
/* results at a glance: the homepage's stat cards (.stat-ruled), the comparison as a second label line */
.stat-ruled .stat .stat-l + .stat-l { margin-top: -8px; color: var(--citron-300); }   /* the compared value in the fact register's citron */
/* the numbers in the headings' glass (paper pages only) */
.stat-ruled.res-stats .stat-n {
    background-image: linear-gradient(178deg, #ffffff 0%, color-mix(in srgb, var(--text-primary) 92%, transparent) 42%, color-mix(in srgb, var(--text-primary) 62%, transparent) 100%);
    -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
}
/* the source link under the caveat: citron, underlined only on hover */
.res-paper-page .res-link { margin-top: 0; padding-top: 0; font-size: var(--text-small-size); color: var(--citron-300); text-decoration: none; }
.res-paper-page .res-link::after { content: none; }
.res-paper-page .res-link:hover { color: var(--citron-300); text-decoration: underline; }
.res-paper-page .res-prose > .res-link { margin-top: 12px; }   /* the caveat's own line of air */

/* the benchmark table: the docs' table register, numbers right-aligned,
 * rows parted by the page's faint divider, the paper's own system lit */
.res-table-wrap { padding: 2rem; }
.res-table { width: 100%; border-collapse: collapse; margin: 1rem 0 0; }
.res-table th, .res-table td { padding: 12px 0; text-align: left; font-weight: 400; }
.res-table thead th { font-size: var(--text-mini-size); color: var(--text-tertiary); border-bottom: 1px solid rgba(255, 255, 255, 0.055); }
.res-table tbody th, .res-table tbody td { font-size: var(--text-large-size); line-height: var(--text-large-line-height); color: var(--text-secondary); }   /* the body register (Ivan 2026-09-17) */
.res-table tbody tr + tr th, .res-table tbody tr + tr td { border-top: 1px solid rgba(255, 255, 255, 0.055); }
.res-table th + th, .res-table td { text-align: right; }
.res-table .res-table-featured th { color: var(--text-primary); }
.res-table .res-table-featured td { color: var(--citron-300); }

/* the resource list: one row per artifact, title over description, the
 * outward arrow at the far end, the title lighting citron on hover */
.res-resources { margin: 1.5rem 0 0; padding: 0; list-style: none; }
.res-resources li { margin: 0; }   /* base.css indents every li by 24px */
.res-resources li + li { border-top: 1px solid rgba(255, 255, 255, 0.055); }
.res-resources a { display: flex; align-items: center; gap: 16px; padding: 14px 0; color: inherit; text-decoration: none; }
.res-res-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.res-res-title { font-size: var(--text-regular-size); color: var(--text-primary); transition: color .2s; }
.res-res-desc { font-size: var(--text-small-size); line-height: 1.5; color: var(--text-tertiary); }
.res-resources a > svg { flex: 0 0 auto; margin-left: auto; color: var(--text-tertiary); }
.res-resources a:hover .res-res-title, .res-resources a:focus-visible .res-res-title { color: var(--citron-300); }

/* the citation: the entry in the label mono on the glass the tiles use */
/* the entry in the system's true mono, its copy button inside the block at
 * the top-right (Ivan 2026-09-17) */
.res-bibtex-box { margin: 1rem 0 0; padding: 24px; border-radius: 12px; background: rgba(255, 255, 255, 0.035); }
.res-bibtex {
    margin: 0; padding: 0; border: 0; background: none; box-shadow: none; overflow: visible;   /* base.css draws pre as its own panel; the box is the panel here */
    font-family: var(--font-family-mono); font-size: var(--text-mini-size); line-height: 1.6;
    color: var(--text-secondary);
    white-space: pre-wrap; overflow-wrap: anywhere;
}
.res-bibtex-box .res-copy-bib { margin-top: 20px; display: inline-flex; align-items: center; gap: 8px; }
.res-copy-icon { display: block; flex: none; }   /* 16px glyph, 2.25 stroke at 16 (the glyph rule) */

/* the manuscript: the buttons, and the frame the preview opens into */
.res-pdf { padding: 2rem; }
/* the preview as a full-screen modal: the page's ground, a 64px bar with the
 * menu's close control at its right, the frame filling the rest (Ivan 2026-09-17) */
.res-pdf-modal { position: fixed; inset: 0; z-index: 1200; background: var(--surface-canvas); }
.res-pdf-modal[hidden] { display: none; }
/* the modal's bar: the nav's geometry with the brand at the left and a single
 * close control where the nav's button sits (Ivan 2026-09-17) */
.res-pdf-bar { position: absolute; top: 0; left: 0; right: 0; height: 64px; box-sizing: border-box; max-width: 1160px; margin-inline: auto; padding: 0 2rem; display: flex; align-items: center; justify-content: space-between; }
.res-pdf-brand { font-family: var(--font-family-sans); font-size: 18px; font-weight: var(--font-weight-medium); }
.res-pdf-close {
    width: 40px; height: 40px; margin-right: -8px;
    display: grid; place-items: center; border: 0; background: none; cursor: pointer;
    color: var(--text-secondary); font-size: 30px; line-height: 1; font-family: var(--font-family-sans);
}
@media (width <= 700px) { .res-pdf-bar { padding-inline: max(env(safe-area-inset-left), 1rem) max(env(safe-area-inset-right), 1rem); } }
.res-pdf-close:hover { color: var(--text-primary); }
.res-pdf-frame { position: absolute; inset: 64px 0 0; width: 100%; height: calc(100% - 64px); border: 0; background: rgba(255, 255, 255, 0.035); }
html.res-modal-open { overflow: hidden; }

@media (width <= 700px) {
    .res-prose { padding: 0 1rem 3rem; }
    .res-table-wrap, .res-pdf { padding: 1.5rem 1rem; }
    .res-pdf-frame { height: 480px; }
}

/* the method in the homepage's How it works layout: stage icons in the
 * network mark's teal; the diagram floats in the diagram row, a caption
 * beneath it; the notes list runs one column beside the worked question */
.engine-card .res-stage-icon { color: var(--teal-400); }
.engine-card .res-stage-icon svg { display: block; }
/* the diagram row at the homepage's height (520), the figure sized by that
 * height; its caption in the canvas labels' type, mirrored above the chain
 * at the distance the drawn label sits below it (Ivan 2026-09-17) */
.engine-diagram.res-method-row { padding: 0.5rem 2rem 3rem; min-height: 520px; }
.res-method-row .res-method-fig { width: auto; max-width: 100%; height: 420px; margin: 0; }
/* the captions under the diagram in the summary register: the chain's line
 * and the paper's, where the drawn label used to sit (Ivan 2026-09-17) */
.res-method-row .res-method-cap {
    position: absolute; left: -40%; right: -40%; top: 100%; margin: 12px 0 0; text-align: center;   /* wider than the figure, so a long caption holds one line */
    font-family: var(--font-family-sans); font-size: var(--text-small-size); line-height: var(--text-small-line-height); font-weight: 400; color: var(--text-secondary);
}
.res-method-row .res-method-cap span { display: block; }
.res-method-row .res-method-cap span + span { margin-top: 12px; }
/* the chart fills its box to the top, so its caption goes beneath the axis label instead */
.res-method-row .res-method-fig:not(.res-fig-units) .res-method-cap { top: 100%; }   /* the chart's caption sits under its box too */
/* the loop's caption inside the square, under the drawn line, in the canvas
 * labels' type (Ivan 2026-09-17) */
.res-method-row .res-fig-units .res-method-cap {
    top: calc(210 / 387 * 100%); left: 24%; right: 24%; margin: 0;
    font-size: 11px; font-weight: 500; line-height: 1.5; color: rgba(230, 228, 220, 0.92);
}
@media (width <= 940px) { .res-method-row .res-method-fig { width: 100%; height: auto; } }
.res-cell .res-sum + .res-sum { margin-top: 0.75rem; }   /* the notes as plain paragraphs (Ivan 2026-09-17) */

/* the results' caveat and its source in two columns: the caveat in the
 * body register on the left, the source line and its button on the right */
.res-prose.res-source { padding-top: 3rem; }
.res-prose.res-source > p:first-child { grid-column: 1 / 7; }
.res-prose.res-source > .res-source-link { grid-column: 1 / 7; margin-top: 1rem; justify-self: start; font-size: var(--text-large-size); line-height: var(--text-large-line-height); color: var(--teal-400); text-decoration: none; }
.res-prose.res-source > .res-source-link:hover { text-decoration: underline; text-underline-offset: 3px; }
@media (width <= 940px) { .res-prose.res-source > p:first-child, .res-prose.res-source > .res-source-link { grid-column: 1 / 13; } }

/* a heading with no sub beside it runs the full width (Ivan 2026-09-17) */
.res-paper-page .ruled-heading .section-split:not(:has(.section-sub)) > .section-head { grid-column: 1 / 13; }
/* heading full width with its sub beneath it (the people section, Ivan 2026-09-17) */
.res-paper-page .section-split.res-head-stack > .section-head { grid-column: 1 / 13; }
.res-paper-page .section-split.res-head-stack > .section-sub { grid-column: 1 / 13; grid-row: 2; margin-top: 1rem; }
/* the table's caption tags in the body register (Ivan 2026-09-17) */
/* the research areas as the resources heading's sub (Ivan 2026-09-17) */
.res-paper-page .section-split.res-head-stack > .section-sub.res-tags { display: flex; margin-top: 1.25rem; }
.res-paper-page .res-table-wrap > .res-tags span { font-family: var(--font-family-sans); font-size: var(--text-large-size); line-height: var(--text-large-line-height); letter-spacing: -0.011em; }   /* the sub's type, in citron */
/* the two cards' sub lines in the resource rows' small register (Ivan 2026-09-17) */
.res-paper-page .res-tags.res-cell-sub span { font-family: var(--font-family-sans); font-size: var(--text-small-size); line-height: var(--text-small-line-height); letter-spacing: -0.011em; }
section:has(#resources-h) .res-cell > .res-title + .res-sum { font-size: var(--text-small-size); line-height: var(--text-small-line-height); color: var(--text-tertiary); }
/* the resources cell's own heading and its tag line (Ivan 2026-09-17) */
.res-cell > .res-tags.res-cell-sub { margin: 0; }   /* the cell's own gap, so it lines up with the citation card's sub */
.res-cell > .res-tags.res-cell-sub + .res-resources { margin-top: 1.5rem; }
/* the full paper in the door's layout: centred heading, line, buttons, the
 * preview frame beneath (Ivan 2026-09-17) */
.res-paper-door .res-hero-actions { justify-content: center; margin: 0; }
/* a lone related card across the row: the figure on the left half, the
 * card's text on the right, centred against it (Ivan 2026-09-17) */
.res-grid.res-grid-solo { grid-template-columns: minmax(0, 1fr); }
.res-paper.res-paper-wide { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; grid-row: auto; column-gap: 48px; row-gap: 0; align-items: center; padding: 2rem; }   /* twice the grid's gutter between figure and text (Ivan 2026-09-17) */
.res-paper-wide > .res-fig { margin: 0; }
.res-paper-wide > .res-paper-body { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.res-paper-wide > .res-paper-body > .res-tags { margin-top: 10px; }
.res-paper-wide > .res-paper-body > .res-authors { margin-top: 20px; }
@media (width <= 940px) { .res-paper.res-paper-wide { grid-template-columns: minmax(0, 1fr); row-gap: 12px; padding: 1.5rem 1rem; } }
/* the research pages' doors: 1rem more between the line and the button (Ivan 2026-09-17) */
.res-door .door-member { margin-bottom: 38px; }
/* the square loop's top tiles carry their name above (Ivan 2026-09-17) */
.res-unit.is-top { flex-direction: column-reverse; translate: -50% calc(-100% + 24px); }

/* Contact page (contact.html): the site's heading split, then the
 * homepage's door row holding the form. The form reads as a sentence: a
 * word, then the field it introduces; the topic as pill radios; the message
 * as a textarea. Fields take the auth box's input treatment, the send button
 * the hero's primary. */
.contact-door { text-align: left; }
/* one centred column, the founders flanking the heading: the disc becomes
 * a full-width layer over the copy block, a face at each side, its halo
 * off; the sub on a narrower measure (Ivan 2026-09-21) */
.contact-hero .section-split { align-items: start; row-gap: 0; }
.contact-hero .contact-copy { grid-column: 1 / 13; grid-row: auto; position: relative; text-align: center; padding-block: 0; }
.contact-hero .contact-side { grid-column: 3 / 11; grid-row: auto; text-align: center; margin-top: 3rem; }   /* +1rem above the box (Ivan 2026-09-21) */
.contact-hero .section-split > .contact-copy > .section-head { text-align: center; }
.contact-hero .section-split > .contact-copy > .section-sub.contact-sub { max-width: 30em; margin-inline: auto; text-align: center; }
/* the founders as a small pair above the heading (Ivan 2026-09-21): a 176 disc
 * holding two 72px faces, the halo off */
.contact-copy .res-orb { --orb: 176px; position: relative; margin: -56px auto 0; justify-self: center; }   /* the disc is taller than the pair: pulled up so the faces sit 24 above the heading */
.contact-copy .res-orb-halo { display: none; }
.contact-sign { display: inline-block; margin-top: 1rem; color: var(--citron-300); }   /* +0.25rem under the sub (Ivan 2026-09-21) */
/* Althea's composer, from the prototype's r7/composer.css (dark theme,
 * verbatim where it could be): the box, its input, the mode button and its
 * menu (the shared item-menu), the teal glass send. Only the areas this
 * page uses are placed: text on top, the topic and send beneath. */
.chat-composer { --row-hover: rgb(255 255 255 / 11%); --cx-ground: #1b1b1b; display: flex; flex-direction: column; gap: 12px; text-align: left; }
.cx-box {
    position: relative; isolation: isolate;
    display: grid; grid-template-columns: 1fr auto; grid-template-areas: "text text" "reply send";
    align-items: center; column-gap: 6px; row-gap: 8px;
    padding: 8px; border: none; border-radius: 28px;   /* 8 all round: the same air beside a control as above it */
    background: rgb(255 255 255 / 4.5%);
    -webkit-backdrop-filter: blur(20px) saturate(1.3); backdrop-filter: blur(20px) saturate(1.3);
    box-shadow: 0 1px 2px rgb(0 0 0 / 28%), 0 10px 30px rgb(0 0 0 / 35%);
}
.cx-box::after, .cx-glass::before {
    content: ''; position: absolute; inset: 0; z-index: 1; padding: 1px; border-radius: inherit;
    background: radial-gradient(38% 60% at 22% 6%, rgb(255 255 255 / 55%) 0%, rgb(255 255 255 / 0%) 76%), rgb(255 255 255 / 11%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude;
    pointer-events: none; transition: background 150ms linear;
}
.cx-glass { position: relative; isolation: isolate; -webkit-backdrop-filter: blur(20px) saturate(1.5); backdrop-filter: blur(20px) saturate(1.5); box-shadow: 0 1px 2px rgb(0 0 0 / 28%), 0 6px 18px rgb(0 0 0 / 22%); }
.cx-glass > * { position: relative; z-index: 2; }
.cx-glass.cx-teal { background: rgb(46 88 90 / 82%); }
.cx-glass.cx-teal::before { background: radial-gradient(38% 60% at 22% 6%, rgb(255 255 255 / 70%) 0%, rgb(255 255 255 / 0%) 76%), rgb(167 215 214 / 28%); }
.cx-input {
    grid-area: text; width: 100%; min-height: 44px; max-height: 40vh; padding: 8px; box-sizing: border-box;   /* 8 all round: with the box's 8, the text sits 16 from every edge, the same as its distance to the row */
    resize: none; border: 0; background: none; outline: none; color: var(--text-primary);
    font-family: var(--font-family-sans); line-height: 20px; font-size: var(--text-regular-size); overflow-y: auto;
}
.cx-input::placeholder { color: var(--text-quaternary); }
/* the reply address in the input's own register, one line in the mode's slot */
.cx-reply-wrap { grid-area: reply; position: relative; display: block; min-width: 0; }
.cx-reply-icon { position: absolute; left: 14px; top: 50%; translate: 0 -50%; width: 16px; height: 16px; color: var(--teal-400); pointer-events: none; }   /* Solar letter in the accent, the 16 glyph at 2.25 (the glyph rule) */
.cx-reply-icon [stroke-width] { stroke-width: 2.25; }
.cx-input.cx-reply {
    width: 100%; min-height: 44px; height: 44px; max-width: none; padding: 12px 16px 12px 38px; border-radius: 20px;   /* the box is 28, less the 8 of padding between them: concentric */
    /* the well the composer gives a control at rest (send with nothing to send): the dark
     * ground and its hairline, so the address reads as a field inside the box */
    background: rgb(14 14 14 / 82%); border: 1px solid rgb(255 255 255 / 14%);   /* a deeper well and the menu's hairline, so the field stands off the glass */
    transition: border-color 120ms ease;
}
.cx-input.cx-reply::placeholder { color: var(--text-tertiary); }
.cx-input.cx-reply:focus { border-color: rgb(255 255 255 / 28%); }
/* the browser's autofill tint would paint the well blue: keep the well's own ground and ink */
.cx-input.cx-reply:-webkit-autofill, .cx-input.cx-reply:-webkit-autofill:focus { -webkit-box-shadow: inset 0 0 0 1000px #121313; -webkit-text-fill-color: var(--text-primary); caret-color: var(--text-primary); transition: background-color 9999s ease-out; }
.cx-btn, .cx-send { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; border: none; border-radius: 999px; background: none; color: var(--text-secondary); cursor: pointer; }
.cx-btn svg, .cx-send svg, .cx-mode svg { width: 20px; height: 20px; }
/* a page's box, expanded, opens where it stands: the grown layout at 360 tall */
.cx-box { grid-template-rows: auto auto; }   /* the box follows the text: four lines at rest, then it grows, no scroll */
.cx-box .cx-input:not(.cx-reply) { max-height: none; overflow: hidden; }
.cx-btn svg [stroke-width], .cx-send svg [stroke-width], .cx-mode svg [stroke-width] { stroke-width: 1.8; }
.cx-mode-wrap { grid-area: mode; position: relative; display: inline-flex; }
.cx-mode {
    display: inline-flex; align-items: center; gap: 6px; height: 44px; padding: 0 14px; border: none; border-radius: 999px;
    background: none; color: var(--text-secondary); font: inherit; font-family: var(--font-family-sans); font-size: var(--text-regular-size); cursor: pointer;
    transition: background 120ms ease, color 120ms ease;
}
.cx-mode svg { width: 16px; height: 16px; }
.cx-mode[aria-expanded='true'] { background: rgb(255 255 255 / 6%); color: var(--text-primary); }
.cx-send { grid-area: send; justify-self: end; background: rgb(46 88 90 / 82%); color: #fff; transition: background 120ms ease; }
.cx-send:disabled { background: rgb(28 30 30 / 72%); color: var(--text-quaternary); cursor: default; }
.cx-send:disabled::before { background: radial-gradient(38% 60% at 22% 6%, rgb(255 255 255 / 45%) 0%, rgb(255 255 255 / 0%) 76%), rgb(255 255 255 / 8%); }
@media (any-hover: hover) {
    .cx-btn:hover, .cx-mode:hover { background: var(--row-hover); color: var(--text-primary); }
    .cx-glass.cx-teal:not(:disabled):hover { background: rgb(46 88 90); }
}
@media (prefers-reduced-transparency: reduce) { .cx-box, .cx-glass { -webkit-backdrop-filter: none; backdrop-filter: none; } .cx-box { background: var(--cx-ground); } .cx-glass.cx-teal { background: #2e585a; } }
/* the shared item menu, and the mode menu's two-line rows */
.item-menu {
    position: absolute; right: 0; top: 26px; z-index: 5; display: flex; flex-direction: column; gap: 1px; min-width: 220px; padding: 4px;
    border: var(--border-hairline) solid rgb(255 255 255 / 12%); border-radius: 12px; background: var(--cx-ground); box-shadow: 0 8px 24px rgb(0 0 0 / 45%);
}
.item-menu[hidden] { display: none; }
.item-menu button { padding: 6px 8px; border: none; border-radius: 6px; background: none; color: var(--text-secondary); font: inherit; font-family: var(--font-family-sans); font-size: var(--text-mini-size); text-align: left; cursor: pointer; }
@media (any-hover: hover) { .item-menu button:hover { background: var(--row-hover); color: var(--text-primary); } }
.item-menu.cx-mode-menu { left: 0; right: auto; top: calc(100% + 8px); bottom: auto; z-index: 40; min-width: 272px; padding: 8px; border-radius: 20px; }
.item-menu.cx-mode-menu.is-above { top: auto; bottom: calc(100% + 8px); }
.item-menu.cx-mode-menu button { display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; border-radius: 12px; }
.item-menu.cx-mode-menu button[aria-checked='true'] { background: rgb(255 255 255 / 9%); }
.cx-mode-item { flex: 1; min-width: 0; }
.cx-mode-name { display: block; font-size: var(--text-small-size); color: var(--text-primary); }
.cx-mode-line { display: block; margin-top: 2px; font-size: var(--text-mini-size); line-height: 1.4; color: var(--text-quaternary); }
/* the field a warning names: ringed in the accent */
.cx-input.cx-reply.is-missing, .cx-input.cx-reply.is-missing:focus { border-color: var(--teal-400); }
.cx-input:not(.cx-reply).is-missing::placeholder { color: var(--citron-300); }
/* the badge atom at the field's right end, in the accent's register */
.cx-reply-badge { position: absolute; right: 12px; top: 50%; translate: 0 -50%; border-radius: 999px; font-weight: var(--font-weight-medium); background: rgba(207, 212, 120, 0.14); color: var(--citron-300); pointer-events: none; }
.cx-reply-badge[hidden] { display: none; }
.cx-reply-wrap:has(.cx-reply-badge:not([hidden])) .cx-reply { padding-right: 132px; }
.cx-box:has(.cx-input:not(.cx-reply).is-missing)::after { background: radial-gradient(38% 60% at 22% 6%, rgb(255 255 255 / 55%) 0%, rgb(255 255 255 / 0%) 76%), var(--teal-400); }
.contact-direct { margin: 44px 0 0; font-size: var(--text-large-size); line-height: var(--text-large-line-height); color: var(--text-secondary); text-align: center; }   /* the sub's register (Ivan 2026-09-21) */
.contact-direct a { color: var(--teal-400); text-decoration: none; }
.contact-direct a:hover { text-decoration: underline; text-underline-offset: 3px; }
.contact-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* a short page: the body is a column flex (base.css), so main grows and the
 * footer sits at the bottom of the viewport (Ivan 2026-09-21) */
.contact-page { flex: 1 0 auto; display: flex; flex-direction: column; justify-content: center; }   /* the band sits in the middle of whatever height is spare (Ivan 2026-09-21) */
.contact-page > .band { flex: none; }
@media (width <= 940px) { .contact-hero .contact-side { grid-column: 1 / 13; } }
    }
/* the sent state: the demo's ask bubble and response plate (hero-demo.css,
 * the values copied), entering with its motion */
.cx-box { transition: opacity 0.35s var(--motion-curve-house), transform 0.35s var(--motion-curve-house); }
.cx-box.hd-out { opacity: 0; transform: translateY(-12px); }
.contact-form[hidden], .contact-sent[hidden] { display: none; }
.contact-sent { position: relative; display: flex; align-items: center; justify-content: center; text-align: left; }
.contact-orb { position: absolute; z-index: 0; pointer-events: none; }   /* sized and offset by its script: bleeds 120px past the plate */
/* the plate is the shelf's own (art-plate hd-response); here it stands at the
 * box's height with the message centred, and no fixed 350 */
/* the plate is the shelf's own (art-plate hd-response); here it stands at the
 * box's height with the message centred, and no fixed 350 */
.contact-sent .contact-answer { width: auto; max-width: 100%; min-height: 0; justify-content: center; align-items: center; text-align: center; z-index: 1; }
.contact-answer-text { margin: 0; max-width: 34em; font-size: var(--text-regular-size); line-height: 1.55; color: var(--text-primary); text-wrap: pretty; }
@media (prefers-reduced-motion: reduce) { .cx-box { transition: none; } }
