/* Contrast, measured against the white section ground 2026-08-31:
   #929292 was 3.11:1 and brand --color-2 #1d84c7 was 4.06:1 as text, both
   below the 4.5 AA minimum. #6e6e6e is 5.10:1 and #1a6bb5 is 5.51:1. The
   brand blue survives untouched wherever it is a non-text rule or accent. */
/* Legislative and Policy Work (DESIGN-SPEC B5). Light section on the page's
   dark/light alternation -- deliberately white: #results directly above is
   the dark stage for the ledger count-up, and a second dark band would
   dilute it (Matt's call, 2026-08-31). FORK 4: .bio-policy--editorial
   (shipped), .bio-policy--timeline (4A), .bio-policy--cards (4B).
   Type sizes come from the theme ramp (--fsize-*) or responsive clamp();
   no hardcoded font-size in this file. */

.bio-policy {
    background: white;
    padding: 6% 0;
    /* n17: containing block and stacking context for the ground texture
       painted by .bio-policy::before further down this file. */
    position: relative;
    isolation: isolate;
}

.bio-policy-inner {
    width: 90%;
    max-width: 1100px;
    margin: 0 auto;
}

.bio-policy-heading {
    font-family: var(--heading-font);
    color: var(--color-1);
    font-size: var(--fsize-lg);
    margin: 0 0 40px;
}

/* ---- FORK 4A: vertical timeline rail ---- */
.bio-policy--timeline .bio-policy-rail {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 36px;
    padding-left: 32px;
    border-left: 3px solid var(--color-2);
}
.bio-policy--timeline .bio-policy-entry {
    position: relative;
}
.bio-policy--timeline .bio-policy-year {
    position: absolute;
    left: -32px;
    top: 2px;
    transform: translateX(calc(-100% - 18px));
    font-family: var(--text-font);
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--color-2);
    text-transform: uppercase;
    font-size: var(--fsize-xs);
    white-space: nowrap;
}
.bio-policy--timeline .bio-policy-entry::before {
    content: "";
    position: absolute;
    left: -32px;
    top: 8px;
    transform: translateX(-50%);
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: var(--color-2);
    border: 3px solid white;
    box-shadow: 0 0 0 1px var(--color-2);
}

/* ---- FORK 4B: three statute cards ---- */
.bio-policy--cards .bio-policy-rail {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
}
.bio-policy--cards .bio-policy-entry {
    border: 1px solid #e9e9e9;
    border-radius: 4px;
    padding: 20px;
}
.bio-policy--cards .bio-policy-year {
    display: block;
    font-family: var(--text-font);
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--color-2);
    text-transform: uppercase;
    font-size: var(--fsize-xs);
    margin-bottom: 8px;
}

.bio-policy-title {
    /* Rendered as a styled <p> (heading map: H3 only in Background). */
    font-family: var(--heading-font);
    color: var(--color-1);
    font-size: var(--fsize-h3);
    margin: 0 0 8px;
    line-height: 1.2;
}
.bio-policy-body {
    color: var(--color-3);
    font-size: var(--fsize-default);
    line-height: 1.6;
    margin: 0;
    max-width: 65ch;
}

/* The page's single pull-quote (gate W7). */
.bio-pullquote {
    margin: 56px 0 0;
    padding-left: 24px;
    border-left: 4px solid var(--color-2);
}
.bio-pullquote p {
    font-family: var(--heading-font);
    color: var(--color-1);
    font-size: clamp(28px, 4vw, 40px);
    line-height: 1.15;
    margin: 0 0 10px;
}
.bio-pullquote cite {
    display: block;
    font-family: var(--text-font);
    font-style: normal;
    font-weight: 600;
    color: var(--color-4);
    font-size: var(--fsize-xs);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

@media (max-width: 1000px) {
    .bio-policy--cards .bio-policy-rail {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 750px) {
    .bio-policy--timeline .bio-policy-rail {
        padding-left: 20px;
    }
    .bio-policy--timeline .bio-policy-year {
        position: static;
        transform: none;
        display: block;
        margin-bottom: 4px;
    }
    .bio-policy--timeline .bio-policy-entry::before {
        left: -20px;
    }
}

/* n17, Matt 2026-09-01: "Ad a subtle background texture".

   The policy section is the page's largest white field -- 2,648px of it -- sat
   between two near-black sections, and it read as a blank sheet. A hairline
   diagonal weave at 2.5% of the brand blue gives the ground a surface without
   competing with the type or the photographs. Drawn in CSS rather than as an
   image: no request, no asset to vault, and it scales at any viewport. The
   pseudo-element carries it so the section's own background stays a flat colour
   for anything that needs to sample it. */
.bio-policy::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        repeating-linear-gradient(
            45deg,
            rgba(29, 132, 199, 0.025) 0,
            rgba(29, 132, 199, 0.025) 1px,
            transparent 1px,
            transparent 9px
        );
}
@media (prefers-reduced-transparency: reduce) {
    .bio-policy::before { display: none; }
}

/* ---- Editorial feature rows (Matt's "editorial hero" note, 2026-08) ---- */
.bio-policy--editorial .bio-policy-features {
    display: flex;
    flex-direction: column;
}
.bio-policy--editorial .bio-policy-feature {
    position: relative;
    display: grid;
    grid-template-columns: 3fr 2fr;   /* 60/40 asymmetry (gate W2) */
    gap: 48px;
    align-items: start;
    padding: 64px 0;
    border-top: 1px solid #e9e9e9;
}
.bio-policy--editorial .bio-policy-feature:nth-child(even) .bio-policy-feature-text  { order: 2; }
.bio-policy--editorial .bio-policy-feature:nth-child(even) .bio-policy-feature-media { order: 1; }


/* Ghost year numeral: the time dimension as typography. Static -- costs
   nothing against the page's motion budget (house Rule 5). */
.bio-policy--editorial .bio-policy-ghost-year {
    position: absolute;
    top: 8px;
    right: -8px;
    font-family: var(--heading-font);
    font-size: clamp(96px, 14vw, 180px);
    line-height: 1;
    color: rgba(29, 132, 199, 0.10);   /* --color-2 at 10%; P15 clean */
    letter-spacing: 0.02em;
    pointer-events: none;
    user-select: none;
    z-index: 0;
}
.bio-policy--editorial .bio-policy-feature:nth-child(even) .bio-policy-ghost-year {
    right: auto;
    left: -8px;
}

/* n3, Matt 2026-09-02: "move the 2017 background up a good bit to not be fully
   hidden by the photo. And same for the others also."

   Measured at 1920: the numeral sets in Anton at 180px, whose ink runs from
   11.5px to 167.5px inside its own 180px line box. At top:8px that put ink at
   y=20.5..176.5 in the row while the photograph starts at y=65 -- 44px of a
   156px numeral showing, 71% of it behind the picture.

   The lift is written in the numeral's OWN em rather than in pixels because
   the size is a clamp: 0.4em is 72px against the 180px numeral and shrinks
   with it, so the relationship holds at every width in the two-column range
   instead of only at 1920. Ink now runs -51.5..104.5: three quarters of the
   year stands in the 64px gutter above the row, and its foot still tucks
   behind the top edge of the photograph, which is what makes it read as a
   ground element rather than a number floating in whitespace.

   Scoped to min-width:1001px. Below that the row stacks text-then-media and
   the numeral sits behind the kicker, not the photo -- a different geometry,
   tuned in the n13 mobile pass, and this note is about the desktop row. */
@media (min-width: 1001px) {
    .bio-policy--editorial .bio-policy-ghost-year {
        top: calc(8px - 0.4em);
    }
}
.bio-policy--editorial .bio-policy-feature-text,
.bio-policy--editorial .bio-policy-feature-media {
    position: relative;
    z-index: 1;
}

.bio-policy--editorial .bio-policy-kicker {
    margin: 0 0 10px;
    font-family: var(--text-font);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: var(--fsize-xs);
}
.bio-policy--editorial .bio-policy-kicker-year  { color: var(--color-2); margin-right: 12px; }
.bio-policy--editorial .bio-policy-kicker-label { color: var(--color-4); }

.bio-policy--editorial .bio-policy-title {
    font-family: var(--heading-font);
    color: var(--color-1);
    font-size: clamp(34px, 4.5vw, 52px);
    line-height: 1.05;
    margin: 0 0 18px;
}
.bio-policy--editorial .bio-policy-body {
    color: var(--color-3);
    font-size: var(--fsize-body);
    line-height: 1.65;
    margin: 0;
    max-width: 60ch;
}

/* Photo slot */
.bio-policy-photo { margin: 0 0 18px; }
.bio-policy-photo img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 3 / 2;
    object-fit: cover;
}
.bio-policy-photo figcaption {
    font-family: var(--text-font);
    font-size: var(--fsize-xs);
    color: var(--color-4);
    margin-top: 8px;
    letter-spacing: 0.02em;
}

/* Photo placeholder -- bio-tech n23 convention: a visible position marker
   naming what belongs in the slot, never invented imagery. Disappears the
   moment a real image is set. */
.bio-policy-photo--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 180px;
    border: 2px dashed rgba(29, 132, 199, 0.45);
    border-radius: 4px;
    background: rgba(29, 132, 199, 0.05);
}
.bio-policy-photo-label {
    font-family: var(--text-font);
    font-size: var(--fsize-xs);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #5b6b78;
    text-align: center;
    padding: 16px;
}

/* Press cards -- the news, woven in */
.bio-policy-press {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}
.bio-policy-press-item:only-child { grid-column: 1 / -1; }
/* The parent theme decorates every li with a 7px blue disc via ::before, which
   put a stray dot to the left of each press card. Same suppression
   .bio-results-index-item already carries, for the same reason. */
.bio-policy-press-item::before {
    content: none !important;
}
.bio-policy-press-play {
    position: relative;
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}
.bio-policy-press-play img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    filter: brightness(0.92);
    transition: filter 0.2s ease-out;
}
.bio-policy-press-play:hover img,
.bio-policy-press-play:focus-visible img { filter: brightness(1); }
.bio-policy-press-badge {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.bio-policy-press-badge svg { width: 46px; height: auto; }
.bio-policy-press-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-top: 10px;
}
.bio-policy-press-outlet {
    font-family: var(--text-font);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: var(--fsize-xs);
    color: #1a6bb5;
}
.bio-policy-press-headline {
    font-family: var(--text-font);
    font-weight: 600;
    font-size: var(--fsize-default);
    line-height: 1.4;
    color: var(--color-1);
    text-decoration: none;
    background-image: linear-gradient(var(--color-2), var(--color-2));
    background-size: 0% 2px;
    background-repeat: no-repeat;
    background-position: 0 100%;
    transition: background-size 0.25s ease-out;
}
a.bio-policy-press-headline:hover,
a.bio-policy-press-headline:focus-visible { background-size: 100% 2px; }
.bio-policy-press-date {
    font-family: var(--text-font);
    font-size: var(--fsize-xs);
    color: var(--color-4);
    letter-spacing: 0.04em;
}

/* Pull-quote, inline variant inside the kratom feature (still the page's
   only blockquote -- gate W7) */
.bio-policy--editorial .bio-pullquote--inline {
    grid-column: 1 / -1;
    /* Grid auto-placement is order-modified document order, and the even-row
       column swap gives text/media order 1 and 2 -- without this the quote
       (default order 0) would place FIRST in the row, not beneath the pair. */
    order: 3;
    margin: 40px 0 0;
}
/* n13, Matt 2026-09-01: "widen this or put it on the far right above. it takes
   up too much space on its own."

   The blockquote already spanned the row -- grid-column and order above see to
   that. What made it look like a narrow column was this measure cap: 24ch
   resolved against 44px display type is 528px, so the quote set nine lines deep
   inside an 1100px row and left the other half of the row empty. Uncapped, at
   one step down the size ramp, the same words set in three lines and the
   section gets about 250px of its height back. */
.bio-policy--editorial .bio-pullquote--inline p {
    font-size: clamp(26px, 2.6vw, 38px);
    line-height: 1.18;
    max-width: none;
}

/* Lightbox (src set on click; gate P12) */
.bio-policy-lightbox {
    position: fixed;
    inset: 0;
    z-index: 999;
    background: rgba(34, 31, 31, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.bio-policy-lightbox[hidden] { display: none; }
.bio-policy-lightbox-frame {
    position: relative;
    width: min(920px, 100%);
    aspect-ratio: 16 / 9;
}
.bio-policy-lightbox-frame iframe {
    width: 100%;
    height: 100%;
    border: 0;
}
.bio-policy-lightbox-close {
    position: absolute;
    top: -44px;
    right: 0;
    width: 44px;
    height: 44px;
    border: 0;
    background: none;
    color: white;
    font-family: var(--text-font);
    font-weight: 700;
    font-size: var(--fsize-sm);
    cursor: pointer;
}

@media (max-width: 1000px) {
    .bio-policy--editorial .bio-policy-feature {
        grid-template-columns: 1fr;
        gap: 28px;
        padding: 48px 0;
    }
    .bio-policy--editorial .bio-policy-feature:nth-child(even) .bio-policy-feature-text  { order: 0; }
    .bio-policy--editorial .bio-policy-feature:nth-child(even) .bio-policy-feature-media { order: 0; }
    .bio-policy--editorial .bio-policy-ghost-year { right: 0; }
    .bio-policy--editorial .bio-policy-feature:nth-child(even) .bio-policy-ghost-year { left: auto; right: 0; }
}
@media (max-width: 500px) {
    .bio-policy-press { grid-template-columns: 1fr; }
}

/* Matt's mobile round, 2026-09-02. n4 and n7 drop two press cards, n6 drops
   one photograph, n5 drops the pull-quote -- "drop on mobile only". Taken
   together the rule is one media item per entry on a phone, which is what the
   other three entries already had. Which photograph and which cards is decided
   in block.php, keyed by file and by video id rather than by nth-child, so a
   reordered repeater cannot move the rule onto the wrong picture.

   The pull-quote goes by selector because there is only ever one of it (gate
   W7). Hidden, the phone render has zero blockquotes, which still satisfies
   "no more than one". */
@media (max-width: 750px) {
    .bio-policy-photo--phone-hidden,
    .bio-policy-press-item--phone-hidden,
    .bio-policy--editorial .bio-pullquote {
        display: none;
    }
}

/* --color-4 (#929292) is a theme-wide muted-text token and measures 3.11:1 on
   this section's white ground -- below the 4.5 AA minimum for normal text. It
   is used here by the kicker label, the press date and the pull-quote citation.
   Overridden locally rather than globally: the token is used elsewhere on the
   site, possibly over darker grounds where it passes, and retiring it site-wide
   is a decision with a much wider blast radius than this section. #6e6e6e is
   5.10:1 and reads as the same muted gray. */
.bio-policy--editorial {
    --color-4: #6e6e6e;
}
.bio-policy--editorial .bio-pullquote cite {
    color: #6e6e6e;
}

/* A feature row with nothing in its media column (block.php emits the modifier
   on the same test that suppresses the column, currently only the 2018 City
   Hall entry, which has no photograph). Left on the base 3fr/2fr grid the text
   sat alone in the 3fr column with a blank 2fr beside it, and the even-row
   ghost numeral, which belongs behind a photo, sat behind the kicker and title.
   Scoped to the two-column range: below 1001px every row is already 1fr with
   the numeral at right: 0, and this must not move it for one row only.

   Cascade: the grid rule ties the base .bio-policy--editorial .bio-policy-feature
   at (0,2,0) and the numeral rule ties the :nth-child(even) override at (0,4,0);
   both win on source order, which is why this block sits at the END of the file.
   Verified on computed values, not source order. */
@media (min-width: 1001px) {
    .bio-policy--editorial .bio-policy-feature--no-media {
        grid-template-columns: 1fr;
    }
    .bio-policy--editorial .bio-policy-feature.bio-policy-feature--no-media .bio-policy-ghost-year {
        right: -8px;
        left: auto;
    }
}

/* n4, Matt 2026-09-02: "reduce top padding on desktop".

   The section pads 6% top and bottom, which is 115px at 1920 and 86px at 1440.
   The sections below it, #technology and #leadership, both pad 64px, and
   #results above pads clamp(36px, 3.5vw, 48px); 64px is the rhythm of the
   page's fixed-padding sections, so the top matches #technology. min() keeps
   the existing 6% wherever it is already smaller (1001-1066px), so the rule
   only ever reduces. Desktop only: below 1001px the 6% stands (46px at 768,
   23px at 390). Bottom padding untouched.

   Cascade: ties .bio-policy { padding } at (0,1,0) and wins on source order,
   which is why it sits below that rule. Verified on the computed value. */
@media (min-width: 1001px) {
    .bio-policy {
        padding-top: min(6%, 64px);
    }
}

/* n9, Matt 2026-09-02, on the kratom blockquote: "bring this up to the left
   column".

   The quote spanned the full row beneath the text/media pair, so on the row
   that carries it the text column ended 335px above the media column and the
   quote sat below both. It now takes a second grid row in the TEXT column,
   directly under the body, while the media column spans both rows. Only the
   row block.php marks --quoted gets the second row: a row-gap on every row
   would add 40px wherever the text is taller than the media.

   "Left" is a rendered position: odd rows put the text in column 1 and even
   rows swap it to column 2 with order, so the quote follows the text column in
   both cases. The carrying row today is the third (odd), so the quote lands in
   column 1. auto 1fr rather than auto auto: a spanning item's excess height is
   shared equally across auto tracks and would open a gap between the body and
   the quote; the fr track absorbs it instead, so the quote hugs the body.

   The type steps down once more from the n13 size: at column width (631px at
   1100) the 38px line set six lines deep and pushed the row past the media. */
@media (min-width: 1001px) {
    .bio-policy--editorial .bio-policy-feature--quoted {
        grid-template-rows: auto 1fr;
        row-gap: 40px;
    }
    .bio-policy--editorial .bio-policy-feature--quoted .bio-policy-feature-media {
        grid-row: 1 / span 2;
    }
    .bio-policy--editorial .bio-policy-feature--quoted .bio-pullquote--inline {
        grid-column: 1;
        grid-row: 2;
        align-self: start;
        margin: 0;
    }
    .bio-policy--editorial .bio-policy-feature--quoted:nth-child(even) .bio-pullquote--inline {
        grid-column: 2;
    }
    /* n5, Matt 2026-09-02: "make this slightly smaller font". One step down
       from the n4 size -- 32px to 28px at 1920 -- which is enough to pull the
       quote off the photograph's baseline without dropping it to body size.
       It is still the page's single pull-quote (gate W7) and still the largest
       type in the section. */
    .bio-policy--editorial .bio-policy-feature--quoted .bio-pullquote--inline p {
        font-size: clamp(21px, 1.5vw, 28px);
    }
}
