/* Overtime Men's Health · Member portal showcase
   Three type voices: Fraunces (titles, greeting, big numbers) ·
   system sans (body) · IBM Plex Mono (labels, serials, axes). */

:root {
    --paper: #fbf7ef;
    --cream: #f6f0e4;
    --card: linear-gradient(180deg, #ffffff 0%, #fefcf7 100%);
    --ink: #191713;
    --mute: #565149;
    --faint: #6f6a5f;
    --line: rgba(25, 23, 19, 0.1);
    --line-strong: rgba(25, 23, 19, 0.14);
    --line-soft: rgba(25, 23, 19, 0.08);

    --champagne: #b8973f;
    /* Darkened from #8c6f2a on 2026-08-04. --deep is the portal's small-text gold, and it measured
       4.44:1 on paper, 4.18:1 on cream and 4.01:1 on the cream wash: under the 4.5 AA bar on every
       light ground it is actually used on, by a hair, everywhere. That single hair accounted for most
       of the failing pairs the critique measured (the Learn eyebrow and CTA, the shop pill, the coach
       inline note, the membership "/yr", and the Privacy Policy link in every footer).
       #7a5f22 clears all of them: paper 5.64, cream 5.31, card 5.87, cream wash 5.08, copper wash 4.77.
       ⚠️ Size was NOT the fix and cannot be: WCAG requires 4.5:1 for anything under 18.66px, so raising
       these labels from 9px to 11px would have improved readability and cleared zero failures. The
       critique framed size and contrast as one problem, and they are two.
       club.css redefines --deep as #d4b366 for the dark theme, so this only moves the light value. */
    --deep: #7a5f22;
    --gold: #febb00;
    --gold-warm: #c7a24e;
    --gold-light: #e6d3a0;
    --dark-a: #201308;
    --dark-b: #4a3115;

    /*
     | TYPE SCALE, added 2026-08-04. Until now the portal had NO size tokens at all: no --fs-*, no
     | --text-*, no --size-*. Every step was retyped as a literal, so `8.5px` existed as 22 separate
     | declarations in this file plus 24 more inline in Blade templates. Changing the label scale meant
     | editing 46 places and hoping. Compare colour, where the token layer is near-total and a single
     | --deep edit above cleared most of the portal's contrast failures in one line. That asymmetry is
     | the whole reason for this block.
     |
     | ⚠️ EVERY VALUE HERE IS THE VALUE THAT WAS ALREADY IN USE. This block plus the migration that
     | follows it changes nothing on screen, by design: it was verified by measuring computed font sizes
     | across nine portal pages before and after and requiring them to be identical. A refactor that
     | also moves pixels cannot be reviewed, because you cannot tell a mistake from an intention.
     |
     | Names match the roles documented in DESIGN.md's typography block, so the stylesheet and the design
     | system use one vocabulary. The consolidation that SHOULD follow (the reading band carries five
     | near-duplicate steps at w400: 13, 13.5, 14, 14.5, 15, of which 14.5 is the real body at 67 uses)
     | is a separate, visible change and deliberately not bundled in here.
     */
    --fs-display: clamp(38px, 5.2vw, 64px);
    --fs-statfigure: 26px;
    --fs-headline: 23px;
    --fs-subhead: 21px;
    --fs-lede: 15px;
    --fs-body: 14.5px;
    /* DEPRECATED 08-11 (stage 4A reading-band collapse): --fs-body-dense (14px) and
       --fs-supporting-tight (13px) were the density duplicates. Consumers moved to --fs-body and
       --fs-supporting. These aliases remain only so a straggler reference cannot break; they are
       removed once the grep comes back empty. */
    --fs-body-dense: 14px;
    --fs-supporting: 13.5px;
    --fs-supporting-tight: 13px;
    --fs-caption: 12.5px;
    --fs-caption-tight: 12px;
    --fs-label-lg: 11px;
    --fs-meta: 10px;
    --fs-label: 9.5px;
    --fs-micro: 9px;
    --fs-micro-tight: 8.5px;
    --fs-nano: 8px;

    --good: #1c7a4e;
    /* Shifted from #b0701c on 2026-08-11: that amber measured 3.79:1 on paper, under the 4.5 floor
       for the 12.5px Watch labels it colours. #8a5a10 measures 5.53:1 on paper and keeps the hue.
       club.css owns the dark-theme value. Wash follows the same hue. */
    --warn: #8a5a10;
    --bad: #b3261e;
    --good-wash: rgba(28, 122, 78, 0.09);
    --warn-wash: rgba(138, 90, 16, 0.1);
    --bad-wash: rgba(179, 38, 30, 0.09);

    --serif:'Helvetica Neue','Helvetica Neue LT Std',Helvetica,Arial,sans-serif;
    --sans:
        "Helvetica Neue", -apple-system, BlinkMacSystemFont, Helvetica, Arial,
        sans-serif;
    --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

    /*
     | MOTION, added 2026-08-04 (Phase 4). Three curves total, one duration ladder, and a rule about
     | what may move: transform and opacity only, under 300ms, ease-out for UI, the light spring for
     | presses and small successes. Every interactive state on the portal reads from these, so motion
     | reads as one instrument rather than thirty scattered .2s ease literals. Reduced-motion removes
     | the lot and keeps opacity-only fades where a state change still needs acknowledging.
     */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    --dur-press: 120ms;
    --dur-ui: 240ms;
    --dur-sheet: 300ms;

    --r-card: 24px;
    --r-tile: 20px;
    --shadow:
        0 1px 2px rgba(25, 23, 19, 0.04), 0 10px 28px rgba(140, 111, 42, 0.07),
        0 30px 70px rgba(140, 111, 42, 0.05);
    --shadow-soft:
        0 1px 2px rgba(25, 23, 19, 0.03), 0 6px 18px rgba(140, 111, 42, 0.05);

    /*
     | SEMANTIC TEXT TOKENS, added 2026-08-11 (typography migration stage 3). Aliases over the
     | primitives, not new colors: the alias carries WHY the text is that color, which is what
     | stops the next literal from being invented. Because they reference the primitives,
     | club.css's dark redefinitions flow through with no extra mapping.
     | Gold rule unchanged: --gold/#febb00 and the champagne ramp are fills and large-display
     | accents, never text on light grounds. Small gold text is always --text-premium.
     */
    --text-primary: var(--ink);
    --text-secondary: var(--mute);
    --text-muted: var(--faint);
    --text-inverse: var(--paper);
    --text-interactive: var(--deep);
    --text-premium: var(--deep);
    --text-success: var(--good);
    --text-warning: var(--warn);
    --text-critical: var(--bad);
    --text-disabled: #9a948a; /* disabled states only: contrast-exempt by design, never content */

    /* The five weights the system uses (bold added 08-11, stage 4A: the 700s were real emphasis —
       CTAs, badges, selected states — not a bypass). Nothing else may be declared. */
    --fw-display: 300;
    --fw-regular: 400;
    --fw-medium: 500;
    --fw-semibold: 600;
    --fw-bold: 700;

    /*
     | SPECIALIZED MEASURES, deliberately outside the reading scale. These never style sentences.
     | --fs-hero-figure: rank/score moments only (the standings rank). Responsive: 88px desktop,
     | 48px floor on phones. Always paired with a text label; size alone never carries meaning.
     |
     | --fs-price-*: the canonical money system (stage 4B). One family, three context variants:
     | display = marketing/pricing cards (56px desktop max, NOT a fixed size); selection = plan/
     | term pickers, prominent but subordinate to the page heading; summary = checkout/transactional,
     | compact on purpose so the total due never fights the commitment terms. Cadence/annual/
     | comparison/disclosure keep readable steps and never drop below --mute contrast.
     | Public pages that cannot load od.css get these from partials/price-tokens.blade.php, and
     | tests/Feature/PriceTokenParityTest.php fails if the two definitions ever diverge.
     |
     | --fs-price-value / --fs-price-badge added 08-12. Stage 4B built roles for what a thing COSTS
     | (display/selection/summary) and for the terms around it (cadence/annual/comparison/
     | disclosure), but no role for what a thing is WORTH. So the two claims that argue the
     | membership pays for itself were never migrated and stayed hardcoded below the family's own
     | 12px floor: .plan__val at 9.5px ("$1,796 value", "Members save $2,634 / yr on average") and
     | .plan__fold at 9px ("Save $593 with the yearly plan"). Those are the most persuasive numbers
     | on the homepage and they were the smallest text on it.
     | Measured for comparison the same day: Superpower's mobile site floors at 10px and puts its
     | price in the hero subhead at 14px (OT-Bot-Library/references/superpower-site-audit-2026-08-12).
     | value = inline worth/savings claims in a feature row; at <=560px .plan__val takes its own
     | full-width line, so 12px does not compete with the feature text. badge stays a step down at
     | 11px because .plan__fold is a fixed-width folded-corner ribbon and its geometry is the
     | constraint, not legibility.
     */
    --fs-hero-figure: clamp(48px, 8vw, 88px);
    --fs-price-display: clamp(34px, 6vw, 56px);
    --fs-price-selection: clamp(28px, 4vw, 40px);
    --fs-price-summary: clamp(20px, 2.2vw, 24px);
    --fs-price-cadence: 14px;
    --fs-price-annual: 12px;
    --fs-price-comparison: 12.5px;
    --fs-price-disclosure: 12.5px;
    --fs-price-value: 12px;
    --fs-price-badge: 11px;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}
html {
    scroll-behavior: smooth;
    /* Both lines are the iPhone fix for the topbar appearing to detach while scrolling
       (Clement, 08-06). iOS rubber-bands the WHOLE page, position:fixed bars included, so
       every bounce near the top rode the bar down and exposed whatever sits behind <html>.
       Nothing did: only body painted paper, so the gap rendered as the raw browser canvas,
       dark in dark mode, the strip in his screenshot. viewport-fit=cover (08-05) then put
       that strip in front of the status bar instead of behind Safari chrome.
       - background: the same paper as body, so anything a bounce exposes is invisible.
       - overscroll-behavior-y: no rubber-band at all, so the bar never rides. Also disables
         Safari pull-to-refresh here, which is correct for an app-like portal. */
    background: var(--paper);
    overscroll-behavior-y: none;
}
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
}

body {
    font-family: var(--sans);
    font-size: var(--fs-body);
    line-height: 1.6;
    color: var(--ink);
    background: var(--paper);
    -webkit-font-smoothing: antialiased;
}

/* Atmosphere: fixed champagne corner glows under content, film grain above. */
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background:
        radial-gradient(
            560px 400px at 0% 0%,
            rgba(199, 162, 78, 0.11),
            transparent 70%
        ),
        radial-gradient(
            700px 520px at 100% 100%,
            rgba(184, 151, 63, 0.09),
            transparent 72%
        );
}
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 2147483000;
    pointer-events: none;
    opacity: 0.05;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size: 240px 240px;
}

::selection {
    background: var(--gold-light);
    color: var(--ink);
}

a {
    color: inherit;
}
button {
    font: inherit;
    color: inherit;
    cursor: pointer;
}
img {
    display: block;
    max-width: 100%;
}
em {
    font-style: italic;
}

/* ---------- Shell ---------- */
.shell {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: 256px minmax(0, 1fr);
    min-height: 100vh;
}

.sidebar {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 32px;
    padding: 34px 26px 28px;
    border-right: 1px solid var(--line-soft);
}
.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
}
.brand-logo {
    width: 162px;
    height: auto;
    display: block;
}
.topbar .brand-logo {
    width: 118px;
}
.brand-mark {
    font-family: var(--mono);
    font-size: var(--fs-meta);
    letter-spacing: 0.14em;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    flex: none;
}
.brand-word {
    font-family: var(--serif);
    font-weight: 400;
    font-size: 17px;
    letter-spacing: -0.01em;
    line-height: 1.15;
}
.brand-word small {
    display: block;
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--faint);
    margin-top: 3px;
}

.nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.nav a {
    position: relative;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 11px 16px;
    border-radius: 999px;
    text-decoration: none;
    font-size: var(--fs-body);
    color: var(--mute);
}
.nav a:hover {
    color: var(--ink);
    background: rgba(25, 23, 19, 0.035);
}
.nav a svg {
    width: 18px;
    height: 18px;
    flex: none;
    color: var(--faint);
    transition: color 0.2s ease;
}
.nav a:hover svg {
    color: var(--mute);
}
.nav a[aria-current] {
    color: var(--ink);
    font-weight: 600;
    background: rgba(184, 151, 63, 0.1);
}
/* The active page gets a gold dot at the trailing edge (2026-08-04 chrome pass). Bold ink alone
   was a weak signal; the dot is the same device the mobile drawer uses, one system both chrome. */
.nav a[aria-current]::after {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--gold);
    margin-left: auto;
    flex: none;
}
.nav a[aria-current] svg {
    color: var(--deep);
}

.side-foot {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.member-chip {
    display: flex;
    align-items: center;
    gap: 12px;
    border-top: 1px solid var(--line-soft);
    padding-top: 16px;
}
.mc-ava {
    width: 36px;
    height: 36px;
    border-radius: 999px;
    flex: none;
    display: grid;
    place-items: center;
    font-family: var(--serif);
    font-weight: 400;
    font-size: var(--fs-lede);
    color: #fbf7ef;
    background: linear-gradient(135deg, #c7a24e 0%, #b8973f 48%, #7a5f22 100%);
    box-shadow: inset 0 1px 1px rgba(255, 244, 214, 0.4);
}
.member-chip .mc-name {
    font-size: var(--fs-supporting);
    font-weight: 600;
}
.member-chip .mc-meta {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--faint);
    margin-top: 4px;
    line-height: 1.9;
}
.careline {
    font-family: var(--mono);
    font-size: var(--fs-label);
    letter-spacing: 0.12em;
    color: var(--mute);
    text-decoration: none;
}
.careline:hover {
    color: var(--ink);
}

/* Mobile chrome (hidden on desktop) */
.topbar,
.bottomnav {
    display: none;
}

.main {
    padding: clamp(28px, 4.5vw, 60px) clamp(22px, 4.5vw, 64px) 90px;
    max-width: 1280px;
    width: 100%;
    /* The grid column may shrink below the content's min-content size. Needed 2026-08-04 when the
       add-on carousel asked for 680px of min-content (its widest panel + padding) and the 1fr
       track blew the whole page out to 716px of sideways scroll on a phone. */
    min-width: 0;
}

/* ---------- Type voices ---------- */
.eyebrow {
    font-family: var(--mono);
    font-size: var(--fs-label);
    font-weight: 500;
    letter-spacing: 0.26em;
    text-transform: uppercase;
    color: var(--faint);
}
.page-title {
    font-family: var(--serif);
    font-weight: 300;
    font-size: clamp(38px, 5.2vw, 64px);
    line-height: 0.95;
    letter-spacing: -0.02em;
    margin-top: 14px;
    text-wrap: balance;
}
.page-title em,
.sec-title em {
    font-style: italic;
    color: var(--deep);
}
.lede {
    color: var(--mute);
    font-size: var(--fs-lede);
    margin-top: 14px;
    max-width: 52ch;
}
.sec-title {
    font-family: var(--serif);
    font-weight: 400;
    font-size: var(--fs-headline);
    letter-spacing: -0.01em;
    line-height: 1.1;
}
.mono {
    font-family: var(--mono);
}

/* ---------- Cards ---------- */
.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    box-shadow: var(--shadow);
    padding: 28px;
}
/*
 | .card--lead : THE PAGE'S SUBJECT. Added 2026-08-04.
 |
 | Measured cause. Across nine portal pages, 36 of 40 cards shared ONE identical surface: same gradient,
 | same 1px rgba(25,23,19,.1) hairline, same 24px radius, same shadow. So no card was ever more important
 | than another, every page read as a list of equal-weight boxes, and no page had a subject. That is why
 | the portal read safe despite good tokens and good type.
 |
 | Why a hairline and not a shadow. DESIGN.md's Ambient-Only rule forbids shadow from carrying hierarchy:
 | "If two surfaces must read as different levels, that is a hairline, a ground change, or a radius
 | change, not a deeper shadow." A gold hairline is also the device the three dark cards already use
 | (rgba(230,211,160,.18)), so this is the system repeating itself on light rather than a new idea.
 |
 | No new colour value. color-mix takes the existing --champagne, which BOTH themes define (od #b8973f,
 | club #c7a24e), so each theme contributes its own gold and the dark portal needs no separate rule.
 | Two classes beat club.css's single-class .card override regardless of load order, which is why this
 | works without duplicating it there.
 |
 | ⚠️ USE IT ONCE PER PAGE, AND ONLY WHERE A PAGE GENUINELY HAS ONE SUBJECT. The point is contrast with
 | the supporting cards; a second lead card on the same page cancels the first and the page is flat again,
 | just louder. Settings deliberately has none: it is a list of equal settings and ranking one would be
 | noise. Membership needs none: its plan card is already a dark card. Pages with a single card have no
 | hierarchy to express.
 */
.card.card--lead {
    border-color: color-mix(in srgb, var(--champagne) 55%, transparent);
}

.card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 20px;
}

/* Dark focal object (one per view) */
.dark-card {
    position: relative;
    overflow: hidden;
    background: linear-gradient(140deg, var(--dark-a) 0%, var(--dark-b) 100%);
    color: var(--gold-light);
    border: 1px solid rgba(230, 211, 160, 0.18);
    border-radius: var(--r-card);
    box-shadow:
        0 2px 4px rgba(25, 23, 19, 0.12),
        0 18px 44px rgba(32, 19, 8, 0.28);
}
/* 0.55 -> 0.70 on 2026-08-04. Gold-light at 55% over the dark card composites to #96835F, which measured
   4.13:1: under AA, and this is the pattern used for every 9px label on every always-dark card in the
   portal (labs next-draw, membership plan, orders, progress). 70% gives 5.77:1 and still reads as a
   recessive label rather than body text. Alpha, not a new colour, so the warm tint is unchanged. */
.dark-card .eyebrow {
    color: rgba(230, 211, 160, 0.7);
}

/* ---------- Pills & status ---------- */
.pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    border-radius: 999px;
    padding: 5px 11px;
    white-space: nowrap;
}
.s-good {
    color: var(--good);
    background: var(--good-wash);
}
.s-warn {
    color: var(--warn);
    background: var(--warn-wash);
}
.s-bad {
    color: var(--bad);
    background: var(--bad-wash);
}
.chip-pop {
    color: var(--deep);
    background: rgba(184, 151, 63, 0.13);
}
.chip-line {
    color: var(--mute);
    border: 1px solid var(--line-strong);
}

.dot {
    width: 6px;
    height: 6px;
    border-radius: 999px;
    flex: none;
}
.dot.g {
    background: var(--good);
}
.dot.w {
    background: var(--warn);
}
.dot.b {
    background: var(--bad);
}

/* ---------- Buttons ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border-radius: 999px;
    border: 1px solid transparent;
    padding: 12px 22px;
    font-size: var(--fs-supporting);
    font-weight: 500;
    text-decoration: none;
    background: var(--ink);
    color: var(--paper);
    box-shadow:
        0 0 0 1px rgba(184, 151, 63, 0.22),
        0 8px 20px rgba(140, 111, 42, 0.16);
    transition:
        box-shadow var(--dur-ui) var(--ease-out),
        background var(--dur-ui) var(--ease-out),
        transform var(--dur-press) var(--ease-spring);
}
.btn:hover {
    background: #26221b;
    box-shadow:
        0 0 0 1px rgba(184, 151, 63, 0.4),
        0 10px 26px rgba(140, 111, 42, 0.24);
}
/* The full state set (2026-08-04 Phase 4): hover, keyboard focus, press, busy, disabled. */
.btn:focus-visible {
    outline: 2px solid var(--champagne);
    outline-offset: 3px;
}
.btn:active {
    transform: translateY(1px) scale(0.99);
    box-shadow:
        0 0 0 1px rgba(184, 151, 63, 0.3),
        0 4px 12px rgba(140, 111, 42, 0.18);
}
.btn[aria-busy="true"] {
    cursor: progress;
    opacity: 0.75;
    pointer-events: none;
}
.btn.ghost {
    background: transparent;
    color: var(--ink);
    border-color: var(--line-strong);
    box-shadow: none;
}
.btn.ghost:hover {
    background: rgba(25, 23, 19, 0.04);
}
.btn.on-dark {
    background: var(--gold-light);
    color: var(--dark-a);
    box-shadow:
        0 0 0 1px rgba(230, 211, 160, 0.25),
        0 8px 22px rgba(0, 0, 0, 0.3);
}
.btn.on-dark:hover {
    background: #efdfb6;
}

/*
 | .tlink : the portal's standard text link. DE-COSTUMED 2026-08-04.
 |
 | It was IBM Plex Mono at 9.5px, 0.2em tracking, UPPERCASE. Its actual content, read straight out of
 | the templates: "All your markers", "Ask your care team about these", "Back to the store", "Add to
 | this draw", "See where you stand", "Learn the numbers". Those are sentences. Setting a sentence in
 | tracked uppercase monospace is craft-floor's named tell, "monospace as a costume for technical
 | rather than for code, data, or measurement", and it breaks DESIGN.md's own Mono Means Measured rule,
 | which reserves the face for units, serials, dates, axes and eyebrow labels.
 |
 | Measured before deciding: 80 elements across nine portal pages were uppercase mono carrying three or
 | more words. 47 of them are this one class. That volume is not a brand device, it is a habit, and two
 | independent authorities call it the same thing.
 |
 | The underline stays, because once the shouting stops the link needs a real affordance. Sentence case
 | comes from the templates, which already write these in sentence case; only the transform was forcing
 | caps. Side benefit worth naming: the audit found dozens of 14-19px-tall link targets, all of them
 | this class, and 13.5px with its padding clears that.
 |
 | ⚠️ Kept in mono deliberately, because they ARE measured things: .eyebrow (a documented label role),
 | .sys-sum ("5 markers · 5 in range"), .ring-cap and .count-lab ("IN RANGE"), .last-draw (a date),
 | .m-raw (a lab's own assay string), and the footer (a brand name and a phone number).
 */
.tlink {
    font-size: var(--fs-supporting);
    color: var(--mute);
    text-decoration: none;
    border-bottom: 1px solid var(--line-strong);
    padding-bottom: 3px;
}
.tlink:hover {
    color: var(--ink);
    border-color: var(--ink);
}

/* ---------- Grid ---------- */
.grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 22px;
    margin-top: 38px;
}
.span-3 {
    grid-column: span 3;
}
.span-4 {
    grid-column: span 4;
}
.span-5 {
    grid-column: span 5;
}
.span-6 {
    grid-column: span 6;
}
.span-7 {
    grid-column: span 7;
}
.span-8 {
    grid-column: span 8;
}
.span-12 {
    grid-column: span 12;
}

/* ---------- Score ring ---------- */
.score-wrap {
    display: flex;
    align-items: center;
    gap: 30px;
    margin-top: 8px;
}
.ring-box {
    position: relative;
    width: 172px;
    height: 172px;
    flex: none;
}
.ring {
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}
.ring circle {
    fill: none;
    stroke-width: 6;
    stroke-linecap: round;
}
.ring-track {
    stroke: rgba(25, 23, 19, 0.08);
}
.ring-fill {
    stroke: url(#ringGold);
    stroke-dasharray: 527.8;
    stroke-dashoffset: 527.8;
    animation: ringdraw 1.7s cubic-bezier(0.3, 0.7, 0.25, 1) 0.35s forwards;
}
/* The arc ends at the member's own number. Until 09-23 this was a literal 95, which is the demo's 82,
   so every member's ring drew 82% whatever the figure in its centre said. Home sets --ring-to per ring. */
@keyframes ringdraw {
    to {
        stroke-dashoffset: var(--ring-to, 95px);
    }
}
.ring-center {
    position: absolute;
    inset: 0;
    display: grid;
    place-content: center;
    text-align: center;
}
.ring-num {
    font-family: var(--serif);
    font-weight: 300;
    font-size: 56px;
    line-height: 1;
    letter-spacing: -0.02em;
}
.ring-cap {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.26em;
    text-transform: uppercase;
    color: var(--faint);
    margin-top: 6px;
}

.delta {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: var(--fs-supporting);
    color: var(--good);
    font-weight: 500;
}
.delta svg {
    width: 13px;
    height: 13px;
}

.counts {
    display: flex;
    gap: 0;
    margin-top: 26px;
    border-top: 1px solid var(--line-soft);
    padding-top: 18px;
}
.counts > div {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.counts > div + div {
    border-left: 1px solid var(--line-soft);
    padding-left: 18px;
}
.count-num {
    font-family: var(--serif);
    font-weight: 300;
    font-size: 30px;
    line-height: 1;
}
.count-lab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--mute);
}

.big-num {
    font-family: var(--serif);
    font-weight: 300;
    font-size: 74px;
    line-height: 0.9;
    letter-spacing: -0.02em;
    margin-top: 16px;
}
.big-num .unit {
    font-size: 22px;
    letter-spacing: 0;
    color: var(--faint);
    margin-left: 6px;
}

/* ---------- Health ID card ---------- */
.id-slot {
    perspective: 1000px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.idcard {
    position: relative;
    aspect-ratio: 1.62;
    border-radius: var(--r-tile);
    background: linear-gradient(
        135deg,
        var(--dark-a) 0%,
        #31200c 55%,
        var(--dark-b) 100%
    );
    border: 1px solid rgba(230, 211, 160, 0.22);
    box-shadow:
        0 2px 4px rgba(25, 23, 19, 0.14),
        0 24px 50px rgba(32, 19, 8, 0.32),
        inset 0 1px 0 rgba(230, 211, 160, 0.14);
    padding: 22px 24px;
    display: flex;
    flex-direction: column;
    color: var(--gold-light);
    overflow: hidden;
    transform-style: preserve-3d;
    transition: transform 0.25s ease;
    will-change: transform;
}
.idcard .foil {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(
            420px circle at var(--mx, 72%) var(--my, 16%),
            rgba(254, 187, 0, 0.28),
            rgba(199, 162, 78, 0.1) 38%,
            transparent 62%
        ),
        linear-gradient(
            115deg,
            transparent 42%,
            rgba(230, 211, 160, 0.1) 50%,
            transparent 58%
        );
    mix-blend-mode: screen;
    transition: opacity 0.3s ease;
}
.id-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.3em;
    text-transform: uppercase;
}
.id-row.top {
    color: rgba(230, 211, 160, 0.85);
}
.id-chip {
    width: 40px;
    height: 29px;
    border-radius: 6px;
    margin-top: auto;
    margin-bottom: 14px;
    background: linear-gradient(140deg, var(--gold-warm), var(--deep));
    box-shadow:
        inset 0 1px 1px rgba(255, 244, 214, 0.5),
        inset 0 -1px 2px rgba(32, 19, 8, 0.6);
    position: relative;
}
.id-chip::after {
    content: "";
    position: absolute;
    inset: 6px 8px;
    border: 1px solid rgba(32, 19, 8, 0.35);
    border-radius: 3px;
}
.id-name {
    font-family: var(--mono);
    font-size: var(--fs-lede);
    letter-spacing: 0.34em;
    font-weight: 500;
    color: #efe0b8;
    text-shadow:
        0 -1px 0 rgba(0, 0, 0, 0.55),
        0 1px 0 rgba(230, 211, 160, 0.18);
}
.id-row.bot {
    margin-top: 12px;
    font-size: var(--fs-micro-tight);
    color: rgba(230, 211, 160, 0.62);
}
.id-cap {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--faint);
    text-align: center;
}

/* ---------- Journey stepper ---------- */
.steps {
    list-style: none;
    display: flex;
    margin-top: 24px;
    margin-bottom: 26px;
}
.steps li {
    flex: 1;
    position: relative;
    padding-top: 22px;
}
.steps li::before {
    content: "";
    position: absolute;
    top: 5px;
    left: 0;
    right: 0;
    height: 1px;
    background: var(--line);
}
.steps li:last-child::before {
    right: 40%;
}
.steps .s-dot {
    position: absolute;
    top: 0;
    left: 0;
    width: 11px;
    height: 11px;
    border-radius: 999px;
    background: var(--paper);
    border: 1.5px solid var(--faint);
}
.steps .done .s-dot {
    background: var(--champagne);
    border-color: var(--champagne);
}
.steps .now .s-dot {
    background: var(--paper);
    border-color: var(--deep);
    box-shadow: 0 0 0 4px rgba(184, 151, 63, 0.16);
}
.steps .s-lab {
    display: block;
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--mute);
}
.steps .now .s-lab {
    color: var(--deep);
}
.steps .s-sub {
    display: block;
    font-size: var(--fs-supporting);
    color: var(--ink);
    margin-top: 5px;
    padding-right: 14px;
}
.steps li:not(.done):not(.now) .s-sub {
    color: var(--faint);
}

.util-strip {
    margin: auto -28px -28px;
    padding: 16px 28px;
    background: var(--cream);
    border-top: 1px solid var(--line-soft);
    border-radius: 0 0 var(--r-card) var(--r-card);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    /* De-costumed 2026-08-04, same reason as .tlink: this strip renders "Care team: your provider ·
       your wellness advisor", which is a sentence, not a measurement. Was 9px uppercase mono at .16em. */
    font-size: var(--fs-caption);
    color: var(--mute);
}
.util-strip a {
    color: var(--ink);
    text-decoration: none;
}
.util-strip a:hover {
    border-bottom: 1px solid var(--ink);
}

/* ---------- Do this next ---------- */
.next-list {
    list-style: none;
    margin-top: 6px;
}
.next-list li {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 17px 0;
    border-top: 1px solid var(--line-soft);
}
.next-list li:first-child {
    border-top: 0;
}
.n-idx {
    font-family: var(--serif);
    font-weight: 300;
    font-size: 30px;
    color: var(--faint);
    width: 26px;
    flex: none;
    line-height: 1;
}
.n-body {
    flex: 1;
    min-width: 0;
}
.n-name {
    font-size: var(--fs-body);
    font-weight: 600;
}
.n-meta {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--mute);
    margin-top: 4px;
}
.n-go {
    flex: none;
}

/* ---------- Body systems ---------- */
.sys-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px;
    margin-top: 22px;
}
.sys {
    display: flex;
    flex-direction: column;
    gap: 10px;
    text-decoration: none;
    border: 1px solid var(--line-soft);
    border-radius: var(--r-tile);
    padding: 18px;
    background: rgba(255, 255, 255, 0.55);
    transition:
        border-color 0.2s ease,
        box-shadow 0.2s ease;
}
.sys:hover {
    border-color: var(--line-strong);
    box-shadow: var(--shadow-soft);
}
.sys svg {
    width: 26px;
    height: 26px;
    color: var(--mute);
}
.sys-name {
    font-size: var(--fs-body);
    font-weight: 600;
}
.sys-meta {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--faint);
    line-height: 1.9;
}
.sys-meta .w {
    color: var(--warn);
}
.sys-meta .b {
    color: var(--bad);
}

/* ---------- Range bars ---------- */
.mbar {
    position: relative;
    height: 5px;
    border-radius: 999px;
    background: rgba(25, 23, 19, 0.07);
    align-self: center;
    min-width: 90px;
}
.mbar .opt {
    position: absolute;
    top: 0;
    bottom: 0;
    border-radius: 999px;
    background: rgba(28, 122, 78, 0.22);
    transform-origin: left;
    animation: growx 0.9s cubic-bezier(0.3, 0.7, 0.25, 1) 0.3s backwards;
}
.mbar b {
    position: absolute;
    top: 50%;
    width: 9px;
    height: 9px;
    border-radius: 999px;
    transform: translate(-50%, -50%);
    background: var(--ink);
    box-shadow: 0 0 0 2.5px var(--paper);
}
/* Previous draw: a hollow ring behind the solid dot, so direction of change reads without a
   chart (2026-08-04 Phase 3). Smaller and under the current value when the two overlap. */
.mbar b.prev {
    width: 8px;
    height: 8px;
    background: var(--paper);
    border: 1.5px solid var(--faint);
    box-shadow: none;
    opacity: 0.85;
}
@keyframes growx {
    from {
        transform: scaleX(0);
    }
}

.rangebar {
    margin-top: 26px;
}
.rb-track {
    position: relative;
    height: 12px;
    border-radius: 999px;
    background: rgba(25, 23, 19, 0.06);
}
.rb-std {
    position: absolute;
    top: 0;
    bottom: 0;
    background: rgba(25, 23, 19, 0.08);
    border-radius: 999px;
}
.rb-opt {
    position: absolute;
    top: 0;
    bottom: 0;
    border-radius: 999px;
    background: linear-gradient(
        90deg,
        rgba(28, 122, 78, 0.28),
        rgba(28, 122, 78, 0.4)
    );
    transform-origin: left;
    animation: growx 1.1s cubic-bezier(0.3, 0.7, 0.25, 1) 0.4s backwards;
}
.rb-needle {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
}
.rb-needle i {
    display: block;
    width: 15px;
    height: 15px;
    border-radius: 999px;
    background: var(--ink);
    box-shadow:
        0 0 0 3px var(--paper),
        0 2px 6px rgba(25, 23, 19, 0.3);
}
.rb-needle span {
    position: absolute;
    top: -32px;
    left: 50%;
    transform: translateX(-50%);
    font-family: var(--mono);
    font-size: var(--fs-label-lg);
    font-weight: 500;
    color: var(--ink);
}
.rb-axis {
    display: flex;
    justify-content: space-between;
    margin-top: 12px;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.1em;
    color: var(--faint);
}
.rb-legend {
    display: flex;
    gap: 22px;
    margin-top: 16px;
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--mute);
}
.rb-legend span {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.rb-legend .sw {
    width: 16px;
    height: 7px;
    border-radius: 999px;
}
.rb-legend .sw.std {
    background: rgba(25, 23, 19, 0.12);
}
.rb-legend .sw.opt {
    background: rgba(28, 122, 78, 0.35);
}

/* ---------- Marker rows (labs) ---------- */
.mrows {
    display: flex;
    flex-direction: column;
}
.mrow {
    display: grid;
    grid-template-columns: 1.5fr 0.9fr 1.4fr 108px;
    gap: 18px;
    align-items: center;
    padding: 13px 0;
    border-top: 1px solid var(--line-soft);
    text-decoration: none;
    /* First-load reveal (2026-08-04 Phase 3): rows rise once, 24ms apart, capped at the twelfth
       so an 86-marker panel never leaves the last row waiting two seconds. */
    animation: mrowIn 0.32s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: calc(var(--i, 0) * 24ms);
}
@keyframes mrowIn {
    from {
        opacity: 0;
        transform: translateY(6px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}
@media (prefers-reduced-motion: reduce) {
    .mrow {
        animation: none;
    }
}
/* The count line under the labs lede + the hollow-dot legend (Phase 3). */
.labs-count {
    margin-top: 14px;
    font-size: var(--fs-caption);
    color: var(--mute);
    font-variant-numeric: tabular-nums;
}
.labs-count b {
    color: var(--ink);
    font-weight: 600;
}
.labs-count__out {
    color: var(--bad);
    font-weight: 600;
}
.labs-count__legend {
    margin-left: 14px;
    color: var(--faint);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.labs-count__legend i {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    border: 1.5px solid var(--faint);
    background: var(--paper);
}

/* Ghosted marker-bar preview on the empty labs state (2026-08-04 Phase 3). The shape of the real
   viz with zero values, so a brand-new member sees what a panel reads like. Deliberately washed
   to half strength: a preview, not a result. */
/* Shared hero band (labs data hero, membership lounge). Moved here from labs.blade's inline
   styles on 2026-08-04 so the membership page can use the same treatment. object-position keeps
   the subject in frame as the band narrows, so the crop never lands on empty wall on a phone. */
.labs-hero {
    margin: 0 0 20px;
    border-radius: var(--r-card);
    overflow: hidden;
    line-height: 0;
    box-shadow:
        0 2px 4px rgba(25, 23, 19, 0.05),
        0 16px 40px -22px rgba(32, 19, 8, 0.22);
}
.labs-hero img {
    width: 100%;
    height: clamp(168px, 23vw, 286px);
    object-fit: cover;
    object-position: 50% 62%;
}
@media (max-width: 820px) {
    .labs-hero img {
        height: 150px;
        object-position: 50% 62%;
    }
}

/* Hero rotator (2026-08-04, Clement's ask): the band crossfades between a curated set of brand
   stills, one frame every 11s, opacity only. No carousel chrome, no arrows: the imagery is
   ambient, and anything interactive would make it content. Frames are stacked absolute inside the
   band's fixed height so nothing reflows. JS drives the cycle; under reduced-motion it never
   starts, and the first frame is also the no-JS default so the band always shows something. */
.hero-rot {
    position: relative;
    height: clamp(168px, 23vw, 286px);
}
.hero-rot .rot-frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 62%;
    opacity: 0;
    transition: opacity 1.2s var(--ease-out);
}
.hero-rot .rot-frame.on {
    opacity: 1;
}
@media (max-width: 820px) {
    .hero-rot {
        height: 150px;
    }
}
@media (prefers-reduced-motion: reduce) {
    .hero-rot .rot-frame {
        transition: none;
    }
}
.ghost-rows {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-top: 26px;
    max-width: 420px;
    opacity: 0.55;
}
.ghost-row {
    position: relative;
    height: 5px;
    border-radius: 999px;
    background: rgba(25, 23, 19, 0.07);
}
.ghost-row i {
    position: absolute;
    top: 0;
    bottom: 0;
    border-radius: 999px;
    background: rgba(28, 122, 78, 0.22);
}
.ghost-row b {
    position: absolute;
    top: 50%;
    width: 9px;
    height: 9px;
    border-radius: 999px;
    transform: translate(-50%, -50%);
    background: var(--paper);
    border: 1.5px solid var(--faint);
}
.ghost-cap {
    font-family: var(--mono);
    font-size: var(--fs-meta);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--faint);
}

/* The nothing-ordered empty state with its brand still (2026-08-04 Phase 5): text left, vials
   right on wide screens, image drops below on mobile. */
.empty-split__wrap {
    display: grid;
    grid-template-columns: 1.25fr 1fr;
    gap: 30px;
    align-items: center;
}
.empty-split__art {
    margin: 0;
}
.empty-split__art img {
    width: 100%;
    height: auto;
    display: block;
    border-radius: 16px;
}
@media (max-width: 820px) {
    .empty-split__wrap {
        grid-template-columns: 1fr;
    }
    .empty-split__art {
        max-width: 420px;
    }
}
.mrow:first-child {
    border-top: 0;
}
.m-name {
    font-size: var(--fs-body);
}
.m-val {
    font-family: var(--mono);
    font-size: var(--fs-caption);
    font-weight: 500;
    white-space: nowrap;
}
.m-val em {
    font-style: normal;
    color: var(--faint);
    font-size: var(--fs-meta);
    margin-left: 3px;
}
.mrow .pill {
    justify-self: end;
}
.mrow .m-status {
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: 10px;
}
.mrow .m-status .pill {
    justify-self: auto;
}
a.mrow {
    border-radius: 12px;
    margin: 0 -12px;
    padding-left: 12px;
    padding-right: 12px;
}
a.mrow:hover {
    background: rgba(255, 255, 255, 0.85);
}
.m-view {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--deep);
}

.sys-head {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 6px;
}
.sys-head svg {
    width: 22px;
    height: 22px;
    color: var(--mute);
    flex: none;
}
.sys-head .sec-title {
    flex: 1;
}
.sys-head .sys-sum {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--faint);
    white-space: nowrap;
}

.toc {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 26px;
}
.toc a {
    text-decoration: none;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--mute);
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    padding: 8px 15px;
}
.toc a:hover {
    color: var(--ink);
    border-color: var(--ink);
}

section[id] {
    scroll-margin-top: 24px;
}

/* ---------- Trend chart ---------- */
.trend {
    margin-top: 10px;
}
.trend svg {
    width: 100%;
    height: auto;
}
.trend .axis {
    font-family: var(--mono);
    font-size: var(--fs-meta);
    fill: var(--faint);
    letter-spacing: 0.08em;
}
.trend .gridline {
    stroke: rgba(25, 23, 19, 0.07);
    stroke-width: 1;
}
.trend .tline {
    fill: none;
    stroke: var(--champagne);
    stroke-width: 2;
    stroke-linecap: round;
}
.trend .tdot {
    fill: var(--champagne);
}
.trend .tdot.last {
    fill: var(--paper);
    stroke: var(--deep);
    stroke-width: 2.5;
}
.trend .tfill {
    fill: url(#trendFill);
    opacity: 0.5;
}

/* ---------- Products ---------- */
.prod-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
    margin-top: 22px;
}
.product {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 24px;
}
.prod-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
}
.sku {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--faint);
}
.product h3 {
    font-size: 16.5px;
    font-weight: 600;
    letter-spacing: -0.01em;
}
.prod-note {
    color: var(--mute);
    font-size: var(--fs-supporting);
}
.price-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-top: 10px;
}
.price {
    font-family: var(--serif);
    font-weight: 300;
    font-size: 30px;
    letter-spacing: -0.01em;
}
.price .per {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--faint);
}
.retail {
    font-size: var(--fs-caption);
    color: var(--faint);
    text-decoration: line-through;
}
.product .btn {
    margin-top: 14px;
    align-self: flex-start;
}

.prow {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 18px 0;
    border-top: 1px solid var(--line-soft);
}
.prow:first-child {
    border-top: 0;
}
.prow-body {
    flex: 1;
    min-width: 0;
}
.prow .price {
    font-size: 22px;
}
.prow .btn {
    padding: 9px 18px;
    font-size: var(--fs-caption);
}
/* The right cell of a product row (2026-08-04): it had no styles, so the badge, the price pill,
   and the action wrapped wherever they fell. One right-aligned column now: badge, price, action,
   each on its own line, the action never colliding with the name. */
.prow-end {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
    flex: none;
    text-align: right;
}
.prow-end .btn {
    white-space: nowrap;
}

/* ---------- Art & skeletons ---------- */
.art-card {
    border-radius: var(--r-card);
    overflow: hidden;
    border: 1px solid var(--line);
    box-shadow: var(--shadow);
    background: var(--cream);
    margin: 0;
}
.art-card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    aspect-ratio: 4/3;
}
.art-card figcaption {
    padding: 12px 18px;
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--faint);
    background: var(--card);
    border-top: 1px solid var(--line-soft);
}

.skel {
    border-radius: 999px;
    height: 9px;
    background: linear-gradient(
        90deg,
        rgba(25, 23, 19, 0.06) 25%,
        rgba(25, 23, 19, 0.12) 37%,
        rgba(25, 23, 19, 0.06) 63%
    );
    background-size: 400% 100%;
    animation: shimmer 2s ease infinite;
}
.dark-card .skel {
    background: linear-gradient(
        90deg,
        rgba(230, 211, 160, 0.12) 25%,
        rgba(230, 211, 160, 0.24) 37%,
        rgba(230, 211, 160, 0.12) 63%
    );
    background-size: 400% 100%;
}
@keyframes shimmer {
    0% {
        background-position: 100% 0;
    }
    100% {
        background-position: 0 0;
    }
}

/* ---------- Load choreography ----------
   One system, two voices (craft floor: one authored moment, never one identical entrance on
   every section — 37 of 40 cards previously shared the exact same 14px/0.75s rise, which reads
   as a template loading, not a room being lit).
   - Cards: a quieter, quicker settle. 10px and 0.55s on the house exponential ease, so the page
     feels assembled rather than animated. Delay staggering stays on the existing --d markup.
   - The page title: the single authored moment per page. It resolves from a slight blur as it
     rises, like a lens pulling focus — the one place the member's eye starts, so the one place
     the motion is allowed to speak. Everything else defers to it.
   Total intro stays under ~600ms at the deepest --d in use. */
.rise {
    opacity: 0;
    transform: translateY(10px);
    animation: rise 0.55s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    animation-delay: calc(var(--d, 0) * 60ms);
}
@keyframes rise {
    to {
        opacity: 1;
        transform: none;
    }
}
/* The blur rides a SEPARATE non-filling animation: Chrome's fill-forwards freezes every
   property any keyframe names, so folding blur into the filling entrance left a permanent
   computed blur(0px) pinning a compositing layer on every page head. Split, the focus-pull
   plays once and evaporates; only opacity/transform keep their forwards fill. */
.pagehead.rise {
    animation:
        rise 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards,
        headfocus 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes headfocus {
    from {
        filter: blur(6px);
    }
    to {
        filter: blur(0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .rise,
    .pagehead.rise {
        animation: none;
        opacity: 1;
        transform: none;
        filter: none;
    }
    .ring-fill {
        animation: none;
        stroke-dashoffset: var(--ring-to, 95px);
    }
    .mbar .opt,
    .rb-opt {
        animation: none;
    }
    .skel {
        animation: none;
    }
    .idcard {
        transition: none;
    }
    .btn {
        transition: none;
    }
}

/* ---------- Details ---------- */
details {
    border-top: 1px solid var(--line-soft);
}
details summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 0;
    font-size: var(--fs-body);
    font-weight: 600;
}
details summary::-webkit-details-marker {
    display: none;
}
/* 09-25 preview (Clement): a chevron, not "+", so every dropdown reads as one. It turns when open.
   Drawn with a mask filled by currentColor, so a summary's own colour rules still apply. */
details summary::after {
    content: "";
    display: inline-block;
    flex: none;
    width: 14px;
    height: 14px;
    margin-left: 10px;
    vertical-align: middle;
    color: var(--faint);
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform .2s cubic-bezier(.23, 1, .32, 1);
}
details[open] summary::after {
    content: "";
    transform: rotate(180deg);
}
@media (prefers-reduced-motion: reduce) { details summary::after { transition: none; } }
details p {
    color: var(--mute);
    font-size: var(--fs-supporting);
    padding-bottom: 18px;
    max-width: 60ch;
}

/* ---------- Footer ---------- */
.foot {
    margin-top: 60px;
    padding-top: 22px;
    border-top: 1px solid var(--line-soft);
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 12px;
    font-family: var(--mono);
    font-size: var(--fs-meta);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--mute);
}
.foot a {
    color: inherit;
    text-decoration: none;
}
.foot a:hover {
    color: var(--ink);
}

/* ---------- Responsive ---------- */
@media (max-width: 1120px) {
    .grid {
        gap: 18px;
    }
    .span-3,
    .span-4,
    .span-5 {
        grid-column: span 6;
    }
    .span-7,
    .span-8 {
        grid-column: span 12;
    }
    .sys-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 820px) {
    .shell {
        grid-template-columns: 1fr;
    }
    .sidebar {
        display: none;
    }
    .topbar {
        /* position:relative context for the ::before cap below. */
        /* Fixed, not sticky: iOS Safari lets content peek above a position:sticky header
           that lives inside a CSS grid (.shell). Fixed pins it to the visual viewport on
           every browser. .main gets matching top padding below to offset the fixed header. */
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 45;
        display: flex;
        align-items: center;
        justify-content: space-between;
        /* Opaque + safe-area top so it fills behind the status bar / Dynamic Island. */
        padding: calc(16px + env(safe-area-inset-top)) 20px 16px;
        background: var(--paper);
        /* NO backdrop-filter here, and that is the fix, not a simplification: iOS Safari
           rasterises a fixed element's backdrop layer asynchronously, so while scrolling the
           header lags behind the finger and page content visibly slides through it before it
           snaps back (Clement's iPhone 16 Pro Max, 08-06; invisible in desktop emulation).
           The background is fully opaque, so the blur painted nothing anyway.
           translateZ(0) promotes the header to its own compositor layer, which keeps iOS from
           re-rasterising it mid-scroll. Safe on the fixed element itself: a transform only
           re-parents fixed DESCENDANTS, and the topbar has none. */
        transform: translateZ(0);
        border-bottom: 1px solid var(--line-soft);
    }
    /* Clement's screen recording (08-06, iPhone 16 Pro Max) shows the bar itself pinned but page
       content scrolling through a constant ~60px strip ABOVE it, in the status-bar zone. So on
       his iOS build, fixed top:0 resolves below the status area even though viewport-fit=cover is
       served, and safe-area padding cannot help because the bar never reaches y=0. Rather than a
       fourth theory about which viewport iOS is using, cap the bar with a paper slab that extends
       UPWARD and paints over whatever enters that strip, wherever the bar lands. Invisible when
       there is no gap; ends the ghosting when there is one. */
    .topbar::before {
        content: "";
        position: absolute;
        left: 0;
        right: 0;
        bottom: 100%;
        height: 140px;
        background: var(--paper);
    }
    .topbar .brand-word {
        font-size: var(--fs-lede);
    }
    .topbar .serial {
        font-family: var(--mono);
        font-size: var(--fs-micro-tight);
        letter-spacing: 0.2em;
        color: var(--faint);
    }
    .bottomnav {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 40;
        display: flex;
        justify-content: space-around;
        gap: 4px;
        padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
        /* Opaque + no blur, same iOS fix as .topbar above: blur on a fixed bar lags behind
           the finger while scrolling and content slides through it. 0.92 alpha over the page
           read as paper anyway, so nothing visible is lost. */
        background: var(--paper);
        transform: translateZ(0);
        border-top: 1px solid var(--line-soft);
    }
    .bottomnav a {
        flex: 1;
        text-align: center;
        text-decoration: none;
        font-family: var(--mono);
        font-size: var(--fs-meta);
        letter-spacing: 0.12em;
        text-transform: uppercase;
        color: var(--mute);
        padding: 10px 6px;
        border-radius: 999px;
    }
    .bottomnav a[aria-current] {
        color: var(--ink);
        background: #ffffff;
        box-shadow: var(--shadow-soft);
    }
    .main {
        /* Offset the fixed .topbar (~72px tall + status-bar safe area) so content starts below it. */
        padding: calc(92px + env(safe-area-inset-top)) 18px 48px;
    }
    .grid {
        margin-top: 28px;
        gap: 14px;
    }
    .span-3,
    .span-4,
    .span-5,
    .span-6,
    .span-7,
    .span-8 {
        grid-column: span 12;
    }
    .card {
        padding: 22px;
        border-radius: var(--r-tile);
    }
    .util-strip {
        margin: auto -22px -22px;
        padding: 14px 22px;
        border-radius: 0 0 var(--r-tile) var(--r-tile);
    }
    .score-wrap {
        gap: 22px;
    }
    .ring-box {
        width: 138px;
        height: 138px;
    }
    .ring-num {
        font-size: 44px;
    }
    .big-num {
        font-size: 56px;
    }
    .sys-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .prod-grid {
        grid-template-columns: 1fr;
    }
    .counts {
        flex-direction: column;
        gap: 14px;
    }
    .counts > div + div {
        border-left: 0;
        padding-left: 0;
        border-top: 1px solid var(--line-soft);
        padding-top: 14px;
    }
    .counts > div {
        flex-direction: row;
        align-items: baseline;
        justify-content: space-between;
    }
    .mrow {
        grid-template-columns: 1fr auto;
        grid-template-areas: "name val" "bar pill";
        row-gap: 9px;
    }
    .m-name {
        grid-area: name;
    }
    .m-val {
        grid-area: val;
        justify-self: end;
    }
    .mbar {
        grid-area: bar;
        width: 100%;
    }
    .mrow .pill,
    .mrow .m-status {
        grid-area: pill;
    }
    .steps {
        flex-wrap: wrap;
        gap: 18px 0;
    }
    .steps li {
        flex: 1 1 50%;
    }
    .page-title {
        margin-top: 10px;
    }
}

/* ---------- Nav mono indices ---------- */
.nav .n-i {
    font-family: var(--mono);
    font-size: var(--fs-label);
    letter-spacing: 0.12em;
    color: var(--faint);
    margin-left: auto;
    flex: none;
    font-weight: 400;
}
.nav a[aria-current] .n-i {
    color: var(--deep);
}

/* ---------- Goal bars ---------- */
.goal-track {
    position: relative;
    height: 7px;
    border-radius: 999px;
    background: rgba(25, 23, 19, 0.07);
    margin-top: 22px;
}
.goal-fill {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--gold-warm), var(--champagne));
    transform-origin: left;
    animation: growx 1s cubic-bezier(0.3, 0.7, 0.25, 1) 0.4s backwards;
}
.goal-tick {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 2px;
    height: 15px;
    border-radius: 2px;
    background: var(--ink);
}
.goal-axis {
    display: flex;
    justify-content: space-between;
    margin-top: 10px;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--faint);
}
.goal-now {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin-top: 14px;
}
.goal-now .num {
    font-family: var(--serif);
    font-weight: 300;
    font-size: 46px;
    line-height: 0.9;
    letter-spacing: -0.02em;
}
.goal-now .unit {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--faint);
}

/* Gold trend spark */
.spark {
    width: 66px;
    height: 26px;
    color: var(--champagne);
    flex: none;
}
.spark polyline {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.spark circle {
    fill: var(--deep);
}

/* ---------- Change rows ---------- */
.chg-row {
    display: grid;
    grid-template-columns: 1.4fr 1.2fr auto;
    gap: 18px;
    align-items: center;
    padding: 14px 0;
    border-top: 1px solid var(--line-soft);
}
.chg-row:first-child {
    border-top: 0;
}
.chg-vals {
    font-family: var(--mono);
    font-size: var(--fs-caption);
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    white-space: nowrap;
}
.chg-vals .from {
    color: var(--faint);
    font-weight: 400;
}
.chg-vals .arr {
    width: 13px;
    height: 13px;
    color: var(--champagne);
    flex: none;
}
.chg-vals em {
    font-style: normal;
    color: var(--faint);
    font-size: var(--fs-meta);
    margin-left: 2px;
}
.chg-row .pill {
    justify-self: end;
}

/* Serif close */
.serif-close {
    font-family: var(--serif);
    font-weight: 300;
    font-size: clamp(30px, 4.4vw, 50px);
    line-height: 1.02;
    letter-spacing: -0.02em;
    text-wrap: balance;
}

/* ---------- Stack check-off ---------- */
.stk-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 15px 0;
    border-top: 1px solid var(--line-soft);
}
.stk-row:first-of-type {
    border-top: 0;
}
.stk-box {
    appearance: none;
    -webkit-appearance: none;
    width: 24px;
    height: 24px;
    border: 1.5px solid var(--line-strong);
    border-radius: 8px;
    background: #ffffff;
    cursor: pointer;
    flex: none;
    position: relative;
    transition:
        background 0.2s ease,
        border-color 0.2s ease;
}
.stk-box:hover {
    border-color: var(--champagne);
}
.stk-box:checked {
    background: linear-gradient(135deg, #c7a24e 0%, #b8973f 48%, #7a5f22 100%);
    border-color: transparent;
}
.stk-box:checked::after {
    content: "";
    position: absolute;
    left: 6px;
    top: 7px;
    width: 10px;
    height: 5px;
    border-left: 2px solid #fbf7ef;
    border-bottom: 2px solid #fbf7ef;
    transform: rotate(-45deg);
}
.stk-box:focus-visible {
    outline: 2px solid var(--champagne);
    outline-offset: 2px;
}
.stk-body {
    flex: 1;
    min-width: 0;
}
.stk-name {
    font-size: var(--fs-body);
    font-weight: 600;
}
.stk-dose {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--mute);
    margin-top: 4px;
}
.stk-row:has(.stk-box:checked) .stk-name {
    color: var(--mute);
}
.stk-row:has(.stk-box:checked) .stk-state {
    color: var(--good);
}
.stk-state {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--faint);
}
.stk-group {
    margin-top: 24px;
}
.stk-group:first-of-type {
    margin-top: 6px;
}
.stk-group-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--line-soft);
}
.stk-group-head .eyebrow {
    color: var(--deep);
}
.stk-group-head::after {
    content: "";
    flex: 1;
}
.stk-count-num {
    font-family: var(--serif);
    font-weight: 300;
    font-size: 74px;
    line-height: 0.9;
    letter-spacing: -0.02em;
}
.stk-count-num .of {
    font-size: var(--fs-statfigure);
    color: var(--faint);
}

/* ---------- Notifications feed ---------- */
.ntf-rows {
    display: flex;
    flex-direction: column;
}
.ntf-row {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    padding: 18px 0;
    border-top: 1px solid var(--line-soft);
}
.ntf-row:first-child {
    border-top: 0;
}
.ntf-dot {
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: var(--gold);
    box-shadow: 0 0 0 3px rgba(254, 187, 0, 0.16);
    margin-top: 7px;
    flex: none;
}
.ntf-row.read .ntf-dot {
    background: transparent;
    border: 1px solid var(--line-strong);
    box-shadow: none;
}
.ntf-body {
    flex: 1;
    min-width: 0;
}
.ntf-title {
    font-size: var(--fs-body);
    font-weight: 600;
}
.ntf-row.read .ntf-title {
    font-weight: 400;
    color: var(--mute);
}
.ntf-sub {
    font-size: var(--fs-supporting);
    color: var(--mute);
    margin-top: 3px;
}
.ntf-time {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--faint);
    white-space: nowrap;
    margin-top: 4px;
}

/* ---------- Order route (courier signature) ---------- */
.route-svg {
    width: 100%;
    height: auto;
    color: rgba(230, 211, 160, 0.8);
}
.route-svg .path {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-dasharray: 5 7;
    animation: routedash 30s linear infinite;
}
@keyframes routedash {
    to {
        stroke-dashoffset: -240;
    }
}
.route-svg .stop {
    fill: var(--gold);
}
.route-svg .stop-ring {
    fill: none;
    stroke: rgba(254, 187, 0, 0.4);
}
.route-svg .rlab {
    font-family: var(--mono);
    font-size: 7.5px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    fill: rgba(230, 211, 160, 0.6);
}
.order-serial {
    font-family: var(--mono);
    font-size: var(--fs-subhead);
    font-weight: 500;
    letter-spacing: 0.3em;
    color: #efe0b8;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.55);
}

@media (prefers-reduced-motion: reduce) {
    .goal-fill {
        animation: none;
    }
    .route-svg .path {
        animation: none;
    }
}

@media (max-width: 820px) {
    .chg-row {
        grid-template-columns: 1fr auto;
    }
    .chg-row .chg-vals {
        grid-column: 1;
    }
    .chg-row .pill {
        grid-row: 1;
        grid-column: 2;
    }
    .stk-count-num {
        font-size: 56px;
    }
}

@media (max-width: 600px) {
    .sys-head {
        flex-wrap: wrap;
    }
    .sys-head .sys-sum {
        white-space: normal;
        flex-basis: 100%;
        padding-left: 36px;
        line-height: 1.8;
    }
}

@media (max-width: 430px) {
    body {
        font-size: var(--fs-body);
    }
    .sys-grid {
        grid-template-columns: 1fr 1fr;
        gap: 10px;
    }
    .sys {
        padding: 15px;
    }
    .score-wrap {
        flex-direction: column;
        align-items: flex-start;
    }
    .prow {
        flex-wrap: wrap;
    }
    .prow .btn {
        margin-left: 0;
    }
}

/* ---------- Account links (quiet row under the member chip) ---------- */
/* Matched to the mobile drawer's account list (a.nd-sub) on 2026-08-19, at Clement's request:
   a readable label over a quiet subline, one destination per row.
   It was mono micro-caps in a WRAPPING flex row, so on a narrow sidebar "MEMBERSHIP SETTINGS"
   landed on one line and read as a single heading rather than as two separate links. */
.acct-links {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* Sign out is a <button> because logout is a POST. Same selector as the anchors
   beside it so it cannot read as a different kind of control. */
.acct-links button {
    appearance: none;
    background: none;
    width: 100%;
    text-align: left;
    font: inherit;
    cursor: pointer;
}
.acct-links a,
.acct-links button {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
    font-family: inherit;
    font-size: var(--fs-body);
    font-weight: var(--fw-semibold);
    letter-spacing: normal;
    text-transform: none;
    color: var(--ink);
    text-decoration: none;
    padding: 10px 12px;
    margin: 0 -12px;
    border-radius: 10px;
}
.acct-links a small,
.acct-links button small {
    font-size: var(--fs-caption-tight);
    font-weight: var(--fw-regular);
    color: var(--faint);
    line-height: 1.35;
    letter-spacing: normal;
    text-transform: none;
}
/* The count sits beside the word, not under it, so the label still reads as one line. */
.acct-links .acct-line {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.acct-links a:hover,
.acct-links button:hover {
    color: var(--ink);
    background: rgba(0, 0, 0, 0.035);
}
.acct-links a[aria-current] {
    color: var(--ink);
    border-bottom: 1px solid var(--champagne);
}

/* ---------- Segmented control ---------- */
.seg {
    display: inline-flex;
    gap: 2px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    padding: 3px;
    background: rgba(255, 255, 255, 0.6);
}
.seg button {
    border: 0;
    background: transparent;
    border-radius: 999px;
    padding: 7px 16px;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mute);
    transition:
        background 0.2s ease,
        color 0.2s ease;
}
.seg button[aria-pressed="true"] {
    background: var(--ink);
    color: var(--paper);
}
.seg button:focus-visible {
    outline: 2px solid var(--champagne);
    outline-offset: 2px;
}

/* ---------- Switches ---------- */
.set-row {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 16px 0;
    border-top: 1px solid var(--line-soft);
}
.set-row:first-of-type {
    border-top: 0;
}
.set-body {
    flex: 1;
    min-width: 0;
}
.set-name {
    font-size: var(--fs-body);
    font-weight: 600;
}
/* Was 9px uppercase mono with 0.14em tracking, which is the least readable configuration available, and
   Settings uses this class for whole explanatory sentences: "THE BELL SHOWS WHAT IS WAITING ON YOU,
   UPDATED FROM YOUR OWN LAB STAGE AND SETUP. NOTHING IS SCHEDULED OR INVENTED." Mono is reserved for
   things read off an instrument (units, serials, dates, axes) per DESIGN.md's Mono Means Measured rule;
   this is prose telling a member what a control does, so it sets in the body face at a size a person can
   read. Sentence case comes from the markup already, the uppercase was purely the transform.
   Unrelated to contrast: --mute was passing at 9px and still passes at 12.5px. Size never was the
   contrast fix, since AA wants 4.5:1 for anything under 18.66px regardless. */
.set-sub {
    font-size: var(--fs-caption);
    line-height: 1.45;
    color: var(--mute);
    margin-top: 4px;
    max-width: 46ch;
}
.switch {
    position: relative;
    width: 46px;
    height: 27px;
    flex: none;
    border: 1.5px solid var(--line-strong);
    border-radius: 999px;
    background: rgba(25, 23, 19, 0.05);
    transition:
        background 0.25s ease,
        border-color 0.25s ease;
}
.switch::after {
    content: "";
    position: absolute;
    top: 2.5px;
    left: 3px;
    width: 19px;
    height: 19px;
    border-radius: 999px;
    background: #ffffff;
    box-shadow: 0 1px 3px rgba(25, 23, 19, 0.25);
    transition: transform 0.25s cubic-bezier(0.3, 0.7, 0.25, 1);
}
.switch[aria-pressed="true"] {
    background: linear-gradient(135deg, #c7a24e 0%, #b8973f 48%, #7a5f22 100%);
    border-color: transparent;
}
.switch[aria-pressed="true"]::after {
    transform: translateX(18px);
}
.switch:focus-visible {
    outline: 2px solid var(--champagne);
    outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
    .switch,
    .switch::after,
    .seg button {
        transition: none;
    }
}

/* ---------- Usage meters ---------- */
.use-meter {
    display: flex;
    gap: 6px;
    margin-top: 14px;
}
.use-meter span {
    flex: 1;
    height: 7px;
    border-radius: 999px;
    background: rgba(230, 211, 160, 0.16);
}
.use-meter span.used {
    background: linear-gradient(90deg, var(--gold-warm), var(--champagne));
}
.card .use-meter span {
    background: rgba(25, 23, 19, 0.08);
}
.card .use-meter span.used {
    background: linear-gradient(90deg, var(--gold-warm), var(--champagne));
}

/* ---------- Included list ---------- */
.inc-list {
    list-style: none;
}
.inc-list li {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 13px 0;
    border-top: 1px solid var(--line-soft);
    font-size: var(--fs-body);
}
.inc-list li:first-child {
    border-top: 0;
}
.inc-list svg {
    width: 17px;
    height: 17px;
    color: var(--deep);
    flex: none;
    margin-top: 3px;
}

/* ---------- Standings rows ---------- */
.rank-row {
    display: grid;
    grid-template-columns: 52px 1fr auto auto;
    gap: 16px;
    align-items: center;
    padding: 14px 16px;
    border-top: 1px solid var(--line-soft);
}
.rank-row:first-child {
    border-top: 0;
}
.rank-row .r-pos {
    font-family: var(--mono);
    font-size: var(--fs-caption-tight);
    font-weight: 500;
    color: var(--mute);
}
.rank-row .r-name {
    font-size: var(--fs-body);
    font-weight: 600;
}
.rank-row .r-score {
    font-family: var(--serif);
    font-weight: 300;
    font-size: 24px;
    line-height: 1;
}
.rank-row .r-move {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    justify-self: end;
    min-width: 64px;
}
.rank-row .r-move.up {
    color: var(--good);
}
.rank-row .r-move.down {
    color: var(--bad);
}
.rank-row .r-move.flat {
    color: var(--faint);
}
.rank-row.you {
    margin: 0 -16px;
    padding-left: 32px;
    padding-right: 32px;
    background: rgba(184, 151, 63, 0.08);
    border-top: 1px solid rgba(184, 151, 63, 0.25);
    border-bottom: 1px solid rgba(184, 151, 63, 0.25);
}
.rank-row.you + .rank-row {
    border-top: 0;
}
.rank-row .you-tag {
    font-family: var(--mono);
    font-size: var(--fs-nano);
    letter-spacing: 0.2em;
    color: var(--deep);
    border: 1px solid rgba(184, 151, 63, 0.4);
    border-radius: 999px;
    padding: 2px 8px;
    margin-left: 10px;
    vertical-align: 2px;
}

/* ---------- Progress stat cards ---------- */
.stat-was {
    font-family: var(--mono);
    font-size: var(--fs-supporting);
    color: var(--faint);
    text-decoration: line-through;
    text-decoration-color: rgba(179, 38, 30, 0.5);
}
.stat-now {
    font-family: var(--serif);
    font-weight: 300;
    font-size: 58px;
    line-height: 0.9;
    letter-spacing: -0.02em;
    margin-top: 10px;
}
.stat-now .unit {
    font-size: 18px;
    color: var(--faint);
    letter-spacing: 0;
    margin-left: 5px;
}
.stat-delta {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 14px;
    font-family: var(--mono);
    font-size: var(--fs-meta);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    font-weight: 500;
}
.stat-delta.good {
    color: var(--good);
}
.stat-delta svg {
    width: 12px;
    height: 12px;
}

/* ---------- Learn: filters + articles ---------- */
.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 26px;
}
.chips button {
    border: 1px solid var(--line-strong);
    background: transparent;
    border-radius: 999px;
    padding: 8px 15px;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--mute);
    transition:
        background 0.2s ease,
        color 0.2s ease,
        border-color 0.2s ease;
}
.chips button:hover {
    color: var(--ink);
    border-color: var(--ink);
}
.chips button[aria-pressed="true"] {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--paper);
}
.art-row {
    display: flex;
    align-items: baseline;
    gap: 20px;
    padding: 19px 0;
    border-top: 1px solid var(--line-soft);
    text-decoration: none;
}
.art-row:first-child {
    border-top: 0;
}
.art-row.hidden {
    display: none;
}
.art-idx {
    font-family: var(--mono);
    font-size: var(--fs-meta);
    color: var(--faint);
    width: 24px;
    flex: none;
}
.art-body {
    flex: 1;
    min-width: 0;
}
.art-title {
    font-family: var(--serif);
    font-weight: 400;
    font-size: 19px;
    letter-spacing: -0.01em;
    line-height: 1.2;
}
.art-row:hover .art-title {
    color: var(--deep);
}
.art-sub {
    font-size: var(--fs-supporting);
    color: var(--mute);
    margin-top: 5px;
    max-width: 58ch;
}
.art-meta {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--faint);
    white-space: nowrap;
}

/* ---------- Chat ---------- */
.chat {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.msg-meta {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--faint);
    margin-top: 16px;
    margin-bottom: 4px;
}
.msg {
    max-width: 58ch;
    padding: 14px 18px;
    border-radius: 18px;
    font-size: var(--fs-body);
    line-height: 1.55;
}
.msg.them {
    align-self: flex-start;
    background: #ffffff;
    border: 1px solid var(--line);
    border-top-left-radius: 6px;
    box-shadow: var(--shadow-soft);
}
.msg.you {
    align-self: flex-end;
    background: var(--cream);
    border: 1px solid rgba(184, 151, 63, 0.22);
    border-top-right-radius: 6px;
}
.msg-meta.you {
    align-self: flex-end;
}
.composer {
    display: flex;
    gap: 10px;
    margin-top: 22px;
    padding-top: 20px;
    border-top: 1px solid var(--line-soft);
}
.composer input {
    flex: 1;
    min-width: 0;
    font: inherit;
    color: var(--ink);
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    padding: 12px 20px;
    background: #ffffff;
}
.composer input::placeholder {
    color: var(--faint);
}
.composer input:focus-visible {
    outline: 2px solid var(--champagne);
    outline-offset: 1px;
}
.person {
    display: flex;
    align-items: center;
    gap: 16px;
}
.avatar {
    width: 52px;
    height: 52px;
    border-radius: 999px;
    flex: none;
    display: grid;
    place-items: center;
    font-family: var(--serif);
    font-size: 19px;
    color: var(--gold-light);
    background: linear-gradient(140deg, var(--dark-a), var(--dark-b));
    border: 1px solid rgba(230, 211, 160, 0.25);
}
.online {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--good);
}
.online i {
    width: 6px;
    height: 6px;
    border-radius: 999px;
    background: var(--good);
}

/* ---------- Records ---------- */
.doc-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 15px 0;
    border-top: 1px solid var(--line-soft);
}
.doc-row:first-child {
    border-top: 0;
}
.doc-body {
    flex: 1;
    min-width: 0;
}
.doc-name {
    font-size: var(--fs-body);
    font-weight: 600;
}
.doc-sub {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mute);
    margin-top: 4px;
}
.tag {
    font-family: var(--mono);
    font-size: var(--fs-nano);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--mute);
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    padding: 3px 9px;
    white-space: nowrap;
}
.upload-box {
    border: 1.5px dashed var(--line-strong);
    border-radius: var(--r-tile);
    padding: 30px 24px;
    text-align: center;
    color: var(--mute);
    transition:
        border-color 0.2s ease,
        background 0.2s ease;
    cursor: pointer;
    background: transparent;
    width: 100%;
}
.upload-box:hover {
    border-color: var(--champagne);
    background: rgba(184, 151, 63, 0.04);
}
.upload-box svg {
    width: 24px;
    height: 24px;
    margin: 0 auto 10px;
    color: var(--faint);
    display: block;
}

/* ---------- Setup stepper ---------- */
.setup-steps {
    list-style: none;
    display: flex;
    gap: 4px;
    margin-top: 34px;
    flex-wrap: wrap;
}
.setup-steps button {
    border: 1px solid transparent;
    background: transparent;
    border-radius: 999px;
    padding: 9px 16px;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mute);
}
.setup-steps button:hover {
    color: var(--ink);
}
.setup-steps button[aria-current="step"] {
    background: #ffffff;
    border-color: var(--line-soft);
    box-shadow: var(--shadow-soft);
    color: var(--ink);
}
.setup-steps .st-n {
    width: 20px;
    height: 20px;
    border-radius: 999px;
    border: 1px solid var(--line-strong);
    display: grid;
    place-items: center;
    font-size: var(--fs-micro-tight);
    flex: none;
}
.setup-steps button[aria-current="step"] .st-n {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--paper);
}
.setup-steps .done .st-n {
    background: linear-gradient(135deg, #c7a24e, #7a5f22);
    border-color: transparent;
    color: #fbf7ef;
}
.panel {
    display: none;
}
.panel.active {
    display: block;
}
.field {
    padding: 14px 0;
    border-top: 1px solid var(--line-soft);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 18px;
}
.field:first-of-type {
    border-top: 0;
}
.field .f-lab {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--faint);
}
.field .f-val {
    font-size: var(--fs-body);
    font-weight: 500;
    text-align: right;
}
.field .f-lock {
    font-family: var(--mono);
    font-size: var(--fs-nano);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--faint);
    margin-left: 10px;
}
.f-input {
    font: inherit;
    color: var(--ink);
    border: 1px solid var(--line-strong);
    border-radius: 14px;
    padding: 11px 16px;
    background: #ffffff;
    width: 100%;
}
.f-input:focus-visible {
    outline: 2px solid var(--champagne);
    outline-offset: 1px;
}
.opt-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}
.opt-chips button {
    border: 1px solid var(--line-strong);
    background: #ffffff;
    border-radius: 999px;
    padding: 9px 16px;
    font-size: var(--fs-supporting);
    color: var(--mute);
    transition:
        background 0.2s ease,
        color 0.2s ease,
        border-color 0.2s ease;
}
.opt-chips button[aria-pressed="true"] {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--paper);
}
.opt-chips button:focus-visible {
    outline: 2px solid var(--champagne);
    outline-offset: 2px;
}
.addon {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 17px 0;
    border-top: 1px solid var(--line-soft);
}
.addon:first-child {
    border-top: 0;
}
.addon-body {
    flex: 1;
    min-width: 0;
}
.addon .price {
    font-size: var(--fs-subhead);
    white-space: nowrap;
}
.addon .btn {
    padding: 9px 18px;
    font-size: var(--fs-caption);
}
.addon.added .btn.ghost {
    background: var(--ink);
    color: var(--paper);
    border-color: var(--ink);
}
.total-bar {
    position: sticky;
    bottom: 18px;
    margin-top: 26px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    background: linear-gradient(140deg, var(--dark-a), var(--dark-b));
    color: var(--gold-light);
    border: 1px solid rgba(230, 211, 160, 0.2);
    border-radius: 999px;
    padding: 14px 14px 14px 26px;
    box-shadow: 0 14px 34px rgba(32, 19, 8, 0.3);
}
.total-bar .t-lab {
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: rgba(230, 211, 160, 0.6);
}
.total-bar .t-num {
    font-family: var(--serif);
    font-weight: 300;
    font-size: var(--fs-statfigure);
    color: #efe0b8;
}
.site {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 17px 0;
    border-top: 1px solid var(--line-soft);
    width: 100%;
    background: transparent;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
    text-align: left;
}
.site:first-of-type {
    border-top: 0;
}
.site .s-radio {
    width: 20px;
    height: 20px;
    border-radius: 999px;
    border: 1.5px solid var(--line-strong);
    flex: none;
    position: relative;
}
.site[aria-pressed="true"] .s-radio {
    border-color: var(--deep);
}
.site[aria-pressed="true"] .s-radio::after {
    content: "";
    position: absolute;
    inset: 4px;
    border-radius: 999px;
    background: linear-gradient(135deg, #c7a24e, #7a5f22);
}
.slot-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 16px;
}
.slot-chips button {
    border: 1px solid var(--line-strong);
    background: #ffffff;
    border-radius: 999px;
    padding: 9px 15px;
    font-family: var(--mono);
    font-size: var(--fs-label);
    letter-spacing: 0.1em;
    color: var(--mute);
}
.slot-chips button[aria-pressed="true"] {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--paper);
}
.panel-foot {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    margin-top: 30px;
    padding-top: 22px;
    border-top: 1px solid var(--line-soft);
    flex-wrap: wrap;
}

@media (max-width: 820px) {
    .rank-row {
        grid-template-columns: 40px 1fr auto;
    }
    .rank-row .r-move {
        grid-column: 3;
        grid-row: 2;
        justify-self: end;
        min-width: 0;
    }
    .rank-row .r-score {
        grid-row: 1 / span 2;
        align-self: center;
    }
    .art-row {
        flex-wrap: wrap;
        gap: 10px 20px;
    }
    .art-meta {
        flex-basis: 100%;
        padding-left: 44px;
    }
    .stat-now {
        font-size: 46px;
    }
    .total-bar {
        bottom: 96px;
    }
    .field {
        flex-direction: column;
        gap: 6px;
    }
    .field .f-val {
        text-align: left;
    }
}

/* ---------- Product media band ---------- */
.prod-media {
    height: 150px;
    border-radius: 16px;
    background: var(--cream);
    display: grid;
    place-items: center;
    margin-bottom: 8px;
    overflow: hidden;
}
.prod-media img {
    max-height: 122px;
    width: auto;
    filter: drop-shadow(0 12px 18px rgba(32, 19, 8, 0.16));
}
.prod-media.stub svg {
    width: 32px;
    height: 32px;
    color: var(--gold-warm);
    opacity: 0.75;
}

/* ---------- Mobile "More" sheet ---------- */
.bn-more {
    flex: 1;
    border: 0;
    background: transparent;
    cursor: pointer;
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--mute);
    padding: 10px 6px;
    border-radius: 999px;
}
.bn-more[aria-expanded="true"],
.bn-more.here {
    color: var(--ink);
    background: #ffffff;
    box-shadow: var(--shadow-soft);
}
.more-scrim {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(25, 23, 19, 0.35);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
}
.more-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 61;
    background: var(--paper);
    border-top: 1px solid var(--line-soft);
    border-radius: 20px 20px 0 0;
    padding: 20px 22px calc(18px + env(safe-area-inset-bottom));
    transform: translateY(105%);
    transition: transform 0.32s cubic-bezier(0.22, 0.61, 0.25, 1);
    box-shadow: 0 -18px 44px rgba(32, 19, 8, 0.18);
}
body.more-open .more-scrim {
    opacity: 1;
    pointer-events: auto;
}
body.more-open .more-sheet {
    transform: none;
}
.more-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
}
.more-head .eyebrow {
    color: var(--mute);
}
.more-close {
    background: transparent;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--mute);
    padding: 9px 14px;
}
.more-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px;
}
.more-grid a {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 48px;
    padding: 10px 12px;
    border-radius: 14px;
    text-decoration: none;
    font-size: var(--fs-body);
    color: var(--mute);
}
.more-grid a svg {
    width: 18px;
    height: 18px;
    flex: none;
    color: var(--faint);
}
.more-grid a[aria-current] {
    color: var(--ink);
    font-weight: 600;
    background: #ffffff;
    box-shadow: var(--shadow-soft);
}
.more-grid a[aria-current] svg {
    color: var(--deep);
}
.more-foot {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--line-soft);
    text-align: center;
}
@media (min-width: 821px) {
    .more-scrim,
    .more-sheet {
        display: none;
    }
}
@media (prefers-reduced-motion: reduce) {
    .more-scrim,
    .more-sheet {
        transition: none;
    }
}

/* ---------- Pending states ---------- */
.msg.thinking {
    display: flex;
    flex-direction: column;
    gap: 9px;
    min-width: 170px;
}
.btn[disabled] {
    opacity: 0.55;
    cursor: default;
    pointer-events: none;
    box-shadow: none;
}

/* Keyboard focus on the portal's control classes (2026-08-04 Phase 4): one champagne ring,
   everywhere a finger or a Tab can land, matching the wizard's rule from this morning. */
.tlink:focus-visible,
.nav a:focus-visible,
.pill:focus-visible,
.chips a:focus-visible,
.chips button:focus-visible {
    outline: 2px solid var(--champagne);
    outline-offset: 2px;
    border-radius: 8px;
}
@media (prefers-reduced-motion: reduce) {
    .btn,
    .btn:active {
        transition: none;
        transform: none;
    }
}

/* ===== Labs - body-system overview strip (P2) =====
   Function's glanceable "Data" screen: one row per body system with a split
   gold/amber/red bar sized by that system's marker counts, jumps to its section
   anchor. Fully token-driven so it themes for BOTH light and dark (club.css only
   remaps the tokens). Fill draws in on load, staggered. Reduced-motion guarded. */
.labs-overview {
    margin-bottom: 30px;
    padding: 20px 24px 8px;
}
.lo-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 4px;
}
.lo-legend {
    display: flex;
    gap: 15px;
    font-family: var(--mono);
    font-size: var(--fs-micro);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--faint);
}
.lo-legend i {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-style: normal;
}
.lo-legend b {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    display: inline-block;
}
.lo-legend .d-opt {
    background: var(--good);
}
.lo-legend .d-watch {
    background: var(--warn);
}
.lo-legend .d-out {
    background: var(--bad);
}

.lo-list {
    display: flex;
    flex-direction: column;
}
.lo-row {
    position: relative;
    display: grid;
    grid-template-columns: 34px 1fr auto;
    grid-template-areas: "ico name count" "ico bar bar";
    align-items: center;
    column-gap: 14px;
    row-gap: 10px;
    padding: 15px 4px;
    text-decoration: none;
    border-top: 1px solid var(--line-soft);
    transition: background 0.18s ease;
}
.lo-row:first-child {
    border-top: 0;
}
.lo-row:hover {
    background: var(--line-soft);
}
.lo-ico {
    grid-area: ico;
    width: 34px;
    height: 34px;
    align-self: center;
    display: grid;
    place-items: center;
    border-radius: 10px;
    background: var(--cream);
    border: 1px solid var(--line);
    color: var(--deep);
}
.lo-ico svg {
    width: 19px;
    height: 19px;
}
.lo-name {
    grid-area: name;
    font-family: var(--serif);
    font-weight: 400;
    font-size: 17px;
    letter-spacing: -0.01em;
    color: var(--ink);
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.lo-flag {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--bad);
    background: var(--bad-wash);
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 3px 8px;
}
.lo-count {
    grid-area: count;
    font-family: var(--mono);
    font-size: var(--fs-caption-tight);
    color: var(--faint);
    letter-spacing: 0.02em;
    white-space: nowrap;
}
.lo-count b {
    font-family: var(--serif);
    font-size: 18px;
    font-weight: 400;
    color: var(--ink);
}
.has-out .lo-count b {
    color: var(--bad);
}
.lo-count::after {
    content: "\203A";
    margin-left: 10px;
    color: var(--faint);
    font-family: var(--sans);
    font-size: var(--fs-lede);
    opacity: 0.5;
    display: inline-block;
    transition:
        opacity 0.18s ease,
        transform 0.18s ease,
        color 0.18s ease;
}
.lo-row:hover .lo-count::after {
    opacity: 1;
    transform: translateX(2px);
    color: var(--deep);
}

.lo-bar {
    grid-area: bar;
    height: 8px;
    border-radius: 999px;
    background: var(--line);
    overflow: hidden;
}
.lo-fill {
    display: flex;
    height: 100%;
    gap: 2px;
    transform-origin: left;
    animation: loFill 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both;
    animation-delay: calc(var(--i, 0) * 70ms + 0.15s);
}
.lo-fill i {
    display: block;
    height: 100%;
}
.lo-fill i:first-child {
    border-radius: 999px 0 0 999px;
}
.lo-fill i:last-child {
    border-radius: 0 999px 999px 0;
}
.lo-fill i:only-child {
    border-radius: 999px;
}
.lo-fill .opt {
    background: linear-gradient(90deg, var(--gold-warm), var(--gold-light));
}
.lo-fill .watch {
    background: var(--warn);
}
.lo-fill .out {
    background: var(--bad);
}
@keyframes loFill {
    from {
        transform: scaleX(0);
    }
    to {
        transform: scaleX(1);
    }
}

@media (max-width: 560px) {
    .labs-overview {
        padding: 16px 16px 4px;
    }
    .lo-name {
        font-size: 15.5px;
    }
    .lo-legend {
        display: none;
    }
}
@media (prefers-reduced-motion: reduce) {
    .lo-fill {
        animation: none;
    }
}

/* ===== Appearance toggle (Auto / Light / Dark) =====
   Token-driven pill; the active segment is marked via the data-theme-pref
   attribute the theme script stamps on <html>, so no JS is needed to paint it. */
.ot-theme-seg {
    display: flex;
    gap: 2px;
    margin-top: 13px;
    padding: 3px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--cream);
}
.ot-theme-seg button {
    flex: 1;
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--faint);
    background: none;
    border: 0;
    border-radius: 999px;
    padding: 6px 4px;
    cursor: pointer;
    transition:
        color 0.15s ease,
        background 0.15s ease;
}
.ot-theme-seg button:hover {
    color: var(--ink);
}
html[data-theme-pref="auto"] .ot-theme-seg [data-pref="auto"],
html[data-theme-pref="light"] .ot-theme-seg [data-pref="light"],
html[data-theme-pref="dark"] .ot-theme-seg [data-pref="dark"] {
    background: var(--ink);
    color: var(--paper);
}

/* ===== Labs - collapsible body-system sections (Jacob 07-23) =====
   Each system is a native <details>: the header line stays, the marker rows
   collapse into a tap-to-expand dropdown so the page isn't one long scroll.
   Token-driven (both themes); reduced-motion guarded. */
.sys-fold > summary.sys-head {
    cursor: pointer;
    list-style: none;
    margin: 0;
    user-select: none;
}
.sys-fold > summary.sys-head::-webkit-details-marker {
    display: none;
}
.sys-fold > summary.sys-head::marker {
    content: "";
}
/* suppress the generic details "+"/"−" marker (od.css line ~1379) - we use the chevron */
.sys-fold > summary.sys-head::after {
    content: none;
}
.sys-head .sys-sum {
    margin-left: auto;
}
.sys-head .sys-chev {
    width: 20px;
    height: 20px;
    flex: none;
    color: var(--faint);
    transition:
        transform 0.25s ease,
        color 0.2s ease;
}
.sys-fold > summary.sys-head:hover .sys-chev {
    color: var(--deep);
}
.sys-fold[open] > summary.sys-head .sys-chev {
    transform: rotate(180deg);
    color: var(--deep);
}
.sys-fold[open] > summary.sys-head {
    margin-bottom: 18px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--line);
}
.sys-fold[open] > .mrows {
    animation: sysOpen 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
}
@keyframes sysOpen {
    from {
        opacity: 0;
        transform: translateY(-6px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}
@media (prefers-reduced-motion: reduce) {
    .sys-head .sys-chev {
        transition: none;
    }
    .sys-fold[open] > .mrows {
        animation: none;
    }
}

/* Shop "Member pricing on every order" band: 2-up on desktop, stacked on phones
   (the grid was previously an inline style that never collapsed and crushed the
   copy at 390px). */
.member-pricing-band {
    display: grid;
    grid-template-columns: 1.2fr 1fr;
}
@media (max-width: 820px) {
    .member-pricing-band {
        grid-template-columns: 1fr;
    }
}

/* ---------------------------------------------------------------------------
   Journey pills. The member's position in the sequence, used by any surface
   that has to explain a gate: Perks, Peptides, and anything gated later.
   Defined here rather than in a page style block because it was page-local in
   shop.blade.php, so the Peptides page rendered "Join Intake Blood draw" as
   bare text with no styling at all (2026-08-24). One definition, every surface.
   --------------------------------------------------------------------------- */
.gate-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.gate-pill {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.42rem 0.72rem;
    border-radius: 999px;
    border: 1px solid var(--line-soft);
    color: var(--faint);
    white-space: nowrap;
}
/* Done. Quiet green, because a completed step is reassurance, not an achievement. */
.gate-pill.is-done {
    background: rgba(28, 122, 78, 0.1);
    border-color: rgba(28, 122, 78, 0.3);
    color: var(--good, #1c7a4e);
}
/* Where he is now. The only gold in the row, so the eye lands on the next action. */
.gate-pill.is-now {
    background: linear-gradient(115deg, rgba(199, 162, 78, 0.15), rgba(199, 162, 78, 0.03));
    border-color: var(--champagne, #c7a24e);
    color: var(--deep, #7a5f22);
    font-weight: var(--fw-bold);
}

/* ============================================================================
   Mitochondria (MeScreen) on My Labs.

   Token-only on purpose: club.css remaps the tokens at :root, so this whole
   component re-themes for free and there is nothing here to keep in sync. No
   literal colour appears below. A literal rgba(255,255,255,x) is a light-mode
   assumption wearing a transparency and it composites to an accidental grey on
   the dark ground; that bug put copper at 1.30:1 on My Membership on 08-03.

   The off-state of a band segment is a color-mix of its own semantic token
   rather than a new value, the same move .card--lead makes with --champagne.
   ========================================================================= */

/* The reading: a cream well, not a nested card. Cards do not nest in this
   system, and a recessed surface is the sanctioned way to inset content. */
.mito-read {
    display: grid;
    grid-template-columns: 132px 1fr;
    gap: 26px;
    align-items: start;
    background: var(--cream);
    border: 1px solid var(--line-soft);
    border-radius: 20px;
    padding: 22px 24px;
    margin: 4px 0 6px;
}
.mito-read__fig {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* A rank figure, deliberately at stat scale and not the 88px hero moment: this
   sits inside a fold among eight sibling folds, so it is not the page's
   subject and must not out-shout the page title. */
.mito-score {
    /* var(--serif) is this codebase's heading face and it resolves to Helvetica
       Neue, not Fraunces: the serif pivot was walked back on 08-13 and DESIGN.md
       still describes the old world. Matching .sec-title is what keeps this
       figure consistent with every other heading a member sees on this page. */
    font-family: var(--serif);
    font-size: var(--fs-statfigure);
    font-weight: 400;
    line-height: 1;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    margin: 2px 0 0;
}
.mito-score__unit {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--faint);
    margin: 0;
}
.mito-profile {
    font-family: var(--serif);
    font-size: var(--fs-subhead);
    font-weight: 400;
    line-height: 1.15;
    letter-spacing: -0.01em;
    color: var(--ink);
    margin: 0;
}
.mito-profile__read {
    font-size: var(--fs-supporting);
    line-height: 1.5;
    color: var(--mute);
    margin: 6px 0 0;
}

/* MeScreen's 17 profiles as one strip, worst on the left. The member's own step
   is the only filled one, so position reads before any label does. */
.mito-ladder {
    display: flex;
    gap: 2px;
    margin: 14px 0 0;
}
.mito-ladder i {
    flex: 1;
    height: 5px;
    border-radius: 999px;
    transition: none;
}
.mito-ladder i.t-good {
    background: color-mix(in srgb, var(--good) 20%, transparent);
}
.mito-ladder i.t-warn {
    background: color-mix(in srgb, var(--warn) 20%, transparent);
}
.mito-ladder i.t-bad {
    background: color-mix(in srgb, var(--bad) 20%, transparent);
}
.mito-ladder i.is-on {
    height: 11px;
    margin-top: -3px;
    border-radius: 999px;
}
.mito-ladder i.t-good.is-on {
    background: var(--good);
}
.mito-ladder i.t-warn.is-on {
    background: var(--warn);
}
.mito-ladder i.t-bad.is-on {
    background: var(--bad);
}
.mito-ladder__key {
    display: flex;
    justify-content: space-between;
    gap: 14px;
    margin: 9px 0 0;
}
.mito-ladder__key span {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--faint);
}

/* The profile's own explanation. Reading text, so it sits at body size and takes the
   60ch measure the house rule already puts on any <p> inside a <details>. */
.mito-summary {
    font-size: var(--fs-body);
    line-height: 1.6;
    color: var(--mute);
    margin: 16px 0 0;
}
.mito-summary + .mito-summary {
    margin-top: 10px;
}

/* One of the four measurement areas. */
.mito-group {
    margin-top: 22px;
}
/* Measured: the group name is 14.5px/500 and a metric name is 14.5px/400, which is
   too small a step to find four groups by while scanning. Type size cannot fix it
   without colliding with .sec-title, so separation goes where this system always
   puts it: a hairline. Shadow is warmth, hairlines are structure. */
.mito-group + .mito-group {
    margin-top: 26px;
    padding-top: 22px;
    border-top: 1px solid var(--line-soft);
}
.mito-group__head {
    display: flex;
    align-items: center;
    gap: 12px;
}
.mito-group__name {
    flex: 1;
    font-size: var(--fs-body);
    font-weight: 500;
    color: var(--ink);
    margin: 0;
}
.mito-group__blurb {
    font-size: var(--fs-supporting);
    line-height: 1.5;
    color: var(--mute);
    margin: 5px 0 2px;
    max-width: 62ch;
}
.mito-what {
    display: block;
    font-size: var(--fs-caption-tight);
    line-height: 1.4;
    color: var(--faint);
    margin-top: 2px;
}

/* The band strip. .mbar supplies the grid placement and the mobile reflow;
   .bandbar replaces its single track with one segment per named band, drawn in
   MeScreen's own order. That order is NOT always worst to best: baseline
   respiration is optimal in the MIDDLE and bad at both ends, and oxidative
   stress runs best-first. Forcing a single direction would misstate three of
   the nine measures, so each segment carries its own tone and the member's
   position is the segment they sit in, never a value mapped onto a scale. */
.bandbar {
    background: none;
    display: flex;
    align-items: center;
    gap: 3px;
    height: 10px;
}
.bandbar i {
    flex: 1;
    height: 5px;
    border-radius: 999px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.bandbar i.t-good {
    background: color-mix(in srgb, var(--good) 20%, transparent);
}
.bandbar i.t-warn {
    background: color-mix(in srgb, var(--warn) 20%, transparent);
}
.bandbar i.t-bad {
    background: color-mix(in srgb, var(--bad) 20%, transparent);
}
.bandbar i.is-on {
    height: 10px;
}
.bandbar i.t-good.is-on {
    background: var(--good);
}
.bandbar i.t-warn.is-on {
    background: var(--warn);
}
.bandbar i.t-bad.is-on {
    background: var(--bad);
}
/* "You are here", punched out of the filled segment. --paper flips with the
   theme, so this stays a hole rather than becoming a light dot on dark. */
.bandbar i.is-on b {
    width: 5px;
    height: 5px;
    border-radius: 999px;
    background: var(--paper);
}

/* A mito status word runs longer than a blood-marker pill ("Severe stress",
   "Disrupted"), and the shared 108px pill column clips it. The value column is
   also narrower here than on a blood row: those carry a unit beside the figure
   and these do not, so the same width left the number stranded 146px from its
   own bar.
   MUST stay inside a min-width query. `.mito .mrow` is two classes and the
   mobile reflow rule is one, and a media query adds no specificity, so an
   unscoped version of this wins at 390px and the four-column grid overflows. */
@media (min-width: 821px) {
    .mito .mrow {
        grid-template-columns: 1.5fr 0.45fr 1.45fr minmax(108px, auto);
    }
    /* Nine figures in a column scan as a column. Tabular so they line up. */
    .mito .m-val {
        text-align: right;
        font-variant-numeric: tabular-nums;
    }
}

.mito-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 22px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--line-soft);
}
.mito-meta span {
    font-family: var(--mono);
    font-size: var(--fs-micro-tight);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--faint);
}

/* Empty state as a next step, in the body face, one step down from the fact it
   replaces. The button goes to a row that exists. */
.mito-empty {
    padding: 6px 0 2px;
    max-width: 62ch;
}
.mito-empty__lede {
    font-size: var(--fs-lede);
    line-height: 1.6;
    color: var(--ink);
    margin: 0;
}
.mito-empty__body {
    font-size: var(--fs-body);
    line-height: 1.6;
    color: var(--mute);
    margin: 8px 0 16px;
}

/* Research use only, not FDA reviewed. MeScreen prints this three times in
   their own report. It is a claim we inherit by rendering their data, so it is
   set in --mute at caption size and is readable, not buried at --faint. */
.mito-disclaimer {
    font-size: var(--fs-caption-tight);
    line-height: 1.5;
    color: var(--mute);
    margin: 14px 0 0;
}
.mito-empty + .mito-disclaimer {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--line-soft);
}

@media (max-width: 820px) {
    .mito-read {
        grid-template-columns: 1fr;
        gap: 16px;
        padding: 20px;
    }
    .mito-ladder__key {
        flex-direction: column;
        gap: 3px;
    }
}
@media (max-width: 640px) {
    /* The profile name is a long mono string and would push the fold title.
       .sys-sum already carries a short summary at this width. */
    .mito > summary > .pill {
        display: none;
    }
}
