/* ==========================================================================
   KnowTheSpore base.css: the foundation layer of the revamp.

   Load order (templates/layout/header.php): tokens.css, fonts.css, base.css,
   blocks.css, then optional page sheets. Every value here comes from a
   tokens.css custom property. No raw hex, px font size, font weight, z-index
   or breakpoint number appears outside tokens.css, except the breakpoint
   numbers in the single marked section at the end of this file.

   Class names follow docs/DESIGN_SPEC.md "Implementation contract".
   Article-body blocks (Template::articleBlocks) are styled by blocks.css.

   Internal custom properties start with "--_" and are private to this file:
     --_bg       band background          --_ink      body text color
     --_heading  heading color            --_label    kicker color
     --_link     link color               --_muted    secondary text color
     --_focus    focus ring color         --_pat      pattern ink
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Reset
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-padding-top: calc(var(--header-h) + var(--space-4));
}

body {
    --_bg: var(--c-bg);
    --_ink: var(--c-ink);
    --_heading: var(--c-ink-heading);
    --_label: var(--c-label-on-light);
    --_link: var(--c-link);
    --_muted: var(--c-ink-muted);
    --_focus: var(--c-focus);
    margin: 0;
    min-height: 100vh;
    background: var(--c-bg);
    color: var(--_ink);
    font-family: var(--role-body-family);
    font-weight: var(--role-body-weight);
    font-size: var(--fs-body);
    line-height: var(--lh-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

img, picture, svg, video, canvas { display: block; max-width: 100%; height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
table { border-collapse: collapse; }
hr { border: 0; border-top: var(--border-hairline) solid var(--c-line); margin: var(--space-6) 0; }

h1, h2, h3, h4, h5, h6 {
    margin: 0 0 var(--space-3);
    color: var(--_heading);
    font-family: var(--role-heading-family);
    font-weight: var(--role-heading-weight);
    line-height: var(--lh-heading);
    letter-spacing: var(--tr-heading);
    text-wrap: balance;
    overflow-wrap: break-word;
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4, h5, h6 {
    font-family: var(--role-title-family);
    font-weight: var(--role-title-weight);
    font-size: var(--fs-title);
    line-height: var(--lh-title);
    letter-spacing: 0;
}

p, ul, ol, dl, figure, blockquote { margin: 0 0 var(--space-4); }
p { text-wrap: pretty; }
:is(p, ul, ol, dl, figure, blockquote):last-child { margin-bottom: 0; }
strong, b { font-family: var(--role-strong-family); font-weight: var(--role-strong-weight); }

a { color: var(--_link); text-decoration-thickness: var(--border-hairline); text-underline-offset: 0.18em; }
a:hover { text-decoration-thickness: 2px; }

::selection { background: var(--c-band-gold); color: var(--c-ink); }


/* --------------------------------------------------------------------------
   2. Focus and skip link
   -------------------------------------------------------------------------- */
:focus-visible {
    outline: 3px solid var(--_focus);
    outline-offset: 2px;
}

.skip-link {
    position: absolute;
    top: var(--space-2);
    left: var(--space-2);
    z-index: var(--z-toast);
    padding: var(--space-2) var(--space-4);
    background: var(--c-accent);
    color: var(--c-bg);
    font-weight: var(--role-button-weight);
    border-radius: var(--radius-sm);
    transform: translateY(-200%);
}
.skip-link:focus { transform: none; }

.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}


/* --------------------------------------------------------------------------
   3. Type roles
   -------------------------------------------------------------------------- */
.t-display {
    font-family: var(--role-display-family);
    font-weight: var(--role-display-weight);
    font-size: var(--fs-display);
    line-height: var(--lh-display);
    letter-spacing: var(--tr-display);
    color: var(--_heading);
    text-wrap: balance;
}
.t-h1, .t-h2, .t-h3 {
    font-family: var(--role-heading-family);
    font-weight: var(--role-heading-weight);
    line-height: var(--lh-heading);
    letter-spacing: var(--tr-heading);
    color: var(--_heading);
    text-wrap: balance;
}
.t-h1 { font-size: var(--fs-h1); }
.t-h2 { font-size: var(--fs-h2); }
.t-h3 { font-size: var(--fs-h3); }

/* Lead paragraphs (also .title-band__lead and .profile-title__lead, which carry
   .t-lead): a reading measure and open leading so a two-line lead stays easy. */
.t-lead {
    max-width: var(--measure-lead);
    font-size: var(--fs-lead);
    line-height: var(--lh-lead);
    color: var(--_ink);
    text-wrap: pretty;
}

.t-label {
    display: inline-block;
    margin: 0 0 var(--space-2);
    font-family: var(--role-label-family);
    font-weight: var(--role-label-weight);
    font-size: var(--fs-label);
    line-height: var(--lh-tight);
    letter-spacing: var(--tr-label);
    text-transform: uppercase;
    color: var(--_label);
}

.t-taxon {
    font-family: var(--role-taxon-family);
    font-weight: var(--role-taxon-weight);
    font-style: italic;
    color: var(--_muted);
}

.t-muted { color: var(--_muted); }

.t-stat {
    display: block;
    font-family: var(--role-display-family);
    font-weight: var(--role-display-weight);
    font-size: var(--fs-stat);
    line-height: var(--lh-tight);
    letter-spacing: var(--tr-display);
    font-variant-numeric: tabular-nums lining-nums;
    color: var(--_heading);
}


/* --------------------------------------------------------------------------
   4. Bands and the content column
   Every section: <section class="band band--{tone}"><div class="col">...</div></section>
   -------------------------------------------------------------------------- */
.band {
    position: relative;
    padding-block: var(--band-y);
    background-color: var(--_bg);
    color: var(--_ink);
    overflow-x: clip;
}

.col {
    position: relative;
    z-index: var(--z-base);
    width: 100%;
    max-width: var(--col);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

/* Running prose keeps a reading measure inside the wide column and stays on the column's left
   edge (owner 2026-10-21). Paragraphs, lists, quotes and prose headings are capped; tables,
   figures, callouts, data blocks, grids, cards and section headers keep the full column. */
:is(.prose, .faq-answer, .article-body) > :is(p, ul, ol, blockquote, h2, h3, h4) {
    max-width: var(--measure-prose);
}

/* One reading width per article page (owner 2026-10-22, after scovidex.app: "Tôi ghét việc width
   cứ thay đổi ngẫu nhiên"). A .col--read column holds one centred column of --col-read: header,
   hero, TOC, prose, callouts, tables, figures, sources and FAQ share its width and axis, and
   nothing inside is narrower or wider. Card grids such as "Keep reading" keep the wide column. */
/* .band > .col.col--read outranks a component's own margin shorthand (.toc, .article-hero,
   .article-end .sources-section), so every child keeps the shared centre axis. */
.band > .col.col--read > * {
    width: 100%;
    max-width: var(--col-read);
    margin-inline: auto;
}
/* An inline-block label cannot take the auto margins, so it becomes a block row on the axis. */
.band > .col.col--read > .t-label { display: block; }
.col--read :is(.prose, .faq-answer, .article-body) > *,
.col--read .t-lead {
    max-width: none;
}

/* Light tones */
.band--white  { --_bg: var(--c-surface); }
.band--base   { --_bg: var(--c-bg); }
.band--lilac  { --_bg: var(--c-band-lilac); }

/* Dark tones. Two jobs, never mixed (docs/DESIGN_SPEC.md "Contrast sections"):
   band--strong (deep violet) carries brand and app moments only;
   band--ink (near-black) carries contrast sections for safety, data and decisions.
   The footer shares the ink tone at its deepest step. */
.band--strong {
    --_bg: var(--c-band-strong);
    --_ink: var(--c-on-strong);
    --_heading: var(--c-on-strong);
    --_label: var(--c-label-on-strong);
    --_link: var(--c-on-strong);
    --_muted: var(--c-on-strong-muted);
    --_focus: var(--c-focus-on-strong);
}
.band--ink,
.band--footer {
    --_ink: var(--c-on-ink);
    --_heading: var(--c-on-ink);
    --_label: var(--c-label-on-ink);
    --_link: var(--c-on-ink);
    --_muted: var(--c-on-ink-muted);
    --_focus: var(--c-focus-on-ink);
}
.band--ink    { --_bg: var(--c-band-ink); }
.band--footer { --_bg: var(--c-band-footer); }

/* Safety tones */
.band--danger {
    --_bg: var(--c-danger-bg);
    --_heading: var(--c-danger);
    --_label: var(--c-danger);
    --_link: var(--c-danger);
    padding-block: var(--space-3);
}
.band--emergency {
    --_bg: var(--c-emergency);
    --_ink: var(--c-on-emergency);
    --_heading: var(--c-on-emergency);
    --_label: var(--c-on-emergency);
    --_link: var(--c-on-emergency);
    --_muted: var(--c-on-emergency);
    --_focus: var(--c-focus-on-strong);
    padding-block: var(--space-5);
}

/* Light surfaces nested in a dark band get light-surface ink back.
   .prose (blocks.css) is a light-only component. */
:is(.card, .dex-card, .faq details, .safety-banner, .toc, .prose, .grid__end) {
    --_ink: var(--c-ink);
    --_heading: var(--c-ink-heading);
    --_label: var(--c-label-on-light);
    --_link: var(--c-link);
    --_muted: var(--c-ink-muted);
    --_focus: var(--c-focus);
}
/* Article prose inside a dark band sits on a surface panel, like a card. */
:is(.band--strong, .band--ink) .prose {
    padding: var(--space-5);
    background: var(--c-surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}


/* --------------------------------------------------------------------------
   5. Pattern: the light spore scatter (docs/DESIGN_SPEC.md "Composition system")
   One opt-in class, pat-dots. A band without it is flat. At most a third of
   the bands in main carry it, never two adjacent bands, never the band marked
   data-role="primary" (scripts/layout_audit.py). The scatter is a generated
   seamless tile used whole (AGENTS.md rule 8; masters and records in
   art-src/brand/pat-scatter-*), one per ground family, painted only in the
   margin zones left and right of the column, so no mark sits behind text or a
   card. Its strength is the pattern-strength token for light or dark grounds.
   -------------------------------------------------------------------------- */
:root {
    --img-scatter-white: url("/assets/images/patterns/scatter-white.webp");
    --img-scatter-offwhite: url("/assets/images/patterns/scatter-offwhite.webp");
    --img-scatter-lilac: url("/assets/images/patterns/scatter-lilac.webp");
    --img-scatter-dark: url("/assets/images/patterns/scatter-dark.webp");
    --img-dv-wave: url("/assets/images/dividers/wave.webp");
}
.pat-dots {
    --_scatter: var(--img-scatter-white);
    --_pat-o: var(--pattern-strength-light);
}
.band--base.pat-dots  { --_scatter: var(--img-scatter-offwhite); }
.band--lilac.pat-dots { --_scatter: var(--img-scatter-lilac); }
.pat-dots:is(.band--strong, .band--ink, .band--footer, .band--emergency) {
    --_scatter: var(--img-scatter-dark);
    --_pat-o: var(--pattern-strength-dark);
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .band.pat-dots {
        --_scatter: var(--img-scatter-dark);
        --_pat-o: var(--pattern-strength-dark);
    }
}
:root[data-theme="dark"] .band.pat-dots {
    --_scatter: var(--img-scatter-dark);
    --_pat-o: var(--pattern-strength-dark);
}
.pat-dots::before,
.pat-dots::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    width: calc(50% - var(--col) / 2);
    pointer-events: none;
    background-image: var(--_scatter);
    background-size: var(--pattern-tile) var(--pattern-tile);
    background-repeat: repeat;
    opacity: var(--_pat-o);
}
/* The two margins start at different points of the tile so they do not mirror. */
.pat-dots::before { left: 0; background-position: right top; }
.pat-dots::after { right: 0; background-position: left calc(var(--pattern-tile) * 0.41) top calc(var(--pattern-tile) * 0.23); }


/* --------------------------------------------------------------------------
   6. Dividers, chosen by the boundary (docs/DESIGN_SPEC.md "Composition system")
   - Two light bands (white, off-white, lilac) touching: one thin dashed
     hairline along the seam, drawn here, never placed by a template.
   - Into and out of a dark band, and around the danger strip: a straight
     edge, no divider.
   - dv-wave-top: at most one per page. The band's top edge waves up into the
     band above; the generated unit (art-src/brand/dv-wave) is the mask of a
     strip painted in this band's own ground. Not combined with pat-dots.
   - dv-sporo: <div class="dv-sporo" aria-hidden="true"></div> between two
     light bands, at most one per page: the dashed hairline with the generated
     Sporo medallion (art-src/brand/sporo-medallion) on it. Never on safety
     pages or beside a band that shows a poisonous species.
   -------------------------------------------------------------------------- */
.band:is(.band--white, .band--base, .band--lilac) + .band:is(.band--white, .band--base, .band--lilac) {
    border-top: var(--border-hairline) dashed var(--c-line);
}

.dv-wave-top::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: var(--space-4);
    pointer-events: none;
    background-color: var(--_bg);
    -webkit-mask: var(--img-dv-wave) left bottom / calc(var(--space-4) * 3) var(--space-4) repeat-x;
    mask: var(--img-dv-wave) left bottom / calc(var(--space-4) * 3) var(--space-4) repeat-x;
}

.dv-sporo {
    position: relative;
    z-index: var(--z-base);
    height: 0;
    border-top: var(--border-hairline) dashed var(--c-line);
}
.dv-sporo::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    width: calc(var(--space-6) + var(--space-2));
    height: calc(var(--space-6) + var(--space-2));
    transform: translate(-50%, -50%);
    background: url("/images/brand/sporo/sporo-medallion.webp") center / contain no-repeat;
}


/* --------------------------------------------------------------------------
   7. Grids: divide the column evenly. Phone reflow is in section 13.
   -------------------------------------------------------------------------- */
.grid {
    --_cols: 1;
    display: grid;
    grid-template-columns: repeat(var(--_cols), minmax(0, 1fr));
    gap: var(--space-4);
    padding: 0;
    list-style: none;
}
.grid--2 { --_cols: 2; }
.grid--3 { --_cols: 3; }
.grid--4 { --_cols: 4; }
.grid--6 { --_cols: 6; gap: var(--space-3); }

/* Grid end tile (templates/components/grid-end.php). Real-data grids whose count cannot fill the
   last row end with one navigation tile that spans exactly the empty columns. The server computes
   the span for desktop (data-span-d) and for the phone reflow (data-span-p); 0 hides the tile at
   that width. It is real navigation, never a fake species card. */
.grid__end {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--space-2);
    min-height: 100%;
    padding: var(--space-5);
    border: var(--border-hairline) dashed var(--c-line-strong);
    border-radius: var(--radius-md);
    background: var(--c-surface-sunk);
    color: var(--c-ink);
    text-decoration: none;
}
.grid__end:hover .link-arrow { text-decoration: underline; text-underline-offset: 0.18em; }
.grid__end .t-label { margin: 0; }
.grid__end p { margin: 0; color: var(--c-ink-muted); font-size: var(--fs-small); }
.grid__end[data-span-d="0"] { display: none; }
.grid__end[data-span-d="1"] { grid-column: span 1; }
.grid__end[data-span-d="2"] { grid-column: span 2; }
.grid__end[data-span-d="3"] { grid-column: span 3; }
.grid__end[data-span-d="4"] { grid-column: span 4; }
.grid__end[data-span-d="5"] { grid-column: span 5; }


/* --------------------------------------------------------------------------
   8. Cards
   -------------------------------------------------------------------------- */
.card,
.dex-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
    padding-bottom: var(--space-4);
    background: var(--c-surface);
    color: var(--_ink);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    overflow: hidden;
    text-decoration: none;
}
a.card, a.dex-card { color: var(--_ink); }
.card > :not(.card__media),
.dex-card > :not(.card__media) { margin-inline: var(--space-4); margin-block: 0; }
.card > .card__media + *,
.dex-card > .card__media + * { margin-top: var(--space-3); }
.card > :first-child:not(.card__media),
.dex-card > :first-child:not(.card__media) { margin-top: var(--space-4); }
.card :is(h2, h3, h4) {
    margin: 0;
    font-family: var(--role-title-family);
    font-weight: var(--role-title-weight);
    font-size: var(--fs-title);
    line-height: var(--lh-title);
    letter-spacing: 0;
}
:is(a.card, a.dex-card):hover :is(h2, h3, h4, .dex-card__name) { text-decoration: underline; text-underline-offset: 0.18em; }

.card__media {
    position: relative;
    margin: 0;
    aspect-ratio: 4 / 3;
    background: var(--c-surface-sunk);
    overflow: hidden;
}
/* Identification pictures are never cropped: the whole photo sits on the sunk surface. */
.card__media img,
.card__media picture {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.card__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.credit {
    position: absolute;
    left: var(--space-2);
    bottom: var(--space-2);
    margin: 0;
    padding: 2px var(--space-2);
    font-size: var(--fs-label);
    line-height: var(--lh-tight);
    font-weight: var(--fw-bold);
    color: var(--c-on-strong);
    background: color-mix(in srgb, var(--c-band-footer) 72%, transparent);
    border-radius: var(--radius-sm);
}
.credit a { color: inherit; }

/* Horizontal card: media left, body right. */
.card--h {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    align-items: center;
    gap: var(--space-4);
    padding-bottom: 0;
}
.card--h > .card__media { height: 100%; aspect-ratio: auto; min-height: 7.5rem; }
.card--h > :not(.card__media) { margin: var(--space-4) var(--space-4) var(--space-4) 0; }
.card--h > .card__media + * { margin-top: var(--space-4); }

/* Species index card */
.dex-card__no {
    font-size: var(--fs-caption);
    line-height: var(--lh-tight);
    font-variant-numeric: tabular-nums;
    color: var(--_muted);
}
.dex-card__name {
    margin: 0;
    font-family: var(--role-heading-family);
    font-weight: var(--role-heading-weight);
    font-size: var(--fs-title);
    line-height: var(--lh-tight);
    letter-spacing: var(--tr-heading);
    color: var(--_heading);
}
.dex-card .t-taxon { font-size: var(--fs-small); line-height: var(--lh-tight); }
.dex-card .ed-tag { margin-top: var(--space-2); }


/* --------------------------------------------------------------------------
   9. Controls: buttons, links, chips, badges, forms
   -------------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--control-h);
    padding: 0 var(--space-5);
    border: var(--border-hairline) solid transparent;
    border-radius: var(--radius-sm);
    font-family: var(--role-button-family);
    font-weight: var(--role-button-weight);
    font-size: var(--fs-small);
    line-height: var(--lh-tight);
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease),
        color var(--motion-fast) var(--motion-ease),
        border-color var(--motion-fast) var(--motion-ease);
}
.btn--primary { background: var(--c-accent); color: var(--c-bg); }
.btn--primary:hover { background: var(--c-accent-hover); color: var(--c-bg); }
.btn--gold { background: var(--c-highlight); color: var(--c-band-strong); }
.btn--gold:hover { background: color-mix(in srgb, var(--c-highlight), var(--c-surface) 18%); color: var(--c-band-strong); }
.btn--outline { background: transparent; color: var(--_link); border-color: currentColor; }
.btn--outline:hover { background: color-mix(in srgb, currentColor 8%, transparent); }
.btn--sm {
    min-height: var(--control-h-sm);
    padding: 0 var(--space-4);
    font-size: var(--fs-caption);
}
.band--strong .btn--primary { background: var(--c-on-strong); color: var(--c-band-strong); }
.band--strong .btn--primary:hover { background: var(--c-band-lilac); color: var(--c-band-strong); }
:is(.band--ink, .band--footer) .btn--primary { background: var(--c-on-ink); color: var(--c-band-ink); }
:is(.band--ink, .band--footer) .btn--primary:hover { background: var(--c-band-gold); color: var(--c-band-ink); }
.band--emergency .btn,
.band--emergency .btn:hover { background: var(--c-on-emergency); color: var(--c-emergency); border-color: var(--c-on-emergency); }

.link-arrow {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--_link);
    font-weight: var(--fw-bold);
    text-decoration: underline;
    text-underline-offset: 0.2em;
}
.link-arrow::after {
    content: "\2192";
    text-decoration: none;
    display: inline-block;
    transition: transform var(--motion-fast) var(--motion-ease);
}
.link-arrow:hover::after { transform: translateX(3px); }

.chip {
    display: inline-flex;
    align-items: center;
    min-height: var(--control-h-sm);
    padding: 0 var(--space-3);
    background: var(--c-chip);
    color: var(--c-on-chip);
    border-radius: var(--radius-sm);
    font-size: var(--fs-small);
    line-height: var(--lh-tight);
    text-decoration: none;
}
a.chip:hover { background: color-mix(in srgb, var(--c-chip), var(--c-accent) 10%); }
.t-label.chip,
.chip.t-label { min-height: 0; padding: var(--space-1) var(--space-2); color: var(--c-on-chip); font-size: var(--fs-label); }

.vs-badge {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: var(--control-h);
    height: var(--control-h);
    border-radius: 50%;
    background: var(--c-band-strong);
    color: var(--c-on-strong);
    font-family: var(--role-display-family);
    font-weight: var(--role-display-weight);
    font-size: var(--fs-small);
    letter-spacing: 0;
    box-shadow: 0 0 0 4px var(--c-surface);
}

.month-strip {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    margin: 0;
    padding: 0;
    list-style: none;
    border: var(--border-hairline) solid var(--c-line);
    border-radius: var(--radius-sm);
    background: var(--c-surface);
    overflow: hidden;
}
.month-strip > * {
    display: grid;
    place-items: center;
    min-height: var(--control-h-sm);
    margin: 0;
    font-size: var(--fs-caption);
    font-weight: var(--fw-bold);
    line-height: 1;
    color: var(--c-ink);
}
.month-strip > * + * { border-left: var(--border-hairline) solid var(--c-line); }
.month-strip > .is-on { background: var(--c-accent); color: var(--c-bg); border-left-color: var(--c-accent); }

/* Spore-print swatch (Template::sporeSwatch picks the key): profile field marks, home sample card. */
.spore-swatch {
    flex: none;
    width: 1.5em;
    height: 1.5em;
    border: var(--border-hairline) solid var(--spore-swatch-outline);
    border-radius: var(--radius-sm);
}
.spore-swatch--white        { background: var(--spore-white); }
.spore-swatch--cream        { background: var(--spore-cream); }
.spore-swatch--pink         { background: var(--spore-pink); }
.spore-swatch--chocolate    { background: var(--spore-chocolate); }
.spore-swatch--rust         { background: var(--spore-rust); }
.spore-swatch--purple-brown { background: var(--spore-purple-brown); }
.spore-swatch--black        { background: var(--spore-black); }
.spore-swatch--olive        { background: var(--spore-olive); }

.facts {
    display: grid;
    grid-template-columns: minmax(6.5rem, 32%) minmax(0, 1fr);
    margin: 0;
    font-size: var(--fs-small);
    line-height: var(--lh-title);
}
.facts > div { display: contents; }
.facts dt,
.facts dd {
    margin: 0;
    padding: var(--space-3) 0;
    border-top: var(--border-hairline) solid var(--c-line);
}
.facts dt { padding-right: var(--space-3); font-weight: var(--fw-bold); color: var(--_heading); }
.facts dd { color: var(--_ink); }
.facts > dt:first-of-type,
.facts > dt:first-of-type + dd,
.facts > div:first-child > :is(dt, dd) { border-top: 0; }

.faq { margin: 0; }
.faq > h2 { margin-bottom: var(--space-4); }
.faq details {
    margin: 0 0 var(--space-3);
    background: var(--c-surface);
    border: var(--border-hairline) solid var(--c-line);
    border-radius: var(--radius-sm);
}
.faq summary {
    position: relative;
    display: flex;
    align-items: center;
    min-height: var(--control-h);
    padding: var(--space-3) calc(var(--space-4) * 2 + var(--space-4)) var(--space-3) var(--space-4);
    list-style: none;
    font-weight: var(--fw-medium);
    line-height: var(--lh-title);
    color: var(--_ink);
    cursor: pointer;
}
.faq summary::-webkit-details-marker { display: none; }
/* Open/closed glyph from the vendored Phosphor font: ph-plus, ph-minus when open. */
.faq summary::after {
    content: "\e3d4";
    position: absolute;
    right: var(--space-4);
    top: 50%;
    transform: translateY(-50%);
    font-family: "Phosphor";
    font-style: normal;
    font-weight: normal;
    font-size: var(--space-5);
    line-height: 1;
    speak: never;
}
.faq details[open] > summary::after { content: "\e32a"; }
.faq .faq-answer {
    padding: 0 var(--space-4) var(--space-4);
    color: var(--_ink);
}

.field {
    display: grid;
    gap: var(--space-1);
    min-width: 0;
}
.field label {
    font-size: var(--fs-caption);
    font-weight: var(--fw-bold);
    color: var(--_heading);
}
.field :is(input, select, textarea) {
    width: 100%;
    min-height: var(--control-h);
    padding: 0 var(--space-4);
    background: var(--c-surface);
    color: var(--c-ink);
    border: var(--border-hairline) solid var(--c-line-strong);
    border-radius: var(--radius-sm);
}
.field textarea { padding-block: var(--space-3); min-height: calc(var(--control-h) * 2); }
.field :is(input, select, textarea)::placeholder { color: var(--c-ink-muted); }

.waitlist-form {
    display: flex;
    align-items: flex-end;
    gap: var(--space-3);
    margin: 0;
}
.waitlist-form .field { flex: 1 1 auto; }
.waitlist-form .btn { flex: none; }


/* --------------------------------------------------------------------------
   10. Editorial chrome: breadcrumb, byline, table of contents, sources
   -------------------------------------------------------------------------- */
.breadcrumb { margin: 0 0 var(--space-4); font-size: var(--fs-caption); line-height: var(--lh-title); }
.breadcrumb ol {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1) var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}
.breadcrumb li { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--_muted); }
.breadcrumb li + li::before { content: "/"; color: var(--_muted); }
.breadcrumb a { color: var(--_link); text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }

.byline {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: 0 0 var(--space-4);
    font-size: var(--fs-caption);
    line-height: var(--lh-title);
    color: var(--_muted);
}
.byline__initials {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: calc(var(--space-6) + var(--space-2));
    height: calc(var(--space-6) + var(--space-2));
    border-radius: 50%;
    background: var(--c-chip);
    color: var(--c-on-chip);
    font-family: var(--role-title-family);
    font-weight: var(--role-title-weight);
    font-size: var(--fs-caption);
    letter-spacing: 0.02em;
}
.byline__text { margin: 0; }
.byline__text a { color: var(--_link); }
.byline__reviewer { color: var(--_ink); }
.byline__sep { padding-inline: var(--space-1); }

/* Table of contents, filled by site.js from the article's h2 headings. */
.toc {
    margin: 0 0 var(--space-6);
    background: var(--c-surface);
    border: var(--border-hairline) solid var(--c-line);
    border-radius: var(--radius-md);
}
.toc-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    min-height: var(--control-h);
    padding: var(--space-2) var(--space-4);
    background: none;
    border: 0;
    border-radius: var(--radius-md);
    text-align: left;
}
.toc-title {
    font-family: var(--role-label-family);
    font-weight: var(--role-label-weight);
    font-size: var(--fs-label);
    letter-spacing: var(--tr-label);
    text-transform: uppercase;
    color: var(--_label);
}
/* Phosphor ph-caret-down; it points up while the list is open. */
.toc-toggle {
    color: var(--_heading);
    font-size: var(--space-5);
    line-height: 1;
    transform: rotate(180deg);
    transition: transform var(--motion-fast) var(--motion-ease);
}
.toc-toggle::before {
    content: "\e136";
    font-family: "Phosphor";
    font-style: normal;
    font-weight: normal;
    speak: never;
}
.toc.is-collapsed .toc-toggle { transform: none; }
.toc.is-collapsed .toc-body { display: none; }
/* A quiet stacked list at the reading width (after scovidex.app): hairline rows, the number in
   the label colour, ink links that turn to the link colour on hover and for the active section. */
.toc ol {
    margin: 0;
    padding: 0 var(--space-4) var(--space-2);
    list-style: none;
    counter-reset: toc;
    font-size: var(--fs-small);
    line-height: var(--lh-title);
}
.toc li {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    padding-block: var(--space-2);
    border-top: var(--border-hairline) solid var(--c-line);
    counter-increment: toc;
}
.toc li::before {
    content: counter(toc);
    flex: none;
    min-width: var(--space-5);
    color: var(--_label);
    font-weight: var(--fw-bold);
    font-size: var(--fs-caption);
    font-variant-numeric: tabular-nums;
}
.toc a { color: var(--_ink); text-decoration: none; }
.toc a:hover,
.toc li.is-active > a { color: var(--_link); text-decoration: underline; }
.toc li.is-active > a { font-weight: var(--fw-bold); }

.sources-section { margin: var(--space-7) 0 0; }
/* "Sources · N" accordion (components/sources.php), a light surface in any band. */
.sources {
    --_ink: var(--c-ink);
    --_heading: var(--c-ink-heading);
    --_link: var(--c-link);
    --_muted: var(--c-ink-muted);
    --_focus: var(--c-focus);
    background: var(--c-surface);
    border: var(--border-hairline) solid var(--c-line);
    border-radius: var(--radius-sm);
    color: var(--_ink);
}
.sources > summary {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--control-h);
    padding: var(--space-3) var(--space-4);
    list-style: none;
    font-family: var(--role-title-family);
    font-weight: var(--role-title-weight);
    line-height: var(--lh-title);
    color: var(--_heading);
    cursor: pointer;
}
.sources > summary::-webkit-details-marker { display: none; }
.sources__sep { color: var(--_muted); }
.sources__count { font-variant-numeric: tabular-nums; }
.sources__icon { margin-left: auto; transition: transform var(--motion-fast) var(--motion-ease); }
.sources[open] .sources__icon { transform: rotate(180deg); }
.sources .source-list { padding: 0 var(--space-4) var(--space-4) calc(var(--space-4) + var(--space-5)); }
.source-list {
    margin: 0;
    padding-left: var(--space-5);
    font-size: var(--fs-small);
    line-height: var(--lh-title);
}
.source-list li { padding-block: var(--space-1); }
.source-list li::marker { color: var(--_muted); }
.source-note { display: block; color: var(--_muted); font-size: var(--fs-caption); }

/* Reading progress bar driven by site.js */
.reading-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: var(--z-toast);
    pointer-events: none;
}
.reading-progress .rp-bar { width: 0; height: 100%; background: var(--c-highlight); }


/* --------------------------------------------------------------------------
   11. Edibility marks and tags (rendered only by edibilityBadge())
   Shape and label always travel together; color is never the only signal.
   -------------------------------------------------------------------------- */
.ed-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
    font-family: var(--role-body-family);
    font-weight: var(--fw-medium);
    font-size: var(--fs-small);
    line-height: var(--lh-tight);
    color: var(--_ink);
    white-space: nowrap;
}

/* The mark is the generated Loupe stamp image (public/assets/images/icons/
   edibility/, records in art-src/brand/icon-*), rendered by edibilityBadge() as
   <img class="ed-mark ed-mark--{key}">. Each stamp carries its own white sticker
   rim, so one file reads on light and dark bands; --_m / --_ms / --_c stay as
   the tier's token colors for components that tint text or edges by tier.
   --lg loads the larger file for marks drawn at about 28 px and up. */
.ed-mark {
    --_c: var(--_m);
    display: inline-block;
    flex: none;
    width: 1.5em;
    height: 1.5em;
    object-fit: contain;
    vertical-align: -0.3em;
}
.ed-mark--lg { width: 2.1em; height: 2.1em; vertical-align: -0.6em; }
/* A bare <span class="ed-mark ed-mark--{key}"> paints the same stamp file. */
span.ed-mark { background: var(--_icon) center / contain no-repeat; }
.ed-mark--choice    { --_m: var(--ed-choice);    --_ms: var(--ed-choice-on-strong);    --_icon: url("/assets/images/icons/edibility/choice.webp"); }
.ed-mark--edible    { --_m: var(--ed-edible);    --_ms: var(--ed-edible-on-strong);    --_icon: url("/assets/images/icons/edibility/edible.webp"); }
.ed-mark--caution   { --_m: var(--ed-caution);   --_ms: var(--ed-caution-on-strong);   --_icon: url("/assets/images/icons/edibility/caution.webp"); }
.ed-mark--medicinal { --_m: var(--ed-medicinal); --_ms: var(--ed-medicinal-on-strong); --_icon: url("/assets/images/icons/edibility/medicinal.webp"); }
.ed-mark--inedible  { --_m: var(--ed-inedible);  --_ms: var(--ed-inedible-on-strong);  --_icon: url("/assets/images/icons/edibility/inedible.webp"); }
.ed-mark--poisonous { --_m: var(--ed-poisonous); --_ms: var(--ed-poisonous-on-strong); --_icon: url("/assets/images/icons/edibility/poisonous.webp"); }

:is(.band--strong, .band--ink, .band--footer) .ed-mark { --_c: var(--_ms); }
:is(.band--strong, .band--ink, .band--footer) :is(.card, .dex-card, .safety-banner, .faq details, .toc, .prose, .grid__end) .ed-mark { --_c: var(--_m); }
.band--emergency .ed-mark { --_c: var(--c-on-emergency); }


/* --------------------------------------------------------------------------
   12. Safety banner and the emergency band
   safety-banner safety-banner--{choice|edible|caution|medicinal|inedible|poisonous}
   -------------------------------------------------------------------------- */
.safety-banner {
    --_sb-bg: var(--c-surface-sunk);
    --_sb-edge: var(--ed-inedible);
    display: block;
    margin: 0 0 var(--space-5);
    padding: var(--space-4) var(--space-5);
    background: var(--_sb-bg);
    border-left: var(--border-edge) solid var(--_sb-edge);
    border-radius: var(--radius-sm);
    color: var(--_ink);
}
.safety-banner__body { display: grid; gap: var(--space-1); }
.safety-banner__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    margin: 0;
}
.safety-banner__head .ed-tag {
    font-weight: var(--fw-bold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--_heading);
}
.safety-banner__text { margin: 0; font-size: var(--fs-small); line-height: var(--lh-body); }
.safety-banner__text a { color: var(--_link); }

.safety-banner--choice,
.safety-banner--edible    { --_sb-bg: var(--c-safe-bg);    --_sb-edge: var(--ed-choice); }
.safety-banner--edible    { --_sb-edge: var(--ed-edible); }
.safety-banner--caution   { --_sb-bg: var(--c-band-gold);  --_sb-edge: var(--ed-caution); }
.safety-banner--medicinal { --_sb-bg: var(--c-band-lilac); --_sb-edge: var(--ed-medicinal); }
.safety-banner--inedible  { --_sb-bg: var(--c-surface-sunk); --_sb-edge: var(--ed-inedible); }
.safety-banner--poisonous {
    --_sb-bg: var(--c-danger-bg);
    --_sb-edge: var(--c-danger);
    --_heading: var(--c-danger);
}

/* Emergency strip on poisonous safety pages: <section class="band band--emergency"> */
.band--emergency .col {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-4) var(--space-5);
}
.band--emergency :is(h1, h2, h3, .t-h2, .t-h3) {
    margin: 0;
    font-size: var(--fs-h3);
    text-transform: uppercase;
    letter-spacing: 0.01em;
}
.band--emergency p { margin: 0; font-size: var(--fs-small); }
.band--emergency .ed-mark { width: 2.5em; height: 2.5em; }


/* --------------------------------------------------------------------------
   13. Site header
   -------------------------------------------------------------------------- */
.site-header {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    background: var(--c-surface);
    border-bottom: var(--border-hairline) solid var(--c-line);
}
.site-header__inner {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    min-height: var(--header-h);
}
.site-header__logo {
    display: inline-flex;
    flex: none;
    align-items: center;
    margin-right: auto;
}
/* The generated lockup (art-src/brand/logo-light|dark) sits on a 3:1 canvas
   with transparent space above and below it; the negative margin lets that
   space overlap the header padding instead of making the header taller. */
.site-header__logo img {
    width: auto;
    height: calc(var(--header-h) + var(--space-3));
    margin-block: calc(var(--space-3) / -2);
}
.site-nav {
    display: flex;
    align-items: center;
    gap: var(--space-5);
}
.site-nav__list {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}
.site-nav__link {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-min);
    color: var(--c-ink);
    font-size: var(--fs-small);
    font-weight: var(--fw-medium);
    text-decoration: none;
    border-bottom: 2px solid transparent;
}
.site-nav__link:hover { color: var(--c-ink-heading); border-bottom-color: var(--c-line-strong); }
.site-nav__link[aria-current] { color: var(--c-ink-heading); font-weight: var(--fw-bold); border-bottom-color: var(--c-highlight); }

.site-header__toggle {
    display: none;
    place-items: center;
    width: var(--tap-min);
    height: var(--tap-min);
    margin-right: calc(-1 * var(--space-2));
    padding: 0;
    background: none;
    border: 0;
    border-radius: var(--radius-sm);
    color: var(--c-ink-heading);
}
/* Menu glyph from the vendored Phosphor font: ph-list, ph-x while open. */
.site-header__bars {
    display: block;
    font-size: var(--space-5);
    line-height: 1;
}
.site-header__bars::before {
    content: "\e2f0";
    font-family: "Phosphor";
    font-style: normal;
    font-weight: normal;
    speak: never;
}
.site-header.is-open .site-header__bars::before { content: "\e4f6"; }


/* --------------------------------------------------------------------------
   14. Site footer (always band band--footer, the deepest ink step)
   -------------------------------------------------------------------------- */
.site-footer { padding-block: var(--space-7) var(--space-6); }
.site-footer__top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4) var(--space-5);
    padding-bottom: var(--space-5);
    border-bottom: var(--border-hairline) solid color-mix(in srgb, var(--_ink) 18%, transparent);
}
.site-footer__logo { display: inline-flex; }
.site-footer__logo img { width: auto; height: calc(var(--space-7) + var(--space-5)); margin-block: calc(var(--space-4) * -1); }
.site-footer__line { margin: 0; font-size: var(--fs-caption); color: var(--_ink); }
.site-footer__groups { padding-block: var(--space-5); row-gap: var(--space-5); }
.site-footer__group .t-label { margin-bottom: var(--space-2); }
.site-footer__group ul { margin: 0; padding: 0; list-style: none; font-size: var(--fs-caption); line-height: var(--lh-title); }
.site-footer__group li { padding-block: var(--space-1); }
.site-footer__group a { color: var(--_ink); text-decoration: none; }
.site-footer__group a:hover { text-decoration: underline; }
.site-footer__phone { display: block; color: var(--_muted); }
.site-footer__legal {
    margin: 0;
    padding-top: var(--space-4);
    border-top: var(--border-hairline) solid color-mix(in srgb, var(--_ink) 18%, transparent);
    font-size: var(--fs-caption);
    color: var(--_muted);
}


/* --------------------------------------------------------------------------
   15. Motion preferences
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
}
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}


/* ==========================================================================
   16. BREAKPOINTS
   The only place breakpoint numbers appear. They mirror the breakpoint
   tokens documented in tokens.css: phone (max-width: 767px),
   tablet (min-width: 768px), desktop (min-width: 1024px), wide (min-width: 1280px).
   ========================================================================== */

/* phone */
@media (max-width: 767px) {
    .grid--6 { --_cols: 3; }
    .grid--4 { --_cols: 2; }
    .grid--3 { --_cols: 2; }
    .grid--2 { --_cols: 1; }
    .grid { gap: var(--space-3); }
    .grid__end[data-span-p] { display: flex; }
    .grid__end[data-span-p="0"] { display: none; }
    .grid__end[data-span-p="1"] { grid-column: span 1; }
    .grid__end[data-span-p="2"] { grid-column: span 2; }

    .card--h { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: var(--space-3); }
    .card--h > :not(.card__media) { margin: var(--space-3) var(--space-3) var(--space-3) 0; }

    .waitlist-form { flex-direction: column; align-items: stretch; }

    .safety-banner { padding: var(--space-4); }

    .site-header__logo img { height: var(--header-h); margin-block: 0; }
    .site-header__toggle { display: inline-grid; }
    .site-nav {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        z-index: var(--z-menu);
        display: none;
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-4);
        padding: var(--space-2) var(--gutter) var(--space-5);
        background: var(--c-surface);
        border-bottom: var(--border-hairline) solid var(--c-line);
        box-shadow: var(--shadow-card);
    }
    .site-header.is-open .site-nav { display: flex; }
    .site-nav__list { flex-direction: column; align-items: stretch; gap: 0; }
    .site-nav__list li + li { border-top: var(--border-hairline) solid var(--c-line); }
    .site-nav__link { display: flex; min-height: calc(var(--tap-min) + var(--space-2)); font-size: var(--fs-body); border-bottom: 0; }
    .site-nav__link[aria-current] { box-shadow: inset var(--border-edge) 0 0 var(--c-highlight); padding-left: var(--space-3); }
    .site-nav .btn { min-height: var(--control-h); font-size: var(--fs-small); }

    .site-footer__groups { --_cols: 2; }

    /* Touch targets: stand-alone links reach the tap minimum (44 px); links in a row of
       editorial chrome reach about 34 to 36 px, above WCAG 2.5.8's 24 px. */
    .site-footer__group a,
    a.chip:not(.t-label) { display: inline-flex; align-items: center; min-height: var(--tap-min); }
    .breadcrumb a,
    .toc a { display: inline-flex; align-items: center; min-height: var(--control-h-sm); }
    .byline__text a { padding-block: var(--space-2); }
}

/* tablet and up */
@media (min-width: 768px) {
    .site-header__toggle { display: none; }
}
