/* /Components/ApplicationIntelligence/CampaignDecisionReadoutCard.razor.rz.scp.css */
.campaign-readout[b-u188yozj29] {
    --cr-ink: #f7f4ed;
    --cr-muted: #a9b1b4;
    --cr-line: rgba(255, 255, 255, 0.12);
    --cr-teal: #56d7c8;
    --cr-amber: #f5bd5b;
    --cr-coral: #ff7d68;
    display: grid;
    gap: 16px;
    margin: 16px 0;
    border: 1px solid #202b30;
    border-radius: 12px;
    background:
        linear-gradient(135deg, rgba(86, 215, 200, 0.08), transparent 30%),
        #11191d;
    color: var(--cr-ink);
    padding: 18px;
    box-shadow: 0 16px 34px rgba(15, 24, 28, 0.16);
}

.campaign-readout__header[b-u188yozj29],
.campaign-readout__section-title[b-u188yozj29],
.campaign-readout__footer[b-u188yozj29] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
}

.campaign-readout__header > div[b-u188yozj29] {
    display: grid;
    gap: 4px;
}

.campaign-readout__eyebrow[b-u188yozj29],
.campaign-readout__freshness[b-u188yozj29],
.campaign-readout__decision-row span[b-u188yozj29],
.campaign-readout__section-title > span:first-child[b-u188yozj29],
.campaign-readout__latest span[b-u188yozj29],
.campaign-readout__footer[b-u188yozj29] {
    color: var(--cr-muted);
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Consolas, monospace);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.campaign-readout__eyebrow[b-u188yozj29] {
    color: var(--cr-teal);
}

.campaign-readout__header h3[b-u188yozj29],
.campaign-readout__header p[b-u188yozj29],
.campaign-readout__signal p[b-u188yozj29] {
    margin: 0;
}

.campaign-readout__header h3[b-u188yozj29] {
    font-size: 1.15rem;
}

.campaign-readout__header p[b-u188yozj29] {
    color: var(--cr-muted);
    font-size: 0.86rem;
}

.campaign-readout__freshness[b-u188yozj29] {
    border: 1px solid var(--cr-line);
    border-radius: 999px;
    padding: 5px 8px;
    white-space: nowrap;
}

.campaign-readout__decision-row[b-u188yozj29] {
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 0.8fr) minmax(0, 1.4fr);
    border-block: 1px solid var(--cr-line);
}

.campaign-readout__decision-row article[b-u188yozj29] {
    display: grid;
    align-content: start;
    gap: 7px;
    min-width: 0;
    padding: 14px;
    border-right: 1px solid var(--cr-line);
}

.campaign-readout__decision-row article:first-child[b-u188yozj29] {
    padding-left: 0;
}

.campaign-readout__decision-row article:last-child[b-u188yozj29] {
    border-right: 0;
    padding-right: 0;
}

.campaign-readout__decision-row strong[b-u188yozj29] {
    font-size: 0.98rem;
    line-height: 1.3;
}

.campaign-readout__decision-row small[b-u188yozj29] {
    color: var(--cr-teal);
    font-size: 0.75rem;
}

.campaign-readout__value--go[b-u188yozj29] {
    color: var(--cr-teal);
}

.campaign-readout__value--watch[b-u188yozj29] {
    color: var(--cr-amber);
}

.campaign-readout__value--stop[b-u188yozj29] {
    color: var(--cr-coral);
}

.campaign-readout__body[b-u188yozj29] {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    gap: 12px;
}

.campaign-readout__body > article[b-u188yozj29] {
    min-width: 0;
    border: 1px solid var(--cr-line);
    border-radius: 9px;
    background: rgba(255, 255, 255, 0.025);
    padding: 14px;
}

.campaign-readout__section-title[b-u188yozj29] {
    align-items: center;
    margin-bottom: 12px;
}

.campaign-readout__section-title small[b-u188yozj29] {
    color: var(--cr-muted);
    font-size: 0.68rem;
}

.campaign-readout__coverage[b-u188yozj29] {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 6px;
    margin: 0 0 12px;
}

.campaign-readout__coverage div[b-u188yozj29] {
    display: grid;
    gap: 3px;
    border-left: 2px solid var(--cr-line);
    padding-left: 8px;
}

.campaign-readout__coverage dt[b-u188yozj29] {
    color: var(--cr-muted);
    font-size: 0.68rem;
}

.campaign-readout__coverage dd[b-u188yozj29] {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.campaign-readout__stakeholders[b-u188yozj29] {
    display: grid;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.campaign-readout__stakeholders li[b-u188yozj29] {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr);
    gap: 9px;
    align-items: center;
}

.campaign-readout__stakeholders li > span:last-child[b-u188yozj29] {
    display: grid;
    min-width: 0;
    gap: 2px;
}

.campaign-readout__stakeholders strong[b-u188yozj29] {
    overflow: hidden;
    font-size: 0.79rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.campaign-readout__stakeholders small[b-u188yozj29] {
    overflow: hidden;
    color: var(--cr-muted);
    font-size: 0.68rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.campaign-readout__avatar[b-u188yozj29] {
    display: grid;
    width: 28px;
    height: 28px;
    place-items: center;
    border: 1px solid rgba(86, 215, 200, 0.35);
    border-radius: 50%;
    background: rgba(86, 215, 200, 0.09);
    color: var(--cr-teal);
    font-size: 0.66rem;
    font-weight: 800;
}

.campaign-readout__empty[b-u188yozj29] {
    margin: 0;
    color: var(--cr-muted);
    font-size: 0.78rem;
}

.campaign-readout__signal[b-u188yozj29] {
    display: flex;
    flex-direction: column;
}

.campaign-readout__signal > strong[b-u188yozj29] {
    margin-bottom: 7px;
    font-size: 1rem;
    line-height: 1.3;
}

.campaign-readout__signal > p[b-u188yozj29] {
    color: var(--cr-muted);
    font-size: 0.8rem;
    line-height: 1.5;
}

.campaign-readout__signal-badge[b-u188yozj29] {
    border-radius: 999px;
    padding: 4px 7px;
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Consolas, monospace);
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.06em;
}

.campaign-readout__signal-badge--go[b-u188yozj29] {
    background: rgba(86, 215, 200, 0.12);
    color: var(--cr-teal);
}

.campaign-readout__signal-badge--watch[b-u188yozj29] {
    background: rgba(245, 189, 91, 0.12);
    color: var(--cr-amber);
}

.campaign-readout__signal-badge--stop[b-u188yozj29] {
    background: rgba(255, 125, 104, 0.12);
    color: var(--cr-coral);
}

.campaign-readout__latest[b-u188yozj29] {
    display: grid;
    gap: 4px;
    margin-top: auto;
    border-top: 1px solid var(--cr-line);
    padding-top: 12px;
}

.campaign-readout__latest strong[b-u188yozj29] {
    overflow: hidden;
    font-size: 0.75rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.campaign-readout__footer[b-u188yozj29] {
    align-items: center;
    border-top: 1px solid var(--cr-line);
    padding-top: 13px;
    font-size: 0.62rem;
    line-height: 1.45;
    text-transform: none;
}

.campaign-readout__footer span:last-child[b-u188yozj29] {
    color: var(--cr-amber);
    text-align: right;
}

@media (max-width: 860px) {
    .campaign-readout__decision-row[b-u188yozj29],
    .campaign-readout__body[b-u188yozj29] {
        grid-template-columns: 1fr;
    }

    .campaign-readout__decision-row article[b-u188yozj29],
    .campaign-readout__decision-row article:first-child[b-u188yozj29],
    .campaign-readout__decision-row article:last-child[b-u188yozj29] {
        border-right: 0;
        border-bottom: 1px solid var(--cr-line);
        padding: 12px 0;
    }

    .campaign-readout__decision-row article:last-child[b-u188yozj29] {
        border-bottom: 0;
    }
}

@media (max-width: 540px) {
    .campaign-readout[b-u188yozj29] {
        padding: 14px;
    }

    .campaign-readout__header[b-u188yozj29],
    .campaign-readout__footer[b-u188yozj29] {
        align-items: flex-start;
        flex-direction: column;
    }

    .campaign-readout__freshness[b-u188yozj29] {
        white-space: normal;
    }

    .campaign-readout__coverage[b-u188yozj29] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        row-gap: 10px;
    }

    .campaign-readout__footer span:last-child[b-u188yozj29] {
        text-align: left;
    }
}

/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* /Components/Layout/PublicLayout.razor.rz.scp.css */
/* V9 Koso grid header — paper base, hairline rules, mono nav.
   Style contract lives with the page: see PublicHome.razor.css. */
.public-shell[b-rsen19rep5] {
    --ink: #23262b;
    --muted: #596662;
    --paper: #f6f4ef;
    --surface: #fffdf8;
    --line: rgba(35, 38, 43, 0.14);
    --brick: #d97757;
    --brick-deep: #b2503f;
    --teal-deep: #0f746c;
    --mono: "JetBrains Mono", Consolas, monospace;
    --shadow: 0 24px 60px -12px rgba(31, 29, 26, 0.16);
    min-height: 100vh;
    background: var(--paper);
    color: var(--ink);
    font-family: Inter, "Noto Sans TC", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

/* Fixed two-row shell: row 1 = brand + language + send-JD CTA,
   row 2 = the three-view route bar (semantic links, aria-current marks active). */
.public-nav[b-rsen19rep5] {
    position: sticky;
    top: 0;
    z-index: 50;
    border-bottom: 1px solid var(--line);
    background: color-mix(in srgb, var(--paper) 86%, transparent);
    backdrop-filter: blur(10px);
}

.public-nav-top[b-rsen19rep5] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 26px;
    min-height: 48px;
    padding: 12px clamp(18px, 4vw, 56px) 10px;
}

.public-viewbar[b-rsen19rep5] {
    position: relative;
    display: flex;
    align-items: stretch;
    justify-content: center;
    gap: clamp(26px, 4vw, 52px);
    padding: 0 clamp(18px, 4vw, 56px);
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-family: var(--mono);
    font-size: 0.84rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
}

.public-viewbar a[b-rsen19rep5] {
    display: inline-flex;
    align-items: center;
    padding: 13px 2px 11px;
    border-bottom: 3px solid transparent;
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
}

/* Nav icons share the hero glyph grammar — hand-drawn line SVGs on
   currentColor, so hover/active color shifts carry the icon with the label. */
.public-viewbar a .nav-ic[b-rsen19rep5] {
    width: 15px;
    height: 15px;
    flex: none;
    margin-right: 8px;
    opacity: .82;
}

.public-viewbar a[aria-current="page"] .nav-ic[b-rsen19rep5],
.public-viewbar a:hover .nav-ic[b-rsen19rep5] {
    opacity: 1;
}

.public-viewbar a:hover[b-rsen19rep5],
.public-viewbar a:focus[b-rsen19rep5] {
    color: var(--ink);
    text-decoration: none;
}

.public-viewbar a:focus-visible[b-rsen19rep5] {
    outline: 2px solid var(--brick-deep);
    outline-offset: -2px;
}

.public-viewbar a[aria-current="page"][b-rsen19rep5] {
    color: var(--ink);
    font-weight: 760;
    border-bottom-color: var(--brick);
}

/* All three views sit in the one centered row (2026-08-05, Johanna).
   This reverses the 2026-08-02 rule that pinned System & data to the right
   edge on wide screens. Do not restore it: that rule's own reason was "the
   technical annex, while Home and *the AI-method view* stay centered", and
   /ai-method left the nav under GATE-01 with Skill Roster taking the middle
   slot. The split it described — two narrative views against one annex — has
   been the other way round ever since, since Skill Roster is evidence too.
   What the pin actually produced, measured at 1440 before it was removed: a
   52px gap between the first two links and a 379px gap before the third, and
   a right edge landing on exactly the same pixel as the Send-a-JD button
   above it (1369). That put a content view inside the header's actions
   column, where a reader expects utilities rather than the third tab, and it
   stranded the active-page underline at the far edge. */

.public-brand[b-rsen19rep5] {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    color: var(--ink);
    font-weight: 760;
    text-decoration: none;
}

.public-brand span:last-child[b-rsen19rep5] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.public-brand-mark[b-rsen19rep5] {
    display: inline-block;
    width: 24px;
    height: 24px;
    object-fit: contain;
    flex: 0 0 auto;
}

.public-private-link[b-rsen19rep5] {
    border: 1px solid rgba(224, 83, 60, 0.28);
    background: rgba(255, 255, 255, 0.58);
    color: var(--brick-deep) !important;
    font-weight: 760;
}

.public-actions[b-rsen19rep5] {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    flex: 0 0 auto;
}

/* The deep brick is the resting state, not the hover one: white on the lighter
   orange measured 3.1:1, which this label — uppercase, 0.72rem, wide tracking
   — cannot afford. Hover and press step darker still, so the whole ramp reads
   as one control rather than two colors. */
.public-cta[b-rsen19rep5] {
    display: inline-flex;
    align-items: center;
    border: 0;
    border-radius: 0;
    background: var(--brick-deep);
    padding: 10px 16px;
    color: #fff !important;
    font-family: var(--mono);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
}

.public-cta:hover[b-rsen19rep5] {
    background: #8f3f32;
}

.public-cta:active[b-rsen19rep5] {
    background: #7a3529;
}

.public-cta:focus-visible[b-rsen19rep5] {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
}

/* Globe language toggle — one quiet control showing the language it switches
   TO; the culture cookie stays the source of truth. No filled active state:
   the orange CTA must be the only strong element in this row. */
.website-lang[b-rsen19rep5] {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 7px;
    /* borderless, but padded to the CTA's height so the two header controls
       sit on one optical line and the toggle keeps a usable tap target */
    padding: 10px;
    color: var(--muted);
    font-family: var(--mono);
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    line-height: 1.4;
    text-decoration: none;
    white-space: nowrap;
}

.website-lang:hover[b-rsen19rep5] {
    color: var(--ink);
}

.website-lang-ic[b-rsen19rep5] {
    width: 15px;
    height: 15px;
}

.website-lang:focus-visible[b-rsen19rep5] {
    outline: 2px solid var(--teal-deep);
    outline-offset: -2px;
}

/* Quiet identity links beside the brand — language-toggle weight, never CTA
   weight. Hidden below the desktop breakpoint: on small screens the header
   budget belongs to brand + CTA, and the footer already carries these. */
.public-id-links[b-rsen19rep5] {
    display: flex;
    align-items: center;
    gap: 18px;
    margin-left: 26px;
    margin-right: auto;
}

.public-id-links a[b-rsen19rep5] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--muted);
    font-family: var(--mono);
    font-size: 0.66rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    padding: 10px 0;
}

.public-id-links .id-ic[b-rsen19rep5] {
    width: 13px;
    height: 13px;
    flex: 0 0 auto;
}

.public-id-links a:hover[b-rsen19rep5] {
    color: var(--ink);
}

.public-id-links a:focus-visible[b-rsen19rep5] {
    outline: 2px solid var(--teal-deep);
    outline-offset: -2px;
}

@media (max-width: 979px) {
    .public-id-links[b-rsen19rep5] {
        display: none;
    }
}
.public-backtop[b-rsen19rep5] {
    position: fixed;
    right: 22px;
    bottom: 22px;
    z-index: 40;
    width: 44px;
    height: 44px;
    border: 1px solid rgba(31, 29, 26, 0.16);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.92);
    color: var(--brick-deep);
    font-size: 17px;
    font-weight: 800;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 10px 28px -8px rgba(31, 29, 26, 0.28);
    opacity: 0;
    pointer-events: none;
    transform: translateY(8px);
}

@supports (animation-timeline: scroll()) {
    .public-backtop[b-rsen19rep5] {
        animation: public-backtop-reveal-b-rsen19rep5 linear both;
        animation-timeline: scroll(root);
        animation-range: 420px 700px;
    }
}

@keyframes public-backtop-reveal-b-rsen19rep5 {
    to {
        opacity: 1;
        pointer-events: auto;
        transform: translateY(0);
    }
}

.public-backtop:hover[b-rsen19rep5],
.public-backtop:focus[b-rsen19rep5] {
    border-color: rgba(224, 83, 60, 0.55);
    background: rgba(224, 83, 60, 0.08);
}

.public-backtop:focus-visible[b-rsen19rep5] {
    outline: 2px solid var(--brick-deep);
    outline-offset: 2px;
}

@media (max-width: 720px) {
    .public-backtop[b-rsen19rep5] {
        right: 14px;
        bottom: 14px;
        width: 40px;
        height: 40px;
    }

    .public-nav-top[b-rsen19rep5] {
        gap: 8px;
        padding: 10px 14px 8px;
    }

    /* The view bar is the only row allowed to overflow horizontally.
       flex-start on mobile: centering + overflow clips the left edge.

       2026-08-04: the hidden scrollbar left the row with no sign that it
       continues — measured 39px out of reach at 375px in English (zh fits
       exactly, its glyphs are narrower). The trailing fade is that sign.
       The right padding must stay >= --viewbar-fade: it parks an empty
       strip under the fade at full scroll, so the last label arrives crisp
       instead of dimmed. Keep the two tied together. */
    .public-viewbar[b-rsen19rep5] {
        --viewbar-fade: 22px;
        justify-content: flex-start;
        padding: 0 calc(14px + var(--viewbar-fade)) 0 14px;
        font-size: 0.78rem;
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--viewbar-fade)), transparent);
        mask-image: linear-gradient(to right, #000 calc(100% - var(--viewbar-fade)), transparent);
    }

    .public-viewbar[b-rsen19rep5]::-webkit-scrollbar {
        display: none;
    }

    .public-actions[b-rsen19rep5] {
        justify-content: flex-end;
        flex-wrap: nowrap;
    }

    .public-brand span:last-child[b-rsen19rep5] {
        white-space: nowrap;
    }

}

@media (max-width: 420px) {
    .public-actions[b-rsen19rep5] {
        align-items: center;
        gap: 6px;
    }

    .public-cta[b-rsen19rep5] {
        flex: 0 0 auto;
        justify-content: center;
        padding: 8px 10px;
        font-size: 0.62rem;
        letter-spacing: 0.08em;
    }

    .website-lang[b-rsen19rep5] {
        padding: 8px 9px;
        font-size: 0.64rem;
    }
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-g0ure6qukp],
.components-reconnect-repeated-attempt-visible[b-g0ure6qukp],
.components-reconnect-failed-visible[b-g0ure6qukp],
.components-pause-visible[b-g0ure6qukp],
.components-resume-failed-visible[b-g0ure6qukp],
.components-rejoining-animation[b-g0ure6qukp] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-g0ure6qukp],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-g0ure6qukp],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-g0ure6qukp],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-g0ure6qukp],
#components-reconnect-modal.components-reconnect-retrying[b-g0ure6qukp],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-g0ure6qukp],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-g0ure6qukp],
#components-reconnect-modal.components-reconnect-failed[b-g0ure6qukp],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-g0ure6qukp] {
    display: block;
}


#components-reconnect-modal[b-g0ure6qukp] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-g0ure6qukp 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-g0ure6qukp 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-g0ure6qukp 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-g0ure6qukp]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-g0ure6qukp 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-g0ure6qukp {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-g0ure6qukp {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-g0ure6qukp {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-g0ure6qukp] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-g0ure6qukp] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-g0ure6qukp] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-g0ure6qukp] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-g0ure6qukp] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-g0ure6qukp] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-g0ure6qukp] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-g0ure6qukp 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-g0ure6qukp] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-g0ure6qukp {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Pages/Login.razor.rz.scp.css */
/* /login — paper-token card on the Telerik Login-1 skeleton. Scoped CSS cannot
   be shared across components, so the token block is duplicated deliberately;
   keep values in sync with PublicHome.razor.css and the other public views. */
.login-viewport[b-rxl0xhk2hr] {
  color-scheme: light;
  --paper: #f6f4ef;
  --panel: #fffdf8;
  --ink: #23262b;
  --ink-soft: #41474b;
  --mut: #596662;
  --line: rgba(35, 38, 43, .14);
  --line-soft: rgba(35, 38, 43, .08);
  --teal: #4fd1c5;
  --teal-deep: #0f746c;
  --coral-deep: #b2503f;
  --cta: #d97757;
  --serif: Georgia, "Times New Roman", serif;
  --sans: "Inter", "Noto Sans TC", "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", Consolas, monospace;

  min-height: 100dvh;
  display: grid;
  place-items: center;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  /* Mobile gutter: the card never touches the viewport edge. */
  padding: 24px 16px;
  box-sizing: border-box;
}

.login-viewport *[b-rxl0xhk2hr],
.login-viewport *[b-rxl0xhk2hr]::before,
.login-viewport *[b-rxl0xhk2hr]::after {
  box-sizing: border-box;
}

.login-card[b-rxl0xhk2hr] {
  width: 100%;
  max-width: 458px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(35, 38, 43, .08);
  padding: 40px 36px 28px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.login-logo[b-rxl0xhk2hr] {
  width: 44px;
  height: 44px;
  align-self: center;
}

.login-heading[b-rxl0xhk2hr] {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.45rem;
  font-weight: 600;
  text-align: center;
  letter-spacing: .01em;
}

.login-error[b-rxl0xhk2hr] {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid rgba(178, 80, 63, .35);
  border-radius: 8px;
  background: rgba(217, 119, 87, .10);
  color: var(--coral-deep);
  font-size: .92rem;
  line-height: 1.45;
}

.login-error:focus-visible[b-rxl0xhk2hr] {
  outline: 2px solid var(--coral-deep);
  outline-offset: 2px;
}

.login-form[b-rxl0xhk2hr] {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.login-field[b-rxl0xhk2hr] {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.login-label[b-rxl0xhk2hr] {
  font-size: .88rem;
  font-weight: 600;
  color: var(--ink-soft);
}

.login-viewport[b-rxl0xhk2hr]  .login-input {
  width: 100%;
}

.login-remember[b-rxl0xhk2hr] {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: .92rem;
  color: var(--ink-soft);
  cursor: pointer;
  user-select: none;
}

.login-viewport[b-rxl0xhk2hr]  .login-submit {
  width: 100%;
}

.login-langs[b-rxl0xhk2hr] {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: .82rem;
  color: var(--mut);
}

.login-lang[b-rxl0xhk2hr] {
  color: var(--mut);
  text-decoration: none;
  padding: 6px 4px; /* comfortable touch target */
}

.login-lang.is-active[b-rxl0xhk2hr] {
  color: var(--teal-deep);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.login-lang:hover[b-rxl0xhk2hr],
.login-lang:focus-visible[b-rxl0xhk2hr] {
  color: var(--ink);
}

@media (max-width: 420px) {
  .login-card[b-rxl0xhk2hr] {
    padding: 28px 20px 22px;
  }
}
/* /Components/Pages/PublicChangelog.razor.rz.scp.css */
/* /changelog — plain-language product changelog, drawn in the shared V9
   paper/hairline vocabulary. Scoped CSS cannot be shared across components,
   so the token block is duplicated deliberately; keep values in sync with
   PublicHome.razor.css, PublicSkills.razor.css, PublicAiMethod.razor.css and
   PublicSystemData.razor.css. */
.ppv[b-cml58ap23j] {
  color-scheme: light;
  --paper: #f6f4ef;
  --panel: #fffdf8;
  --ink: #23262b;
  --ink-soft: #41474b;
  --mut: #596662;
  --dim: #65726e;
  --line: rgba(35, 38, 43, .14);
  --line-soft: rgba(35, 38, 43, .08);
  --teal: #4fd1c5;
  --teal-deep: #0f746c;
  --amber-deep: #8a5f00;
  --coral-deep: #b2503f;
  --cta: #d97757;
  --serif: Georgia, "Times New Roman", serif;
  --sans: "Inter", "Noto Sans TC", "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", Consolas, monospace;

  display: block;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
}
.ppv *[b-cml58ap23j],
.ppv *[b-cml58ap23j]::before,
.ppv *[b-cml58ap23j]::after { box-sizing: border-box; }
.ppv [b-cml58ap23j]::selection { background: rgba(79, 209, 197, .3); }
.ppv a[b-cml58ap23j] { color: inherit; }
:where(.ppv) :where(h1, h2, h3, p, ol, ul)[b-cml58ap23j] { margin: 0; padding: 0; }

.ppv-wrap[b-cml58ap23j] {
  max-width: 1360px;
  margin: 0 auto;
  border-inline: 1px solid var(--line);
  padding-inline: clamp(20px, 3.4vw, 48px);
}
.ppv-sec[b-cml58ap23j] { border-bottom: 1px solid var(--line); }

/* One column for the page (2026-08-11). Measured before this: four different
   right edges stacked down the page — the proof band capped at 560px, the
   scope prose at 62ch/418px, the entry paragraph at 84ch/686px, and every
   rule (timeline head, window heading, entry divider) running the full
   1263px measure. Nothing lined up with anything, and the band read as a
   small orphaned box sitting beside full-bleed rules.
   720px is chosen from the text rather than the frame: after the 148px date
   rail it leaves the entry paragraph at ~68ch, which is a reading measure,
   and titles at ~65ch. A changelog is a document — 40 paragraphs — so the
   1263px measure it inherited was never right for the content.
   The 1360px .ppv-wrap rails stay — they are the site frame shared with the
   sibling views — and the column is centred inside them. Left-aligning it is
   what the home page does with its 62ch leads, but that page has full-width
   bands filling the frame around them; here nothing else fills it, so a
   left-aligned column left the whole page hugging one rail with ~500px of
   dead space beside it. Centred, the frame closes and the page reads as the
   document it is. */
.cl-lead[b-cml58ap23j],
.cl-timeline[b-cml58ap23j] {
  max-width: 720px;
  margin-inline: auto;
}

/* ===== lead ===== */
.cl-lead[b-cml58ap23j] { padding-block: clamp(26px, 4vw, 44px) 8px; }
.cl-h1[b-cml58ap23j] {
  margin-bottom: 10px;
  font-family: var(--serif);
  font-size: clamp(1.5rem, 2.6vw, 2.05rem);
  line-height: 1.25;
  letter-spacing: -.014em;
  color: var(--ink);
}
/* The artifact is named in an eyebrow, not a sentence: it is the subject of
   every figure below, and a label carries that faster than prose. Teal is the
   site's system/proof voice (stat figures, method kickers), so the product
   name arrives in the same register as the evidence it introduces. */
.cl-eyebrow[b-cml58ap23j] {
  margin-bottom: 9px;
  font-family: var(--mono);
  font-size: .64rem;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--teal-deep);
}
/* Header proof band (2026-08-11 owner layout): two figures paired on one row,
   the date on its own full-width row beneath them — the strongest evidence
   gets the widest line. Home page's proof-strip grammar (hairline grid, big
   mono figure over a mono kicker) so the two bands read as one site.
   It spans the column, like every other block on the page. Its own 560px cap
   was what made it read as an orphan against the full-width rules; the fix
   was narrowing the page to the text, not narrowing the band further.
   One row of three, not two-plus-one: measured at 720px, the full-width date
   row held 210px of ink in a 718px cell — 508px of empty panel. A wide empty
   cell is not emphasis, it is a gap; the date carries its weight by being
   twelve specific characters, not by owning a line. Three equal cells also
   match the home page's stat strip, which is where this grammar comes from. */
.cl-proof[b-cml58ap23j] {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin-top: 18px;
  border: 1px solid var(--line);
  background: var(--line);
}
/* Column layout so the kickers can be pushed to the cells' shared bottom
   edge: the date's figure is necessarily smaller than the two integers, so
   aligning the labels from the top would step them down a line. Grid already
   stretches the three cells to equal height, which is what makes this land. */
.cl-proof-cell[b-cml58ap23j] {
  display: flex;
  flex-direction: column;
  background: var(--panel);
  padding: 14px clamp(12px, 1.6vw, 18px) 15px;
}
.cl-proof-n[b-cml58ap23j] {
  display: block;
  font-family: var(--mono);
  font-weight: 600;
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  line-height: 1.05;
  letter-spacing: -.04em;
  color: var(--teal-deep);
}
/* The date is a figure too, but twelve characters of it — sized to sit inside
   a third of the band rather than to match the integers' cap height. Twelve
   characters already carry more visual mass than one digit. */
.cl-proof-date[b-cml58ap23j] {
  font-size: clamp(.98rem, 1.35vw, 1.2rem);
  letter-spacing: -.015em;
}
/* Pushed to the bottom of the cell rather than spaced from the figure above,
   so all three labels sit on one line whatever their figures' sizes. */
.cl-proof-k[b-cml58ap23j] {
  display: block;
  margin-top: auto;
  padding-top: 10px;
  font-family: var(--mono);
  font-size: .62rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--mut);
  line-height: 1.45;
}

/* The five areas as the same chips the entries carry — the header's claim and
   the record's vocabulary are literally the same objects, so "areas improved"
   is checkable rather than asserted. */
.cl-areas[b-cml58ap23j] { margin-top: 18px; }
.cl-areas-k[b-cml58ap23j] {
  margin-bottom: 8px;
  font-family: var(--mono);
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink);
}
.cl-areas-list[b-cml58ap23j] { display: flex; flex-wrap: wrap; gap: 6px; }

/* ===== timeline ===== */
.cl-timeline[b-cml58ap23j] { padding-block: 10px clamp(30px, 4vw, 48px); }

/* The entry total lives here now, as a section rule rather than a headline
   figure: "40" as a big number read as a closed total or an output metric,
   while the same number labelling the records below reads as what it is. */
.cl-timeline-head[b-cml58ap23j] {
  margin-top: clamp(20px, 2.6vw, 30px);
  padding-block: 12px 13px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.cl-timeline-k[b-cml58ap23j] {
  font-family: var(--mono);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink);
}
.cl-timeline-n[b-cml58ap23j] {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: .64rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mut);
}
/* The admission bar, inside the rule block so the closing rule stays flush
   against the first record. Prose weight, deliberately below the two mono
   labels above it: it is a definition, not a headline.
   No measure cap: at .76rem/62ch it stopped 167px short of the rules boxing
   it in, which is the same ragged-edge defect the single column was meant to
   end. Sized instead so the column itself is the measure — two lines in
   English, one in Chinese. */
.cl-timeline-scope[b-cml58ap23j] {
  margin-top: 9px;
  font-size: .88rem;
  line-height: 1.55;
  color: var(--mut);
}
.cl-window[b-cml58ap23j] { padding-block: 18px 6px; }
.cl-window + .cl-window[b-cml58ap23j] { border-top: 1px solid var(--line-soft); }
.cl-window-h[b-cml58ap23j] {
  margin-bottom: 12px;
  font-family: var(--mono);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--coral-deep);
}
.cl-entries[b-cml58ap23j] { list-style: none; }
.cl-entry[b-cml58ap23j] {
  display: grid;
  grid-template-columns: 148px 1fr;
  gap: 6px 20px;
  padding-block: 16px;
}
.cl-entry + .cl-entry[b-cml58ap23j] { border-top: 1px solid var(--line-soft); }
.cl-meta[b-cml58ap23j] {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-start;
  padding-top: .3em;
}
.cl-date[b-cml58ap23j] {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .06em;
  color: var(--dim);
  white-space: nowrap;
}
/* display-only tag chip — five fixed labels, muted so the title stays lead */
.cl-tag[b-cml58ap23j] {
  font-family: var(--mono);
  font-size: .56rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mut);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
}
/* era divider before the compressed early milestones */
.cl-era[b-cml58ap23j] {
  margin-top: 26px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: .62rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--dim);
}
/* text-wrap: pretty, not balance. Balance equalises the lines by pulling them
   in, which on titles this long left them up to 267px short of the measure —
   a ragged left-of-centre block against the full-width rules around it, and
   the single biggest source of the page's uneven right edge. Pretty keeps the
   orphan control without shortening the lines. */
.cl-title[b-cml58ap23j] {
  font-family: var(--serif);
  font-size: 1.06rem;
  line-height: 1.35;
  letter-spacing: -.008em;
  color: var(--ink);
  margin-bottom: 7px;
  text-wrap: pretty;
}
/* No measure cap of its own: the column already holds the paragraph at ~68ch,
   and its old 84ch cap was what left the note ending 400px short of the title
   above it — two right edges inside a single entry. */
.cl-note[b-cml58ap23j] {
  font-size: .92rem;
  line-height: 1.68;
  color: var(--mut);
  text-wrap: pretty;
}

/* mobile: date + tag stack above the title on one row */
@media (max-width: 640px) {
  .cl-entry[b-cml58ap23j] { grid-template-columns: 1fr; gap: 4px; }
  .cl-meta[b-cml58ap23j] { flex-direction: row; align-items: center; gap: 10px; padding-top: 0; }

  /* The band falls back to two-plus-one here: a third of a phone column is
     ~116px, and the date needs ~140px of ink in either language. */
  .cl-proof[b-cml58ap23j] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cl-proof-latest[b-cml58ap23j] { grid-column: 1 / -1; }
  .cl-proof-latest .cl-proof-k[b-cml58ap23j] { padding-top: 6px; }
}

/* ===== footer (shared vocabulary with the other public views) ===== */
.ppv-foot[b-cml58ap23j] { border-bottom: 0; }
.foot-bar[b-cml58ap23j] {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  align-items: center;
  justify-content: space-between;
  padding-block: 20px 26px;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mut);
}
.foot-bar a[b-cml58ap23j] { text-decoration: none; color: var(--mut); }
.foot-bar a:hover[b-cml58ap23j] { color: var(--ink); }
.foot-links[b-cml58ap23j] { display: flex; gap: 22px; }
.foot-privacy[b-cml58ap23j] {
  margin-top: -8px;
  font-family: var(--mono);
  font-size: .56rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
  line-height: 1.8;
}
.foot-fresh[b-cml58ap23j] {
  padding-bottom: 24px;
  padding-top: 6px;
  font-family: var(--mono);
  font-size: .56rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1.8;
}
.foot-fresh a[b-cml58ap23j] { text-decoration: none; color: var(--dim); }
.foot-fresh a:hover[b-cml58ap23j] { color: var(--ink); }
/* /Components/Pages/PublicFieldNote01.razor.rz.scp.css */
.field-note-page[b-8lnfz44deh] {
    min-height: 100vh;
    padding: clamp(42px, 8vw, 92px) clamp(18px, 5vw, 48px) 96px;
    background: #fafaf6;
    color: #131318;
}

.field-note-page > *[b-8lnfz44deh] {
    width: min(100%, 860px);
    margin-inline: auto;
}

.back-link[b-8lnfz44deh] {
    display: inline-flex;
    margin-bottom: 32px;
    color: #16309f;
    font-weight: 750;
    text-decoration: none;
}

.note-hero[b-8lnfz44deh] {
    padding-bottom: 32px;
    border-bottom: 1px solid #e4e4dc;
}

.note-meta[b-8lnfz44deh] {
    color: #1d40d8;
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
    font-size: 0.78rem;
    font-weight: 750;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

h1[b-8lnfz44deh],
h2[b-8lnfz44deh] {
    font-family: "Source Serif 4", Georgia, "Times New Roman", serif;
}

h1[b-8lnfz44deh] {
    max-width: 760px;
    margin: 16px 0;
    font-size: clamp(2.5rem, 7vw, 5.4rem);
    line-height: 0.98;
    letter-spacing: -0.04em;
}

.note-lede[b-8lnfz44deh] {
    max-width: 720px;
    color: #3e3e46;
    font-size: clamp(1.05rem, 2vw, 1.25rem);
    line-height: 1.75;
}

section[b-8lnfz44deh] {
    padding: 30px 0;
    border-bottom: 1px solid #e4e4dc;
}

h2[b-8lnfz44deh] {
    margin: 0 0 14px;
    font-size: clamp(1.45rem, 3vw, 2rem);
}

p[b-8lnfz44deh],
li[b-8lnfz44deh],
td[b-8lnfz44deh],
th[b-8lnfz44deh] {
    line-height: 1.8;
}

.table-wrap[b-8lnfz44deh] {
    overflow-x: auto;
    margin: 20px 0;
}

table[b-8lnfz44deh] {
    width: 100%;
    border-collapse: collapse;
    background: #fff;
}

th[b-8lnfz44deh],
td[b-8lnfz44deh] {
    min-width: 180px;
    border: 1px solid #e4e4dc;
    padding: 14px 16px;
    text-align: left;
    vertical-align: top;
}

th[b-8lnfz44deh] {
    background: #e9edfc;
}

.decision-list[b-8lnfz44deh] {
    display: grid;
    gap: 16px;
    padding-left: 1.4rem;
}

code[b-8lnfz44deh],
pre[b-8lnfz44deh] {
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
}

code[b-8lnfz44deh] {
    border-radius: 4px;
    background: #e9edfc;
    padding: 0.12em 0.36em;
    color: #16309f;
}

pre[b-8lnfz44deh] {
    overflow-x: auto;
    border-radius: 14px;
    background: #161f30;
    padding: 20px;
    color: #f5f4ef;
    font-size: 0.86rem;
    line-height: 1.7;
}

.closing-callout[b-8lnfz44deh] {
    margin-top: 34px;
    border-left: 5px solid #f4744c;
    background: #fff;
    padding: 24px;
    box-shadow: 0 16px 40px rgba(19, 19, 24, 0.07);
}

.closing-callout strong[b-8lnfz44deh] {
    font-family: "Source Serif 4", Georgia, serif;
    font-size: 1.3rem;
}

.closing-callout p[b-8lnfz44deh] {
    margin: 10px 0 0;
}

.note-endnav[b-8lnfz44deh] {
    margin-top: 44px;
}

.endnav-next[b-8lnfz44deh] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 10px 14px;
    border: 1px solid #e4e4dc;
    background: #fff;
    padding: 20px 22px;
    color: #131318;
    text-decoration: none;
    box-shadow: 0 16px 40px rgba(19, 19, 24, 0.05);
}

.endnav-next:hover[b-8lnfz44deh] {
    border-color: #1d40d8;
}

.endnav-kicker[b-8lnfz44deh] {
    color: #1d40d8;
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
    font-size: 0.72rem;
    font-weight: 750;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.endnav-title[b-8lnfz44deh] {
    font-family: "Source Serif 4", Georgia, serif;
    font-size: 1.12rem;
    font-weight: 700;
}

.endnav-arrow[b-8lnfz44deh] {
    margin-left: auto;
    color: #1d40d8;
    font-weight: 800;
}

.endnav-row[b-8lnfz44deh] {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px 14px;
    margin-top: 16px;
}

.endnav-row a[b-8lnfz44deh] {
    color: #16309f;
    font-weight: 750;
    text-decoration: none;
}

.endnav-top[b-8lnfz44deh] {
    border: 0;
    background: none;
    padding: 0;
    color: #16309f;
    cursor: pointer;
    font: inherit;
    font-weight: 750;
}

.endnav-row a:hover[b-8lnfz44deh],
.endnav-top:hover[b-8lnfz44deh] {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.endnav-profile[b-8lnfz44deh] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 14px;
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid #e4e4dc;
    color: #73737d;
    font-size: 0.85rem;
}

.endnav-profile span[b-8lnfz44deh] { color: #131318; font-weight: 750; }
.endnav-profile a[b-8lnfz44deh] { color: #16309f; font-weight: 700; text-decoration: none; }
.endnav-profile a:hover[b-8lnfz44deh] { text-decoration: underline; text-underline-offset: 3px; }
/* /Components/Pages/PublicFieldNoteSkillRoster.razor.rz.scp.css */
.skill-roster-page[b-xyl4bg6z8c],
.skill-roster-page *[b-xyl4bg6z8c],
.skill-roster-page *[b-xyl4bg6z8c]::before,
.skill-roster-page *[b-xyl4bg6z8c]::after {
    box-sizing: border-box;
}

.skill-roster-page[b-xyl4bg6z8c] {
    --ink: #202724;
    --muted: #66706b;
    --paper: #f5f2ea;
    --panel: #fffdf8;
    --line: #d8ddd7;
    --green: #23634d;
    --green-soft: #e6efe9;
    --red: #a14336;
    --red-soft: #f4e8e4;
    --blue: #426578;
    --blue-soft: #e8eef2;
    min-height: 100vh;
    padding: 62px 0 68px;
    background: var(--paper);
    color: var(--ink);
    font-family: Inter, "Noto Sans TC", "Microsoft JhengHei", sans-serif;
    line-height: 1.65;
}

.roster-inner[b-xyl4bg6z8c] {
    width: min(1080px, calc(100% - 40px));
    margin: 0 auto;
}

.back-link[b-xyl4bg6z8c] {
    display: inline-flex;
    margin-bottom: 34px;
    color: var(--green);
    font-size: 14px;
    font-weight: 750;
    text-decoration: none;
}

.back-link:hover[b-xyl4bg6z8c] {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.hero[b-xyl4bg6z8c] { max-width: 930px; }

.eyebrow[b-xyl4bg6z8c] {
    color: var(--green);
    font-size: 13px;
    font-weight: 850;
    letter-spacing: 0.08em;
}

h1[b-xyl4bg6z8c] {
    margin: 13px 0 16px;
    max-width: 1000px;
    font-size: 52px;
    line-height: 1.18;
    letter-spacing: 0;
}

.lead[b-xyl4bg6z8c] {
    max-width: 900px;
    margin: 0 0 10px;
    color: var(--muted);
    font-size: 19px;
}

.intro[b-xyl4bg6z8c] {
    max-width: 900px;
    margin: 0;
    color: var(--ink);
    font-size: 16px;
}

.intro .asof[b-xyl4bg6z8c] {
    color: var(--muted);
    font-size: 13px;
}

.stepgroup[b-xyl4bg6z8c] { margin-top: 44px; }

.stepgroup-kicker[b-xyl4bg6z8c] {
    font-size: 12px;
    font-weight: 850;
    letter-spacing: 0.06em;
}

.stepgroup h2[b-xyl4bg6z8c] {
    margin: 6px 0 12px;
    font-size: 26px;
    line-height: 1.35;
    letter-spacing: 0;
}

.stepgroup.s1 .stepgroup-kicker[b-xyl4bg6z8c] { color: var(--green); }
.stepgroup.s2 .stepgroup-kicker[b-xyl4bg6z8c] { color: var(--blue); }
.stepgroup.s3 .stepgroup-kicker[b-xyl4bg6z8c] { color: var(--red); }

table.roster[b-xyl4bg6z8c] {
    width: 100%;
    border-collapse: collapse;
    border: 1px solid var(--line);
    background: var(--panel);
}

.stepgroup.s1 table.roster[b-xyl4bg6z8c] { border-top: 4px solid var(--green); }
.stepgroup.s2 table.roster[b-xyl4bg6z8c] { border-top: 4px solid var(--blue); }
.stepgroup.s3 table.roster[b-xyl4bg6z8c] { border-top: 4px solid var(--red); }

table.roster th[b-xyl4bg6z8c] {
    text-align: left;
    padding: 10px 16px;
    border-bottom: 1px solid var(--line);
    color: var(--muted);
    font-size: 11px;
    font-weight: 850;
}

table.roster td[b-xyl4bg6z8c] {
    vertical-align: top;
    padding: 14px 16px;
    border-bottom: 1px solid var(--line);
    font-size: 14.5px;
}

table.roster tr:last-child td[b-xyl4bg6z8c] { border-bottom: 0; }

td.station[b-xyl4bg6z8c] {
    width: 20%;
    font-weight: 750;
    white-space: nowrap;
}

td.modules[b-xyl4bg6z8c] { width: 30%; }

code[b-xyl4bg6z8c] {
    font-family: "SFMono-Regular", Consolas, "Noto Sans Mono", monospace;
    font-size: 12.5px;
    background: var(--green-soft);
    color: var(--green);
    padding: 2px 6px;
    border-radius: 4px;
    white-space: nowrap;
}

.stepgroup.s2 code[b-xyl4bg6z8c] { background: var(--blue-soft); color: var(--blue); }
.stepgroup.s3 code[b-xyl4bg6z8c] { background: var(--red-soft); color: var(--red); }

td.judgment[b-xyl4bg6z8c] { color: var(--muted); }
td.judgment b[b-xyl4bg6z8c] { color: var(--ink); }

.retire-note[b-xyl4bg6z8c] {
    margin: 12px 0 0;
    color: var(--muted);
    font-size: 13.5px;
}

.deep[b-xyl4bg6z8c] { margin-top: 52px; }

.deep-kicker[b-xyl4bg6z8c] {
    color: var(--red);
    font-size: 12px;
    font-weight: 850;
    letter-spacing: 0.06em;
}

.deep h2[b-xyl4bg6z8c] {
    margin: 6px 0 6px;
    font-size: 30px;
    line-height: 1.35;
    letter-spacing: 0;
}

.deep-lead[b-xyl4bg6z8c] {
    margin: 0 0 16px;
    color: var(--muted);
    font-size: 15px;
}

details.skillcard[b-xyl4bg6z8c] {
    border: 1px solid var(--line);
    background: var(--panel);
    margin-top: 12px;
}

details.skillcard summary[b-xyl4bg6z8c] {
    cursor: pointer;
    padding: 18px 20px;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 10px 14px;
}

details.skillcard summary[b-xyl4bg6z8c]::-webkit-details-marker { display: none; }

details.skillcard summary[b-xyl4bg6z8c]::after {
    content: "展開 +";
    margin-left: auto;
    color: var(--green);
    font-size: 12.5px;
    font-weight: 800;
    white-space: nowrap;
}

details.skillcard[open] summary[b-xyl4bg6z8c]::after { content: "收合 −"; }

.is-en details.skillcard summary[b-xyl4bg6z8c]::after { content: "Open +"; }
.is-en details.skillcard[open] summary[b-xyl4bg6z8c]::after { content: "Close −"; }

.skillcard .sk-name[b-xyl4bg6z8c] {
    font-family: "SFMono-Regular", Consolas, "Noto Sans Mono", monospace;
    font-size: 15px;
    font-weight: 750;
    color: var(--green);
}

.skillcard .sk-role[b-xyl4bg6z8c] {
    font-weight: 800;
    font-size: 17px;
}

.skillcard .sk-own[b-xyl4bg6z8c] {
    flex-basis: 100%;
    margin: 2px 0 0;
    color: var(--muted);
    font-size: 14px;
}

.skillcard dl[b-xyl4bg6z8c] {
    margin: 0;
    padding: 4px 20px 16px;
    border-top: 1px solid var(--line);
    display: grid;
    grid-template-columns: 150px 1fr;
    column-gap: 18px;
}

.skillcard dt[b-xyl4bg6z8c] {
    padding: 11px 0 0;
    color: var(--muted);
    font-size: 12px;
    font-weight: 850;
}

.skillcard dd[b-xyl4bg6z8c] {
    margin: 0;
    padding: 10px 0;
    font-size: 14.5px;
    border-bottom: 1px dashed var(--line);
}

.skillcard dd:last-of-type[b-xyl4bg6z8c] { border-bottom: 0; }

.skillcard dd.hold[b-xyl4bg6z8c] { font-weight: 650; }

.skillcard .audit[b-xyl4bg6z8c] {
    margin: 0;
    padding: 12px 20px;
    border-top: 1px solid var(--line);
    background: rgba(230, 239, 233, 0.5);
    color: var(--green);
    font-size: 13px;
    font-weight: 700;
}

.callout[b-xyl4bg6z8c] {
    margin-top: 52px;
    padding: 28px 30px;
    border-left: 6px solid var(--red);
    background: var(--red-soft);
}

.callout strong[b-xyl4bg6z8c] {
    display: block;
    font-size: 22px;
    line-height: 1.5;
}

.callout p[b-xyl4bg6z8c] {
    max-width: 900px;
    margin: 8px 0 0;
    font-size: 16px;
}

.lifecycle[b-xyl4bg6z8c] {
    margin: 40px auto 0;
    max-width: 900px;
    text-align: center;
}

.lifecycle .chain-main[b-xyl4bg6z8c] {
    font-size: 17px;
    font-weight: 750;
}

.lifecycle .chain-sub[b-xyl4bg6z8c] {
    margin-top: 4px;
    color: var(--muted);
    font-family: "SFMono-Regular", Consolas, "Noto Sans Mono", monospace;
    font-size: 12.5px;
}

.audit-exit[b-xyl4bg6z8c] {
    margin: 40px 0 0;
    padding: 22px;
    border: 1px solid var(--line);
    background: var(--panel);
    font-size: 15px;
}

.audit-exit a[b-xyl4bg6z8c] {
    color: var(--green);
    font-weight: 750;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.note-endnav[b-xyl4bg6z8c] {
    margin-top: 44px;
}

.endnav-next[b-xyl4bg6z8c] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 10px 14px;
    border: 1px solid var(--line);
    background: var(--panel);
    padding: 20px 22px;
    color: var(--ink);
    text-decoration: none;
}

.endnav-next:hover[b-xyl4bg6z8c] {
    border-color: var(--green);
}

.endnav-kicker[b-xyl4bg6z8c] {
    color: var(--green);
    font-family: "SFMono-Regular", Consolas, "Noto Sans Mono", monospace;
    font-size: 11.5px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.endnav-title[b-xyl4bg6z8c] {
    font-size: 17px;
    font-weight: 800;
}

.endnav-arrow[b-xyl4bg6z8c] {
    margin-left: auto;
    color: var(--green);
    font-weight: 800;
}

.endnav-row[b-xyl4bg6z8c] {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px 14px;
    margin-top: 16px;
}

.endnav-row a[b-xyl4bg6z8c] {
    color: var(--green);
    font-size: 14px;
    font-weight: 750;
    text-decoration: none;
}

.endnav-top[b-xyl4bg6z8c] {
    border: 0;
    background: none;
    padding: 0;
    color: var(--green);
    cursor: pointer;
    font-family: inherit;
    font-size: 14px;
    font-weight: 750;
}

.endnav-row a:hover[b-xyl4bg6z8c],
.endnav-top:hover[b-xyl4bg6z8c] {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.endnav-profile[b-xyl4bg6z8c] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 14px;
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: 13.5px;
}

.endnav-profile span[b-xyl4bg6z8c] { color: var(--ink); font-weight: 800; }
.endnav-profile a[b-xyl4bg6z8c] { color: var(--green); font-weight: 750; text-decoration: none; }
.endnav-profile a:hover[b-xyl4bg6z8c] { text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 820px) {
    .skill-roster-page[b-xyl4bg6z8c] { padding-top: 42px; }
    h1[b-xyl4bg6z8c] { font-size: 40px; }

    table.roster[b-xyl4bg6z8c],
    table.roster tbody[b-xyl4bg6z8c],
    table.roster tr[b-xyl4bg6z8c],
    table.roster td[b-xyl4bg6z8c] {
        display: block;
        width: 100%;
    }

    table.roster thead[b-xyl4bg6z8c] { display: none; }
    table.roster tr[b-xyl4bg6z8c] { border-bottom: 1px solid var(--line); }
    table.roster tr:last-child[b-xyl4bg6z8c] { border-bottom: 0; }
    table.roster td[b-xyl4bg6z8c] { border-bottom: 0; padding: 6px 16px; }
    td.station[b-xyl4bg6z8c] { padding-top: 14px; white-space: normal; }
    td.judgment[b-xyl4bg6z8c] { padding-bottom: 14px; }

    .skillcard dl[b-xyl4bg6z8c] { grid-template-columns: 1fr; }
    .skillcard dt[b-xyl4bg6z8c] { padding-top: 12px; }
    .skillcard dd[b-xyl4bg6z8c] { border-bottom: 0; padding-top: 3px; }
}

@media (max-width: 560px) {
    .roster-inner[b-xyl4bg6z8c] { width: min(100% - 28px, 1080px); }
    h1[b-xyl4bg6z8c] { font-size: 33px; }
    .lead[b-xyl4bg6z8c] { font-size: 17px; }
    .callout[b-xyl4bg6z8c] { padding: 22px; }
}
/* /Components/Pages/PublicHome.razor.rz.scp.css */
/* ============================================================
   PUBLIC HOME · V9 KOSO GRID
   Copy owner: xin-job-hunting shared/candidate-materials/
     signal-to-decision-system-page/copy/current-page-draft.md
   Style contract: that folder's prototypes/DESIGN.md — paper base,
   semantic 3 colors, dark board only at the Hero decision board,
   serif only H1 + Johanna name.
   ============================================================ */
/* ---------- reading progress (mechanism contract: --reading-progress var,
   driven by wwwroot/public-reading-progress.js — kept from the live runtime) ---------- */
.reading-progress[b-32ry10ci0n] {
  position: fixed;
  inset: 0 0 auto;
  z-index: 1001;
  height: 3px;
  pointer-events: none;
  background: rgba(35, 38, 43, .07);
  overflow: hidden;
}

.reading-progress-bar[b-32ry10ci0n] {
  display: block;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, #4fd1c5, #f2b544, #ff8a7a);
  transform: scaleX(var(--reading-progress, 0));
  transform-origin: left center;
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  .reading-progress-bar[b-32ry10ci0n] { will-change: auto; }
}

.pp9[b-32ry10ci0n] {
  color-scheme: light;
  --paper: #f6f4ef;
  --panel: #fffdf8;
  --ink: #23262b;
  --mut: #596662;
  --dim: #65726e;
  --line: rgba(35, 38, 43, .14);
  --line-soft: rgba(35, 38, 43, .08);
  --board: #081012;
  --board2: #10171a;
  --txt: #edf2ef;
  --card-line: rgba(188, 220, 211, .14);
  --teal: #4fd1c5;
  --teal-deep: #0f746c;
  --amber: #f2b544;
  --amber-deep: #8a5f00;
  --coral: #ff8a7a;
  --coral-deep: #b2503f;
  --cta: #d97757;
  --serif: Georgia, "Times New Roman", serif;
  --sans: "Inter", "Noto Sans TC", "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", Consolas, monospace;

  display: block;
  background:
    radial-gradient(900px 520px at 8% -4%, rgba(79, 209, 197, .075), transparent 62%),
    radial-gradient(820px 480px at 96% -6%, rgba(255, 138, 122, .06), transparent 60%),
    var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
}

.pp9 *[b-32ry10ci0n],
.pp9 *[b-32ry10ci0n]::before,
.pp9 *[b-32ry10ci0n]::after { box-sizing: border-box; }

.pp9 [b-32ry10ci0n]::selection { background: rgba(79, 209, 197, .3); }
.pp9 a[b-32ry10ci0n] { color: inherit; }
.pp9 img[b-32ry10ci0n] { max-width: 100%; }

/* Zero-specificity reset: any component rule below must be able to set its own
   margins without an !important arms race. Written with plain selectors this
   reset outweighed rules like .hero-sub{margin-top} and silently flattened the
   page's vertical rhythm. */
:where(.pp9) :where(h1, h2, h3, p, ol, ul)[b-32ry10ci0n] { margin: 0; padding: 0; }

/* ---------- rails + full-bleed dividers ---------- */
.pp9-wrap[b-32ry10ci0n] {
  max-width: 1360px;
  margin: 0 auto;
  border-inline: 1px solid var(--line);
  padding-inline: clamp(20px, 3.4vw, 48px);
}

.pp9-sec[b-32ry10ci0n] { border-bottom: 1px solid var(--line); }

.eyebrow[b-32ry10ci0n] {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--mut);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.eyebrow .tick[b-32ry10ci0n] { color: var(--teal-deep); }

.dot[b-32ry10ci0n] {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--teal);
  display: inline-block;
  flex: none;
  animation: pp9-breathe-b-32ry10ci0n 2.6s ease-in-out infinite;
}


@keyframes pp9-breathe-b-32ry10ci0n {
  0%, 100% { opacity: .45; transform: scale(.85); }
  50% { opacity: 1; transform: scale(1); }
}

/* ---------- hero ---------- */
.hero-head[b-32ry10ci0n] { padding-block: clamp(34px, 4.5vw, 60px) clamp(28px, 3.6vw, 48px); }

/* Gate 1 round 4: the hero reads as ONE typographic lockup, not three islands.
   Reference grammar (AI Hero, measured 2026-08-10): eyebrow is plain mono text
   without a box, 12px above the H1; the support line shares the H1's family and
   ink, subordinate by size alone. Bind with tight gaps, not containers. */
.hero-eyebrow[b-32ry10ci0n] {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 13px;
}

.pool-chip[b-32ry10ci0n] {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--mut);
}

/* No max-width here: the H1 carries authored <br>s (two-line AI-first lockup,
   2026-08-10 Gate 1 round 2 — "I built an AI marketing team" / "to run my job
   search."), and a width cap on top of them would fight the intended break. The
   gradient-underlined pipeline phrase now lives on the board header (.board-name)
   so the category name labels its own visual proof. */
.pp9 h1[b-32ry10ci0n] {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.4rem, 4.4vw, 4rem);
  line-height: 1.12;
  letter-spacing: -.016em;
}

.fx[b-32ry10ci0n] {
  background-image: linear-gradient(90deg, var(--teal), var(--amber), var(--coral));
  background-repeat: no-repeat;
  background-size: 100% .09em;
  background-position: 0 96%;
  padding-bottom: .05em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* Payoff support line: closes the hero scan unit on Johanna's judgment before
   the board. Same serif voice as the H1 (Gate 1 round 3: the first screen keeps
   two type layers only — serif for the editorial voice line H1 → payoff → board
   name, mono for system labels; sans stays body copy), subordinate via size and
   muted color. */
.hero-payoff[b-32ry10ci0n] {
  margin-top: clamp(10px, 1.3vw, 15px);
  font-family: var(--serif);
  font-size: clamp(1.12rem, 1.7vw, 1.38rem);
  line-height: 1.5;
  letter-spacing: -.008em;
  color: var(--ink);
}

/* ---------- decision board ---------- */
.board-band[b-32ry10ci0n] { border-top: 1px solid var(--line); }

/* One clock for the whole board. The brief's travel, the station highlights and
   the console's answer are the same event seen three ways, so they read from a
   single token instead of three literals that drift apart one edit at a time. */
.board[b-32ry10ci0n] {
  --st-cycle: 5.7s;
  background:
    radial-gradient(560px 300px at 50% 42%, rgba(79, 209, 197, .12), transparent 70%),
    repeating-linear-gradient(0deg, rgba(188, 220, 211, .05) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(90deg, rgba(188, 220, 211, .05) 0 1px, transparent 1px 28px),
    linear-gradient(160deg, var(--board), var(--board2));
  color: var(--txt);
  border-inline: 1px solid var(--line);
  max-width: 1360px;
  margin: 0 auto;
}

.board-head[b-32ry10ci0n] {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  align-items: center;
  justify-content: space-between;
  padding: 11px clamp(20px, 3.4vw, 48px);
  border-bottom: 1px solid var(--card-line);
}

/* Enlarged category name on the board itself (Gate 1 round 2): the pipeline
   phrase labels its visual proof instead of closing the H1. Keep the gradient
   underline whole — serif, no uppercase, no wrap inside the .fx span. */
.board-name[b-32ry10ci0n] {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 12px;
  font-family: var(--serif);
  font-size: clamp(1.35rem, 2.6vw, 2rem);
  letter-spacing: -.012em;
  color: var(--txt);
}

.board-name .fx[b-32ry10ci0n] { white-space: nowrap; }

/* Six handoff stations, not six table columns (board-semantics round,
   2026-08-10): visible gutters and per-card frames let the board grid show
   between stations, so the eye reads "work moves between these" instead of
   "one data table with six columns". The In motion label retired with the
   same round — the continuous brief proves the motion. */
/* minmax(0,1fr): plain 1fr tracks floor at min-content, and the gutters spent
   the slack that once let the nowrap station lines fit — a long discipline
   line would push the sixth card past the board edge (measured +44px at 1280). */
.lens-grid[b-32ry10ci0n] {
  position: relative;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 10px;
  padding: 16px clamp(14px, 1.8vw, 26px) 14px;
}

/* The handoff object: a small glowing brief travels the conveyor under the
   stations. It never stops — routine handoffs keep moving without waiting on
   anyone; it fades in at 01 and out at 06, and each card's frame answers
   with a low glow as it passes (pp9-cardSweep, same clock). */
.lens-grid[b-32ry10ci0n]::after {
  content: "";
  position: absolute;
  bottom: 3px;
  left: clamp(14px, 1.8vw, 26px);
  width: 9px;
  height: 12px;
  border: 1px solid var(--teal);
  border-radius: 2px;
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(79, 209, 197, .8) 2px 3px),
    rgba(8, 16, 18, .85);
  box-shadow: 0 0 10px rgba(79, 209, 197, .75);
  animation: pp9-handoff-b-32ry10ci0n var(--st-cycle) linear infinite;
  z-index: 2;
  pointer-events: none;
}

@keyframes pp9-handoff-b-32ry10ci0n {
  0% { left: clamp(14px, 1.8vw, 26px); opacity: 0; }
  3% { opacity: 1; }
  93% { opacity: 1; }
  100% { left: calc(100% - clamp(14px, 1.8vw, 26px) - 9px); opacity: 0; }
}

.lens[b-32ry10ci0n] {
  position: relative;
  background: linear-gradient(180deg, rgba(8, 16, 18, .92), rgba(16, 23, 26, .92));
  border: 1px solid var(--card-line);
  border-radius: 10px;
  padding: 15px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 160px;
}

/* As the brief passes, the station lights up — card face, frame, glow, icon,
   number and name together — then fades behind it.
   Two things keep this "work is moving through here" instead of the "work
   stopped here for approval" reading the earlier frame-only sweep was
   protecting: the envelope is a wake (fast rise, brief peak, longer fall, so
   the light trails the brief rather than parking on the card), and nothing
   moves — no scale, no translate, and the amber decision chip never brightens,
   because a station that flashed its own decision affordance would read as a
   gate. The earlier version was frame-only for that reason; it bought the
   semantics by being nearly invisible, which is the wrong trade when a viewer
   who is not staring at the board cannot tell which station holds the brief.
   Resting values are unchanged: every station stays fully legible, so this is
   not the retired spotlight cycle, which dimmed the other five into a queue.

   --st-delay is the phase, set once per card and inherited by all four
   animations, so the frame can never drift from the text it belongs to.
   Values are derived, not tuned: the brief crosses card i's center at
   ((c_i - 4.5) / (W - 9)) of the cycle, and the peak is parked there. The
   fractions are viewport-invariant to ~0.1% across the single-row range, so
   fixed delays hold. The hand-tuned .855s steps they replace assumed an even
   split of the cycle and ran up to 0.39s out of phase with the brief.
   Window = 16% = 0.91s, which is how long the brief overlaps one card — the
   light lasts exactly as long as the cause is present, and the 0.05s gap that
   leaves between stations is what guarantees only one card is ever lit.
   Scoped to the single-row layout, where the left-to-right pass exists. */
@media (min-width: 1181px) {
  .lens[b-32ry10ci0n] {
    --st-delay: 0s;
    animation: pp9-cardSweep-b-32ry10ci0n var(--st-cycle) linear var(--st-delay) infinite;
  }

  .lens:nth-child(1)[b-32ry10ci0n] { --st-delay: .07s; }
  .lens:nth-child(2)[b-32ry10ci0n] { --st-delay: 1.03s; }
  .lens:nth-child(3)[b-32ry10ci0n] { --st-delay: 2s; }
  .lens:nth-child(4)[b-32ry10ci0n] { --st-delay: 2.96s; }
  .lens:nth-child(5)[b-32ry10ci0n] { --st-delay: 3.93s; }
  .lens:nth-child(6)[b-32ry10ci0n] { --st-delay: 4.89s; }

  .lens-top .glyph[b-32ry10ci0n] { animation: pp9-stationGlyph-b-32ry10ci0n var(--st-cycle) linear var(--st-delay) infinite; }
  .lens-no[b-32ry10ci0n] { animation: pp9-stationNo-b-32ry10ci0n var(--st-cycle) linear var(--st-delay) infinite; }
  .lens-name[b-32ry10ci0n] { animation: pp9-stationName-b-32ry10ci0n var(--st-cycle) linear var(--st-delay) infinite; }
}

/* The surface wash is an inset box-shadow with a spread wider than the card,
   not an overlay element: it paints over the card's own gradient and under its
   text, so face, frame and glow are one animated property and cannot desync,
   and nothing is added to the DOM or to the layout.
   The 200px spread is held constant across both stops and only the alpha
   moves. Interpolating the spread up from 0 instead leaves the wash a vignette
   for the first ~100ms of the rise — an inset shadow only fills the card once
   its spread exceeds half the card's short side. */
@keyframes pp9-cardSweep-b-32ry10ci0n {
  0%, 16%, 100% {
    border-color: var(--card-line);
    box-shadow: 0 0 0 rgba(79, 209, 197, 0), inset 0 0 0 200px rgba(79, 209, 197, 0);
  }
  5%, 8% {
    border-color: rgba(79, 209, 197, .58);
    box-shadow: 0 0 17px rgba(79, 209, 197, .17), inset 0 0 0 200px rgba(79, 209, 197, .07);
  }
}

@keyframes pp9-stationGlyph-b-32ry10ci0n {
  0%, 16%, 100% { stroke: rgba(188, 220, 211, .55); color: rgba(188, 220, 211, .55); }
  5%, 8% { stroke: var(--teal); color: var(--teal); }
}

@keyframes pp9-stationNo-b-32ry10ci0n {
  0%, 16%, 100% { color: var(--teal); text-shadow: 0 0 0 rgba(79, 209, 197, 0); }
  5%, 8% { color: #8ae9df; text-shadow: 0 0 9px rgba(79, 209, 197, .5); }
}

@keyframes pp9-stationName-b-32ry10ci0n {
  0%, 16%, 100% { color: rgba(237, 242, 239, .92); }
  5%, 8% { color: #fff; }
}

/* Station header is a two-line stack: mono eyebrow (number · role avatar) above,
   full role name on its own line so buyer-facing titles never wrap mid-card.
   The eyebrow keeps 01→06 anchored to the card top for the sequential sweep. */
.lens-top[b-32ry10ci0n] { display: flex; align-items: center; justify-content: flex-start; gap: 10px; }

.lens-top .glyph[b-32ry10ci0n] {
  stroke: rgba(188, 220, 211, .55);
  color: rgba(188, 220, 211, .55);
  flex: none;
}

/* No :hover state on a station. The cards are not clickable, so a face-lift or
   a teal icon under the cursor promised an interaction that does not exist —
   and it used the same teal the sweep uses, so a resting mouse manufactured a
   second "active station" that the brief was nowhere near. The sweep is now
   the only thing that makes a station active. */

.lens-no[b-32ry10ci0n] { font-family: var(--mono); font-size: .7rem; color: var(--teal); letter-spacing: .14em; }

/* Steady and legible: the retired spotlight cycle kept five names dim as
   "waiting their turn" — a queue grammar the continuous brief contradicts.
   Names may take two lines (canonical §6 allows it) now that gutters own the
   width the old nowrap depended on. */
.lens-name[b-32ry10ci0n] {
  display: block;
  margin-top: -2px;
  font-weight: 750;
  font-size: .98rem;
  line-height: 1.22;
  letter-spacing: -.02em;
  color: rgba(237, 242, 239, .92);
}

/* Single-row layout reserves the two-line slot on every card, so the six
   judgment lines start on one shared baseline whether or not a name wraps. */
@media (min-width: 1181px) {
  .lens-name[b-32ry10ci0n] { min-height: calc(2 * 1.22em); }
}
.lens-q[b-32ry10ci0n] { font-size: .8rem; line-height: 1.5; color: rgba(237, 242, 239, .72); }
.lens-out[b-32ry10ci0n] { font-family: var(--mono); font-size: .6rem; line-height: 1.55; color: rgba(188, 220, 211, .75); margin-top: auto; letter-spacing: 0; }

.lens-chip[b-32ry10ci0n] {
  align-self: flex-start;
  border: 1px solid var(--card-line);
  padding: 3px 8px;
  font-family: var(--mono);
  font-size: .6rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--amber);
}

/* Six static drop hairlines — one per station, card center down to the
   console frame. They say "she reads every station's cross-stage signal";
   they are not a return path or an approval gate, so nothing travels down
   them. Routine flow (the brief) and cross-stage signals (these lines) are
   two visual responsibilities, and only the brief moves. */
.flow-lane[b-32ry10ci0n] {
  position: relative;
  height: 34px;
  margin: 0 clamp(14px, 1.8vw, 26px);
}

.ftick[b-32ry10ci0n] {
  position: absolute;
  top: 0;
  bottom: -1px;
  width: 1px;
  background: rgba(188, 220, 211, .16);
  pointer-events: none;
}

.ftick:nth-child(1)[b-32ry10ci0n] { left: calc(100% / 12 * 1); }
.ftick:nth-child(2)[b-32ry10ci0n] { left: calc(100% / 12 * 3); }
.ftick:nth-child(3)[b-32ry10ci0n] { left: calc(100% / 12 * 5); }
.ftick:nth-child(4)[b-32ry10ci0n] { left: calc(100% / 12 * 7); }
.ftick:nth-child(5)[b-32ry10ci0n] { left: calc(100% / 12 * 9); }
.ftick:nth-child(6)[b-32ry10ci0n] { left: calc(100% / 12 * 11); }

/* Command console: resting frame, no breathing — a console that pulses on
   its own reads as one more ambient light, and the reader loses which glow
   means "Johanna is needed". The one pulse it keeps is caused: when the
   brief lands on 06, the frame answers in coral — the cycle's result
   entering diagnosis and learn-back. */
.desk[b-32ry10ci0n] {
  background: linear-gradient(180deg, rgba(10, 19, 21, .96), rgba(17, 25, 28, .96));
  padding: 0;
  margin: 0 clamp(14px, 1.8vw, 26px) 16px;
  border: 1px solid rgba(79, 209, 197, .5);
  box-shadow: 0 0 0 1px rgba(79, 209, 197, .1), 0 0 24px rgba(79, 209, 197, .12), inset 0 0 70px rgba(79, 209, 197, .05);
}

/* Desktop only: below 1181px the brief is hidden, and a pulse with no
   visible cause reads as ambient blinking. */
@media (min-width: 1181px) {
  .desk[b-32ry10ci0n] { animation: pp9-consolePulse-b-32ry10ci0n var(--st-cycle) linear infinite; }
}

@keyframes pp9-consolePulse-b-32ry10ci0n {
  0%, 88%, 100% { box-shadow: 0 0 0 1px rgba(79, 209, 197, .1), 0 0 24px rgba(79, 209, 197, .12), inset 0 0 70px rgba(79, 209, 197, .05); }
  93% { box-shadow: 0 0 0 1px rgba(255, 138, 122, .32), 0 0 30px rgba(255, 138, 122, .22), inset 0 0 70px rgba(79, 209, 197, .05); }
}

/* Command console layout (board-semantics round, 2026-08-10): one centered
   column. Johanna sits at the board's geometric center — the six drop lines
   converge on her, so the layout states ownership before any label could.
   Focal chain: face → name → thesis; the decision chain below is the proof
   of judgment, not a ledger. */
.con-center[b-32ry10ci0n] {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 18px clamp(18px, 2.6vw, 40px) 16px;
}

.con-id[b-32ry10ci0n] { display: flex; align-items: center; gap: 14px; }

.desk-avatar[b-32ry10ci0n] {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid rgba(79, 209, 197, .55);
  box-shadow: 0 0 0 3px rgba(79, 209, 197, .12);
}

.desk-name[b-32ry10ci0n] { font-family: var(--serif); font-size: clamp(1.4rem, 2.1vw, 1.8rem); letter-spacing: .01em; }

/* The thesis line is the console's first read: serif editorial voice (same
   layer as H1 → payoff → board name), full ink, centered — subordinate to
   nothing inside the console. */
.desk-role[b-32ry10ci0n] {
  font-family: var(--serif);
  font-size: clamp(1.02rem, 1.5vw, 1.22rem);
  line-height: 1.5;
  letter-spacing: -.008em;
  color: var(--txt);
  text-align: center;
}

/* One decision, traced end to end: SIGNAL → JOHANNA'S CALL → WRITE-BACK.
   An ordered list, so the causal path survives with animations off. All
   three cells stay coral — the diagnose-and-learn family; teal routing
   receipts left the console with the retired ROUTED row. */
.chain[b-32ry10ci0n] {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px 30px;
  width: 100%;
  max-width: 960px;
  margin-top: 6px;
}

.step[b-32ry10ci0n] {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 12px;
  border-left: 2px solid var(--coral);
  text-align: left;
}

.step .tag[b-32ry10ci0n] { font-family: var(--mono); font-size: .62rem; letter-spacing: .1em; color: var(--coral); white-space: nowrap; }
.step .msg[b-32ry10ci0n] { font-size: .8rem; color: rgba(237, 242, 239, .78); line-height: 1.5; }

.step + .step[b-32ry10ci0n]::before {
  content: "→";
  position: absolute;
  left: -24px;
  top: 7px;
  font-family: var(--mono);
  font-size: .72rem;
  color: rgba(237, 242, 239, .38);
}

/* ---------- generic section head ---------- */
.sec-head[b-32ry10ci0n] { padding-block: clamp(40px, 5.5vw, 74px) clamp(26px, 3.4vw, 44px); }
.sec-eyebrow[b-32ry10ci0n] { margin-bottom: clamp(18px, 2.6vw, 30px); }
/* Question + cost line read as one breath: stacked, not split into columns. */
.sec-stack[b-32ry10ci0n] { display: flex; flex-direction: column; gap: clamp(12px, 1.6vw, 18px); }
.sec-stack .sec-lead[b-32ry10ci0n] { max-width: 62ch; }

.pp9 h2[b-32ry10ci0n] {
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(1.85rem, 4.2vw, 3.6rem);
  line-height: .99;
  letter-spacing: -.03em;
}

.pp9 h2 .fx[b-32ry10ci0n] { background-size: 100% .07em; background-position: 0 99%; }
.pp9 h2[b-32ry10ci0n], .sec-lead[b-32ry10ci0n], .cta-line[b-32ry10ci0n] { text-wrap: balance; }
.sec-lead[b-32ry10ci0n] { font-size: clamp(1.05rem, 1.6vw, 1.32rem); line-height: 1.55; color: #41474b; letter-spacing: -.012em; }

/* ---------- proof ---------- */
.stat-band[b-32ry10ci0n] { margin: clamp(30px, 4vw, 56px) 0; border: 1px solid var(--line); background: var(--panel); }

.stat-head[b-32ry10ci0n] {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: .64rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink);
}

.stat-grid[b-32ry10ci0n] { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); }
.stat-cell[b-32ry10ci0n] { background: var(--panel); padding: clamp(16px, 2vw, 24px) clamp(16px, 2vw, 22px); }
.stat-n[b-32ry10ci0n] { font-family: var(--mono); font-weight: 600; font-size: clamp(1.9rem, 3.2vw, 2.8rem); letter-spacing: -.04em; color: var(--teal-deep); line-height: 1; }
.stat-l[b-32ry10ci0n] { margin-top: 9px; font-family: var(--mono); font-size: .64rem; letter-spacing: .09em; text-transform: uppercase; color: var(--mut); line-height: 1.65; }

/* four-station sales-pipeline strip (2026-07-26) */
.stat-grid.four[b-32ry10ci0n] { grid-template-columns: repeat(4, 1fr); }
.stat-n small[b-32ry10ci0n] { font-size: .95rem; font-weight: 400; color: var(--mut); letter-spacing: 0; }
/* Two-line reserve: the four big numbers must sit on one baseline, so a kicker
   that wraps must not push its own number down while the others stay put.
   Sized to be read, not just seen — the band's GATE has readers replay the
   story from these four kickers plus the big numbers alone. */
.stat-k[b-32ry10ci0n] { font-family: var(--mono); font-size: .68rem; letter-spacing: .13em; text-transform: uppercase; color: var(--teal-deep); margin-bottom: 10px; line-height: 1.5; min-height: 3em; }
.stat-cap[b-32ry10ci0n] { margin-top: 6px; font-family: var(--mono); font-size: .55rem; letter-spacing: .08em; text-transform: uppercase; color: var(--mut); line-height: 1.5; }
/* charts sit on a whisper-faint teal wash — variation, not emphasis */
.mfn[b-32ry10ci0n] {
  margin-top: 12px; padding: 10px 12px;
  background: rgba(79, 209, 197, .055); border-radius: 6px;
}
.mfn-row[b-32ry10ci0n] { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.mfn-row:last-child[b-32ry10ci0n] { margin-bottom: 0; }
.mfn-track[b-32ry10ci0n] { flex: 1; min-width: 0; }
.mfn-bar[b-32ry10ci0n] { display: block; height: 8px; background: var(--teal-deep); opacity: .85; border-radius: 2px; min-width: 2px; }
.mfn-lab[b-32ry10ci0n] { font-family: var(--mono); font-size: .55rem; color: var(--mut); white-space: nowrap; }
.wkbars[b-32ry10ci0n] {
  display: flex; gap: 3px; align-items: flex-end; height: 44px; margin-top: 12px;
  padding: 10px 12px 8px;
  background: rgba(79, 209, 197, .055); border-radius: 6px;
  box-sizing: content-box;
}
.wkbars span[b-32ry10ci0n] { flex: 1; background: var(--teal-deep); opacity: .85; border-radius: 2px 2px 0 0; }
.wkbars span.zero[b-32ry10ci0n] { background: var(--amber); opacity: .6; }
@media (max-width: 1080px) {
  .stat-grid.four[b-32ry10ci0n] { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .stat-grid.four[b-32ry10ci0n] { grid-template-columns: 1fr; }
}

/* ---------- hiring bar ---------- */
/* H2 + provenance + both rails must share one screenful — the section's whole
   argument is scannable without scrolling, so the head stays tight. */
#hiring-bar .sec-head[b-32ry10ci0n] { padding-block: clamp(30px, 4vw, 48px) 0; }
#hiring-bar .sec-eyebrow[b-32ry10ci0n] { margin-bottom: clamp(14px, 2vw, 22px); }
#hiring-bar h2[b-32ry10ci0n] { font-size: clamp(1.6rem, 3.1vw, 2.65rem); }
/* Two rails: the left auto-scroll ticker carries volume ("the market keeps
   writing this bar"), the right static market read carries meaning. The left
   rail is evidence density, not reading material — narrow column, small quiet
   type, only the amber-circled words pop; rows stay linked and hover-readable
   because they are the provenance chain. The right rail is the takeaway. */
/* Provenance is metadata, not a lead sentence — but it is the ticker's whole
   credibility claim, so it wraps on narrow viewports instead of truncating. */
.hbar-src[b-32ry10ci0n] { font-family: var(--mono); font-size: .64rem; letter-spacing: .06em; color: var(--mut); line-height: 1.7; margin-top: 8px; }

.hbar-grid[b-32ry10ci0n] { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); border: 1px solid var(--line); background: var(--panel); margin-top: 12px; }

/* The ticker fills its grid cell exactly: the track is absolutely positioned,
   so the row height comes from the market read alone — no leftover blank band.
   Native scrollTop motion (public-home-ticker.js) keeps manual and automatic
   scrolling on the same axis instead of faking movement with a transform.
   No visible scrollbar: the loop makes a thumb position meaningless (it would
   teleport at the seam), so the edge fades carry the "more content" signal and
   wheel / touch / arrow keys stay the manual controls. */
.ticker[b-32ry10ci0n] {
  position: relative;
  overflow-x: hidden;
  overflow-y: auto;
  min-height: 240px;
  border-right: 1px solid var(--line);
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 34px, #000 calc(100% - 34px), transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 34px, #000 calc(100% - 34px), transparent);
}
.ticker[b-32ry10ci0n]::-webkit-scrollbar { display: none; }
.ticker:focus-visible[b-32ry10ci0n] { outline: 1px solid var(--teal); outline-offset: -2px; }
.ticker-track[b-32ry10ci0n] { position: absolute; top: 0; left: 0; right: 0; }

.trow[b-32ry10ci0n] { display: block; text-decoration: none; color: inherit; padding: 8px 14px; border-bottom: 1px solid var(--line-soft); }
.trow:hover[b-32ry10ci0n] { background: #fffef9; }
.t-who[b-32ry10ci0n] { display: block; font-family: var(--mono); font-size: .5rem; letter-spacing: .12em; text-transform: uppercase; color: var(--mut); line-height: 1.35; }
.t-who .co[b-32ry10ci0n] { font-weight: 700; color: var(--ink); }
.t-q[b-32ry10ci0n] { display: block; font-size: .7rem; font-weight: 600; line-height: 1.32; letter-spacing: -.005em; margin-top: 1px; color: rgba(35, 38, 43, .82); }
.t-g[b-32ry10ci0n] { display: block; font-size: .6rem; font-weight: 400; color: var(--mut); line-height: 1.32; margin-top: 1px; }
.t-src[b-32ry10ci0n] { display: flex; gap: 8px; align-items: baseline; margin-top: 3px; font-family: var(--mono); font-size: .47rem; line-height: 1.35; color: var(--dim); }
.t-src .dot[b-32ry10ci0n] { width: 5px; height: 5px; border-radius: 50%; background: var(--teal); display: inline-block; flex: none; align-self: center; }
.t-url[b-32ry10ci0n] { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

.mread[b-32ry10ci0n] { padding: clamp(24px, 3vw, 44px); display: flex; flex-direction: column; gap: 24px; justify-content: center; }
.mread-k[b-32ry10ci0n] { font-family: var(--mono); font-size: .62rem; letter-spacing: .16em; text-transform: uppercase; color: var(--teal-deep); }
.mread-item b[b-32ry10ci0n] { display: block; font-size: clamp(1.06rem, 1.6vw, 1.3rem); font-weight: 750; letter-spacing: -.015em; line-height: 1.3; }
.mread-item p[b-32ry10ci0n] { font-size: .86rem; color: var(--mut); line-height: 1.55; margin-top: 4px; }

/* The X → Y shift is typographic, not animated: the old world sits muted and
   slightly smaller, the amber arrow carries the move, the destination is what
   they are buying — bold ink. The scan order IS the message. */
.mr-n[b-32ry10ci0n] { display: block; font-family: var(--mono); font-size: .55rem; letter-spacing: .14em; color: var(--dim); margin-bottom: 4px; }
.mr-from[b-32ry10ci0n] { color: var(--mut); font-weight: 550; font-size: .85em; }
.mr-arrow[b-32ry10ci0n] { color: var(--amber-deep); font-weight: 400; margin: 0 .32em; }
.mr-to[b-32ry10ci0n] { color: var(--ink); }

/* One-way scroll entrance for the three shifts — supported browsers only,
   static everywhere else. Kept subtle: rise once as the item enters. */
@supports (animation-timeline: view()) {
  .mread-item[b-32ry10ci0n] {
    animation: mread-rise-b-32ry10ci0n linear both;
    animation-timeline: view();
    animation-range: entry 5% entry 45%;
  }
}
@keyframes mread-rise-b-32ry10ci0n {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}

.hbar-grid[b-32ry10ci0n] { margin-bottom: clamp(44px, 5.5vw, 72px); }

/* The circled operative word arrives as raw markup from the JdTicker source
   list, so it carries no Blazor scope attribute — reach it with ::deep. */
.t-q[b-32ry10ci0n]  .circ { position: relative; display: inline-block; padding: 0 .14em; }
.t-q[b-32ry10ci0n]  .circ svg { position: absolute; inset: -26% -9%; width: 118%; height: 152%; overflow: visible; pointer-events: none; }
.t-q[b-32ry10ci0n]  .circ ellipse { fill: none; stroke: var(--amber); stroke-width: 2.4; stroke-linecap: round; transform: rotate(-2.5deg); transform-origin: center; }

/* ---------- johanna ---------- */
.about-grid[b-32ry10ci0n] {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  grid-template-areas: "time side";
  gap: 0 clamp(30px, 4.5vw, 70px);
  align-items: start;
  padding-bottom: clamp(40px, 5vw, 64px);
}

.about-grid .time-rows[b-32ry10ci0n] { grid-area: time; }
.about-grid .side-col[b-32ry10ci0n] { grid-area: side; }

.time-rows[b-32ry10ci0n] { border-top: 1px solid var(--line); }

.time-row[b-32ry10ci0n] {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  gap: clamp(12px, 2vw, 24px);
  padding: clamp(14px, 1.9vw, 20px) 0;
  border-bottom: 1px solid var(--line-soft);
  align-items: baseline;
}

.time-y[b-32ry10ci0n] { font-family: var(--mono); font-weight: 600; font-size: 1.05rem; letter-spacing: -.02em; }

.time-tag[b-32ry10ci0n] {
  display: table;
  border: 1px solid var(--line);
  padding: 3px 9px;
  margin-bottom: 9px;
  font-family: var(--mono);
  font-size: .6rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--mut);
}

.time-v[b-32ry10ci0n] { display: block; font-size: 1.02rem; font-weight: 600; letter-spacing: -.012em; line-height: 1.45; max-width: 44ch; }
.time-o[b-32ry10ci0n] { font-family: var(--mono); font-size: .72rem; color: var(--teal-deep); letter-spacing: .04em; white-space: nowrap; }

/* NOW row closes the four-row arc: the section's single soft emphasis — weight
   and a teal year marker only, no extra elements (canonical §4 layout note). */
.time-row.time-now .time-y[b-32ry10ci0n] { color: var(--teal-deep); }
.time-row.time-now .time-v[b-32ry10ci0n] { font-weight: 750; }

.side-col[b-32ry10ci0n] { position: sticky; top: 86px; display: grid; gap: 18px; }

.profile-card[b-32ry10ci0n] {
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 16px;
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 16px;
  align-items: center;
}

.portrait-frame[b-32ry10ci0n] { display: block; }
.profile-card img[b-32ry10ci0n] { display: block; width: 100%; height: auto; border: 1px solid var(--line-soft); }
.profile-name[b-32ry10ci0n] { font-weight: 800; font-size: 1.22rem; letter-spacing: -.018em; text-transform: uppercase; }
.profile-school[b-32ry10ci0n] { font-family: var(--mono); font-size: .6rem; letter-spacing: .16em; text-transform: uppercase; color: var(--mut); margin: 5px 0 12px; }
/* Credential pair breaks as one unit — never an orphaned "2026" line. */
.profile-school .school-cred[b-32ry10ci0n] { white-space: nowrap; }
.profile-card .cta-links[b-32ry10ci0n] { margin-top: 0; flex-direction: column; gap: 7px; }
.profile-card .cta-links a[b-32ry10ci0n] { text-align: center; padding: 8px 12px; }

.think[b-32ry10ci0n] { border: 1px solid var(--line); background: var(--panel); }
.think-majors[b-32ry10ci0n] { padding: 20px 22px; border-bottom: 1px solid var(--line); font-weight: 750; font-size: clamp(1.05rem, 1.6vw, 1.28rem); letter-spacing: -.015em; }
.think-label[b-32ry10ci0n] { padding: 13px 22px 0; font-family: var(--mono); font-size: .62rem; letter-spacing: .22em; text-transform: uppercase; color: var(--teal-deep); }
.think-rows[b-32ry10ci0n] { padding: 8px 22px 20px; }
/* Label column fits the widest discipline name (EN "Data Science"); a shared
   fixed width keeps the three rows' text column aligned in both languages. */
.think-row[b-32ry10ci0n] { display: grid; grid-template-columns: 88px 1fr; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line-soft); align-items: baseline; }
.think-row:last-child[b-32ry10ci0n] { border-bottom: 0; }
.think-row .n[b-32ry10ci0n] { font-family: var(--mono); font-size: .66rem; color: var(--mut); text-transform: uppercase; letter-spacing: .08em; white-space: nowrap; }
.think-row .t[b-32ry10ci0n] { font-weight: 600; font-size: .95rem; letter-spacing: -.01em; }

/* ---------- CTA band ---------- */
.cta-band[b-32ry10ci0n] { border-top: 1px solid var(--line); background: var(--panel); }
.cta-grid[b-32ry10ci0n] { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, .9fr); gap: clamp(24px, 4vw, 60px); align-items: start; padding-block: clamp(30px, 4.5vw, 54px); }
.cta-line[b-32ry10ci0n] { font-size: clamp(1.35rem, 2.6vw, 2.1rem); font-weight: 750; letter-spacing: -.03em; line-height: 1.25; max-width: 26ch; }

.cta-fx[b-32ry10ci0n] {
  background-image: linear-gradient(90deg, var(--cta), var(--cta));
  background-repeat: no-repeat;
  background-size: 100% .12em;
  background-position: 0 96%;
  padding-bottom: .05em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

.cta-links[b-32ry10ci0n] { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }

.cta-links a[b-32ry10ci0n] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--line);
  padding: 10px 16px;
  color: var(--ink);
  background: var(--paper);
}

.cta-links a svg[b-32ry10ci0n] { width: 14px; height: 14px; flex: none; }
.cta-links a:hover[b-32ry10ci0n] { border-color: var(--teal-deep); color: var(--teal-deep); }

/* Composer — one free-text field, written straight to the feedback table.
   Deliberately not split into typed fields: the visitor decides whether it
   carries a JD, a reply address or a question, and parsing happens downstream. */
.cta-sub[b-32ry10ci0n] { margin-top: 14px; font-size: .95rem; line-height: 1.6; color: var(--mut); max-width: 44ch; }

/* Retell line — the sentence an advocate can forward. Sits under the band as a
   quiet handoff, deliberately weaker than the CTA so it never reads as a second ask.
   The hairline rides the full content wrap; only the text is measure-capped, so the
   rule reads as a divider instead of a fragment ending mid-band. */
.cta-retell-row[b-32ry10ci0n] { border-top: 1px solid var(--line); padding-block: 16px 24px; }
.cta-retell[b-32ry10ci0n] { font-size: .84rem; line-height: 1.65; color: var(--dim); max-width: 72ch; }

.composer[b-32ry10ci0n] { border: 1px solid var(--line); background: var(--paper); position: relative; }
.composer .fhead[b-32ry10ci0n] { padding: 11px 16px; border-bottom: 1px solid var(--line); font-family: var(--mono); font-size: .64rem; letter-spacing: .2em; text-transform: uppercase; color: var(--mut); }
.composer[b-32ry10ci0n]  .k-textarea { border: 0; border-radius: 0; background: transparent; width: 100%; }
.composer[b-32ry10ci0n]  .k-input-inner { font-family: var(--sans); font-size: .95rem; line-height: 1.65; color: var(--ink); padding: 16px; }
.composer[b-32ry10ci0n]  .k-textarea:focus-within { box-shadow: none; outline: 2px solid var(--teal); outline-offset: -2px; }

.composer-foot[b-32ry10ci0n] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-top: 1px solid var(--line-soft);
}

.composer-count[b-32ry10ci0n] { font-family: var(--mono); font-size: .58rem; letter-spacing: .08em; color: var(--dim); }

/* Same ramp as the nav CTA: the deep brick rests, hover and press go darker.
   White on the lighter orange was 3.1:1 at this size and weight. */
.composer[b-32ry10ci0n]  .composer-submit {
  border: 0;
  border-radius: 0;
  background: var(--coral-deep);
  color: #fff;
  font-weight: 700;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  padding: 12px 20px;
}

.composer[b-32ry10ci0n]  .composer-submit:hover:not([disabled]) { background: #8f3f32; }
.composer[b-32ry10ci0n]  .composer-submit:active:not([disabled]) { background: #7a3529; }
.composer[b-32ry10ci0n]  .composer-submit:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.composer[b-32ry10ci0n]  .composer-submit[disabled] { background: var(--line); color: var(--dim); cursor: not-allowed; }

.feedback-honeypot[b-32ry10ci0n] { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.feedback-status[b-32ry10ci0n] { margin: 0 16px 14px; font-size: .85rem; line-height: 1.6; }
.feedback-error[b-32ry10ci0n] { color: var(--coral-deep); }
.feedback-success[b-32ry10ci0n] { color: var(--teal-deep); }

/* ---------- footer ---------- */
.pp9-foot[b-32ry10ci0n] { border-bottom: 0; }

.foot-bar[b-32ry10ci0n] {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  align-items: center;
  justify-content: space-between;
  padding-block: 20px 26px;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--mut);
}

.foot-bar a[b-32ry10ci0n] { text-decoration: none; color: var(--mut); }
.foot-bar a:hover[b-32ry10ci0n] { color: var(--ink); }
.foot-links[b-32ry10ci0n] { display: flex; gap: 22px; }
.foot-privacy[b-32ry10ci0n] { margin-top: -8px; font-family: var(--mono); font-size: .56rem; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); line-height: 1.8; }
.foot-fresh[b-32ry10ci0n] { padding-bottom: 24px; padding-top: 6px; font-family: var(--mono); font-size: .56rem; letter-spacing: .1em; text-transform: uppercase; line-height: 1.8; }
.foot-fresh a[b-32ry10ci0n] { text-decoration: none; color: var(--dim); }
.foot-fresh a:hover[b-32ry10ci0n] { color: var(--ink); }

/* ---------- responsive ---------- */
@media (max-width: 1180px) {
  .lens-grid[b-32ry10ci0n] { grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .lens[b-32ry10ci0n] { min-height: 172px; }
  /* Drop lines and the handoff object only make sense on the single 01→06 row.
     The card sweep and console pulse are min-width-scoped for the same reason:
     no visible brief, no glow to answer it. */
  .lens-grid[b-32ry10ci0n]::after { display: none; }
  .flow-lane[b-32ry10ci0n] { display: none; }
}

@media (max-width: 960px) {
  /* Story first, then the person, then the method — the four-row arc is the
     section's proof of the H2 claim, so it stays adjacent to it on mobile
     (canonical §4 layout note, 2026-08-05). */
  .about-grid[b-32ry10ci0n] { grid-template-columns: 1fr; gap: 26px; grid-template-areas: "time" "side"; }
  .hbar-grid[b-32ry10ci0n] { grid-template-columns: 1fr; }
  .ticker[b-32ry10ci0n] { height: 252px; border-right: 0; border-bottom: 1px solid var(--line); }
  .mread[b-32ry10ci0n] { padding: 24px 20px; }
  .side-col[b-32ry10ci0n] { position: static; max-width: 560px; }
  .cta-grid[b-32ry10ci0n] { grid-template-columns: 1fr; }
}

@media (max-width: 740px) {
  .lens-grid[b-32ry10ci0n] { grid-template-columns: repeat(2, 1fr); }
  .stat-grid[b-32ry10ci0n] { grid-template-columns: 1fr; }
  .stat-n[b-32ry10ci0n] { font-size: 2.1rem; }
  .time-row[b-32ry10ci0n] { grid-template-columns: 64px 1fr; }
  .time-o[b-32ry10ci0n] { grid-column: 2; white-space: normal; }
  /* The decision chain stacks; the ordered list carries the sequence, so the
     connecting arrows retire with the horizontal layout. */
  .chain[b-32ry10ci0n] { grid-template-columns: 1fr; gap: 8px; }
  .step + .step[b-32ry10ci0n]::before { content: none; }
}

@media (max-width: 640px) {
  .pp9 h1 br[b-32ry10ci0n] { display: none; }
}

@media (max-width: 460px) {
  .lens-grid[b-32ry10ci0n] { grid-template-columns: 1fr; }
  .lens[b-32ry10ci0n] { min-height: 0; }
  .pp9 h1[b-32ry10ci0n] { font-size: clamp(2.3rem, 11.5vw, 3rem); }
}

@media (prefers-reduced-motion: reduce) {
  /* The station highlight is four animations sharing one phase, so all four
     have to die here: killing only the card frame would leave a name, a number
     and an icon cycling on their own. Every animated property falls back to a
     resting value that is already declared, so the six stations land in the
     same legible state instead of one of them staying lit. */
  .dot[b-32ry10ci0n], .lens[b-32ry10ci0n], .lens-top .glyph[b-32ry10ci0n], .lens-no[b-32ry10ci0n], .lens-name[b-32ry10ci0n],
  .lens-grid[b-32ry10ci0n]::after, .desk[b-32ry10ci0n], .mread-item[b-32ry10ci0n] { animation: none !important; }
  .lens-grid[b-32ry10ci0n]::after { opacity: 0; }
  /* Ticker degrades to a static list: first 6 rows, no loop duplicate, no fades. */
  .ticker[b-32ry10ci0n] { height: auto; -webkit-mask-image: none; mask-image: none; }
  .ticker-track[b-32ry10ci0n] { position: static; }
  .ticker-copy[b-32ry10ci0n] { display: none; }
  .ticker-track > .trow:nth-of-type(n+7)[b-32ry10ci0n] { display: none; }
}

/* The home-only local anchor row (#hiring-bar / #about) was removed 2026-08-04.
   It stacked a second grey uppercase rail directly above the pool chip, and
   the telemetry said nobody was being served by it: across 151 real visits the
   only click ever recorded on the whole site is the language toggle, and the
   two sections it pointed at are the least-reached on the page. The section
   ids stay — /ai-method still links to #about. */
/* /Components/Pages/PublicSkills.razor.rz.scp.css */
/* /skills — six-station roster, two acts (understand → verify → trust recast
   2026-08-10). Shares the V9 paper/hairline vocabulary with
   PublicHome.razor.css (scoped CSS cannot be shared across components, so the
   token block is duplicated deliberately; keep values in sync with the home
   and PublicSystemData.razor.css). */
.ppv[b-utip0qgn5q] {
  color-scheme: light;
  --paper: #f6f4ef;
  --panel: #fffdf8;
  --ink: #23262b;
  --ink-soft: #41474b;
  --mut: #596662;
  --dim: #65726e;
  --line: rgba(35, 38, 43, .14);
  --line-soft: rgba(35, 38, 43, .08);
  --teal: #4fd1c5;
  --teal-deep: #0f746c;
  --amber-deep: #8a5f00;
  --coral-deep: #b2503f;
  --cta: #d97757;
  --serif: Georgia, "Times New Roman", serif;
  --sans: "Inter", "Noto Sans TC", "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", Consolas, monospace;

  display: block;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
}
.ppv *[b-utip0qgn5q],
.ppv *[b-utip0qgn5q]::before,
.ppv *[b-utip0qgn5q]::after { box-sizing: border-box; }
.ppv [b-utip0qgn5q]::selection { background: rgba(79, 209, 197, .3); }
.ppv a[b-utip0qgn5q] { color: inherit; }
:where(.ppv) :where(h1, h2, h3, p, ol, ul, dl, dd, figure)[b-utip0qgn5q] { margin: 0; padding: 0; }

.ppv-wrap[b-utip0qgn5q] {
  max-width: 1360px;
  margin: 0 auto;
  border-inline: 1px solid var(--line);
  padding-inline: clamp(20px, 3.4vw, 48px);
}
.ppv-sec[b-utip0qgn5q] { border-bottom: 1px solid var(--line); }

/* ===== headings =====
   2026-08-05 owner ruling: the h1 is visible (same words) — the reader holds
   the "six stages" frame before the selector. FocusOnNavigate still lands on it. */
.sk-h1[b-utip0qgn5q] {
  margin-bottom: 14px;
  font-family: var(--serif);
  font-size: clamp(1.5rem, 2.6vw, 2.05rem);
  line-height: 1.25;
  letter-spacing: -.014em;
  color: var(--ink);
}
/* "What's a Skill" — the definition opens the section, so a cold reader
   meets the mechanism before the six stages that run on it. On desktop the
   lead band puts it beside the H1 so the module starts higher. */
.sk-lead[b-utip0qgn5q] { margin-bottom: 0; }
/* Act 1 core sentence (2026-08-10): the one-off-prompt contrast replaced the
   labeled Skill definition — the sentence self-labels, no kicker needed. */
.sk-def[b-utip0qgn5q] { margin-bottom: 14px; }
.sk-def p[b-utip0qgn5q] {
  font-size: .95rem;
  line-height: 1.62;
  color: var(--ink-soft);
  /* round 6: 60ch left the block looking half-set against a ~900px column */
  max-width: 78ch;
}

/* ===== roster module (2026-08-05 ruling) =====
   Single markup, two layouts: base = mobile exclusive accordion
   (workflow-drawer parent); ≥980px regrids the same DOM into a left
   six-stage selector rail + one fixed right detail panel. */
.sk-roster-wrap[b-utip0qgn5q] { padding-block: clamp(20px, 2.6vw, 34px); }

/* slide — lives inside each drawer/panel (and the rest-state overview).
   2026-08-09 ruling: the outer card frame (border + padding + fill) retired;
   only the inner grid-paper art keeps its hairline. */
.sk-slide[b-utip0qgn5q] { border: 0; background: none; padding: 0; }
.sk-slide-cap[b-utip0qgn5q] { display: block; margin-bottom: 10px; }
.sk-slide-stage[b-utip0qgn5q] {
  display: block;
  font-family: var(--mono);
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--coral-deep);
}
.sk-slide-story[b-utip0qgn5q] {
  display: block;
  margin-top: 6px;
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .02em;
  color: var(--mut);
}
.sk-slide-art[b-utip0qgn5q] {
  border: 1px solid var(--line-soft);
  background:
    linear-gradient(var(--line-soft) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-soft) 1px, transparent 1px),
    var(--paper);
  background-size: 24px 24px;
}
.sk-slide-art svg[b-utip0qgn5q] { display: block; width: 100%; height: auto; animation: sk-fade-b-utip0qgn5q .28s ease; }
@keyframes sk-fade-b-utip0qgn5q { from { opacity: 0; } to { opacity: 1; } }

/* the rest-state overview panel renders only when every row is closed;
   the mobile accordion needs no rest panel */
.sk-overview[b-utip0qgn5q] { display: none; }

/* slide drawing vocabulary — hand-drawn hairline strokes on paper */
.sk-slide-art text[b-utip0qgn5q] {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .08em;
  fill: var(--mut);
}
.sk-slide-art text.t-small[b-utip0qgn5q] { font-weight: 400; letter-spacing: .04em; }
.sk-slide-art text.t-ink[b-utip0qgn5q] { fill: var(--ink); }
.sk-slide-art text.t-teal[b-utip0qgn5q] { fill: var(--teal-deep); }
.sk-slide-art text.t-coral[b-utip0qgn5q] { fill: var(--coral-deep); }
.sk-slide-art .s-ink[b-utip0qgn5q] { stroke: var(--ink); }
.sk-slide-art .s-mut[b-utip0qgn5q] { stroke: var(--mut); }
.sk-slide-art .s-teal[b-utip0qgn5q] { stroke: var(--teal-deep); }
.sk-slide-art .s-coral[b-utip0qgn5q] { stroke: var(--cta); }
.sk-slide-art .f-ink[b-utip0qgn5q] { fill: var(--ink); }
.sk-slide-art .f-inksoft[b-utip0qgn5q] { fill: rgba(35, 38, 43, .55); }
.sk-slide-art .f-mut[b-utip0qgn5q] { fill: rgba(117, 129, 126, .55); }
.sk-slide-art .f-teal[b-utip0qgn5q] { fill: var(--teal-deep); }
.sk-slide-art .f-coral[b-utip0qgn5q] { fill: var(--cta); }
.sk-slide-art .card[b-utip0qgn5q] { fill: var(--panel); }

/* stage rows — mono eyebrow, headline-sized buyer outcome, handoff phrase.
   Base layout = mobile exclusive accordion with the 40px plus marker; the
   roster script is the only scroll actor there, so the browser's native
   scroll anchoring stays out of the compensation. */
.sk-board[b-utip0qgn5q] { border-top: 1px solid var(--line); overflow-anchor: none; }
.sk-row[b-utip0qgn5q] { border-bottom: 1px solid var(--line); }
.sk-row-h[b-utip0qgn5q] { margin: 0; }
.sk-head[b-utip0qgn5q] {
  display: flex;
  align-items: center;
  gap: 24px;
  width: 100%;
  padding: 20px 2px;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.sk-head:hover[b-utip0qgn5q] { background: var(--panel); }
.sk-head:focus-visible[b-utip0qgn5q] {
  outline: 2px solid var(--coral-deep);
  outline-offset: -2px;
}
.sk-headmain[b-utip0qgn5q] { flex: 1 1 auto; min-width: 0; }
/* line 1 of the scan layer: stage eyebrow left, handoff right (Koso
   index-row grammar); wraps gracefully when both are long */
.sk-rowtop[b-utip0qgn5q] {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 2px 14px;
}
.sk-rolek[b-utip0qgn5q] {
  display: block;
  font-family: var(--mono);
  font-size: .64rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--mut);
}
.sk-outcome[b-utip0qgn5q] {
  display: block;
  margin-top: 6px;
  font-family: var(--serif);
  font-size: clamp(1.2rem, 2vw, 1.6rem);
  line-height: 1.3;
  letter-spacing: -.012em;
  color: var(--ink);
  max-width: 30em;
}
/* 40×40 plus / minus marker (koso pattern): neutral hairline at rest, the
   whole box inverts to solid ink on hover — size and response carry the
   "this opens" invitation, no color needed. */
.sk-plus[b-utip0qgn5q] {
  position: relative;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  transition: background .15s ease, border-color .15s ease;
}
.sk-head:hover .sk-plus[b-utip0qgn5q],
.sk-head:focus-visible .sk-plus[b-utip0qgn5q] {
  background: var(--ink);
  border-color: var(--ink);
}
.sk-plus[b-utip0qgn5q]::before,
.sk-plus[b-utip0qgn5q]::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--ink);
  transform: translate(-50%, -50%);
  transition: background .15s ease, opacity .15s ease;
}
.sk-head:hover .sk-plus[b-utip0qgn5q]::before,
.sk-head:hover .sk-plus[b-utip0qgn5q]::after,
.sk-head:focus-visible .sk-plus[b-utip0qgn5q]::before,
.sk-head:focus-visible .sk-plus[b-utip0qgn5q]::after { background: var(--paper); }
.sk-plus[b-utip0qgn5q]::before { width: 14px; height: 1.6px; }
/* the upright bar fades out on open, so + reads as − */
.sk-plus[b-utip0qgn5q]::after { width: 1.6px; height: 14px; }
.sk-row.is-open .sk-plus[b-utip0qgn5q]::after { opacity: 0; }

/* drawer body: instant open/close (koso feel). display:none keeps collapsed
   content out of the accessibility tree and tab order; flow-root contains the
   children's margins so the anchoring script's height measure is exact. */
.sk-drawer[b-utip0qgn5q] { display: none; }
.sk-row.is-open .sk-drawer[b-utip0qgn5q] { display: flow-root; }
.sk-drawer-in .sk-slide[b-utip0qgn5q] { margin-bottom: 16px; }

/* stage walker — one Next button at the panel foot (none on 06) */
.sk-next[b-utip0qgn5q] {
  display: inline-block;
  flex: 0 0 auto;
  margin: 0;
  padding: 9px 14px;
  border: 1px solid var(--line);
  background: none;
  font-family: var(--mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.sk-next:hover[b-utip0qgn5q] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.sk-next:focus-visible[b-utip0qgn5q] { outline: 2px solid var(--coral-deep); outline-offset: 2px; }

/* fixed three-question grammar (2026-08-10 recast) — mono label + answer
   rows; the same ruler on all six stations */
.sk-qa[b-utip0qgn5q] {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2px;
  margin-top: 14px;
}
.sk-qa dt[b-utip0qgn5q] {
  font-family: var(--mono);
  font-size: .64rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mut);
  padding-top: 10px;
}
.sk-qa dd[b-utip0qgn5q] {
  font-size: .95rem;
  line-height: 1.62;
  color: var(--ink-soft);
  max-width: 56ch;
}

/* related Skill chips (03 / 05 only) — breadth proof, quieter than the lead
   button below them */
.sk-related[b-utip0qgn5q] {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  margin-top: 14px;
}
.sk-related-k[b-utip0qgn5q] {
  font-family: var(--mono);
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--mut);
}
.sk-related-chip[b-utip0qgn5q] {
  padding: 4px 10px;
  border: 1px solid var(--line);
  background: var(--panel);
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .04em;
  color: var(--teal-deep);
  text-decoration: none;
  white-space: nowrap;
}
.sk-related-chip:hover[b-utip0qgn5q] { border-color: var(--teal-deep); }
.sk-related-chip:focus-visible[b-utip0qgn5q] { outline: 2px solid var(--coral-deep); outline-offset: 2px; }

/* lead Skill deep link — the station's verification door; the panel tail's
   one strong affordance */
.ppv a.sk-lead-btn[b-utip0qgn5q] {
  display: block;
  margin-top: 16px;
  padding: 12px 16px;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  text-align: center;
  text-decoration: none;
  font-family: var(--mono);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  transition: background .15s ease, color .15s ease;
}
.ppv a.sk-lead-btn:hover[b-utip0qgn5q] { background: var(--paper); color: var(--ink); }
.ppv a.sk-lead-btn:focus-visible[b-utip0qgn5q] { outline: 2px solid var(--coral-deep); outline-offset: 2px; }

/* panel foot: the stage walker stands alone (2026-08-09) */
.sk-foot[b-utip0qgn5q] {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin: 4px 2px 16px 0;
}

/* ===== closing band: loop only ===== */
.sk-loop-wrap[b-utip0qgn5q] { padding-block: clamp(24px, 3vw, 38px); }
.sk-loopchain[b-utip0qgn5q] {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--ink-soft);
}
.sk-loopchain .sk-ln b[b-utip0qgn5q] {
  font-weight: 700;
  color: var(--mut);
  margin-right: 4px;
}
.sk-la[b-utip0qgn5q] { color: var(--dim); }
.sk-lback[b-utip0qgn5q] {
  margin-left: 6px;
  padding: 3px 9px;
  border: 1px solid rgba(178, 80, 63, .4);
  color: var(--coral-deep);
  font-weight: 700;
}
/* loop close (2026-08-10 recast): the band absorbs the retired rail's
   identity — avatar + name, the orchestration sentence, one loop note */
.sk-loop-id[b-utip0qgn5q] {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 20px;
}
.sk-loop-avatar[b-utip0qgn5q] {
  width: 40px;
  height: 40px;
  border-radius: 999px;
  object-fit: cover;
  border: 1px solid var(--line);
}
.sk-loop-name[b-utip0qgn5q] {
  font-family: var(--mono);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
}
.sk-orchline[b-utip0qgn5q] {
  margin-top: 10px;
  font-family: var(--serif);
  font-size: clamp(1.06rem, 1.6vw, 1.3rem);
  line-height: 1.55;
  color: var(--ink);
  max-width: 92ch;
}
.sk-loopnote[b-utip0qgn5q] {
  margin-top: 12px;
  font-size: clamp(1rem, 1.4vw, 1.12rem);
  line-height: 1.62;
  color: var(--ink-soft);
  max-width: 92ch;
}
.sk-roster-link[b-utip0qgn5q] {
  display: inline-block;
  margin-top: 18px;
  font-family: var(--mono);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--coral-deep);
  text-decoration: none;
  border-bottom: 1px solid rgba(178, 80, 63, .4);
  padding-bottom: 2px;
}
.sk-roster-link:hover[b-utip0qgn5q] { color: var(--ink); border-bottom-color: var(--ink); }
.sk-roster-link:focus-visible[b-utip0qgn5q] {
  outline: 2px solid var(--coral-deep);
  outline-offset: 3px;
}

/* ===== Act 2 · How I turn judgment into Skills (2026-08-10 recast) =====
   One header (the eyebrow/thesis pair retired), the lifecycle chain band,
   five divided-cell method cards. The header is an h2 — the page keeps its
   single h1 in Act 1. */
.ppv-head[b-utip0qgn5q] { padding-block: clamp(36px, 5vw, 64px) clamp(24px, 3.2vw, 40px); }
.ppv-thesis[b-utip0qgn5q] {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 3vw, 2.6rem);
  line-height: 1.14;
  letter-spacing: -.016em;
}

/* chain band: the 3-second scan layer as a full-width hairline strip; the
   last node closes the loop */
.chain-band[b-utip0qgn5q] { border-block: 1px solid var(--line); background: var(--panel); }
.trace[b-utip0qgn5q] {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 0;
  padding-block: clamp(14px, 1.8vw, 20px);
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
}
.trace li[b-utip0qgn5q] { display: inline-flex; align-items: center; }
.trace li + li[b-utip0qgn5q]::before { content: "\2192"; margin-inline: 12px; color: var(--teal-deep); }
.trace li.trace-loop[b-utip0qgn5q]::before { content: "\21ba"; color: var(--amber-deep); }
.trace li.trace-loop[b-utip0qgn5q] { color: var(--amber-deep); }

/* the five method cards — one flat level, divided cells (Koso grammar):
   1px seams make the cards read as one engineering table; an odd last card
   spans the row */
.ppv-notes[b-utip0qgn5q] { padding-block: clamp(30px, 4vw, 50px) clamp(24px, 3vw, 36px); }
.notes-grid[b-utip0qgn5q] {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
.note-card:last-child:nth-child(odd)[b-utip0qgn5q] { grid-column: 1 / -1; }
.note-card:last-child:nth-child(odd) p[b-utip0qgn5q] { max-width: 78ch; }
.note-card[b-utip0qgn5q] {
  background: var(--panel);
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
}
.note-card .acc-close[b-utip0qgn5q] { margin-top: auto; padding-top: 12px; }
.note-card .tick[b-utip0qgn5q] { font-family: var(--mono); font-size: .58rem; letter-spacing: .14em; text-transform: uppercase; color: var(--mut); margin-bottom: 8px; }
.note-card .at[b-utip0qgn5q] { display: block; font-weight: 750; font-size: 1.02rem; letter-spacing: -.015em; line-height: 1.4; margin-bottom: 8px; }
.note-card p[b-utip0qgn5q] { font-size: .88rem; line-height: 1.65; color: #41474b; max-width: 78ch; }
.note-card p + p[b-utip0qgn5q] { margin-top: 9px; }
.note-card ol[b-utip0qgn5q], .note-card ul[b-utip0qgn5q] { padding-left: 20px; margin-top: 9px; font-size: .88rem; line-height: 1.7; color: #41474b; }
.note-card li + li[b-utip0qgn5q] { margin-top: 5px; }
.note-card .acc-close[b-utip0qgn5q] { font-family: var(--mono); font-size: .72rem; letter-spacing: .04em; color: var(--amber-deep); line-height: 1.7; }

@media (max-width: 960px) {
  .notes-grid[b-utip0qgn5q] { grid-template-columns: 1fr; }
}

/* ===== footer (shared vocabulary with the other public views) ===== */
.ppv-foot[b-utip0qgn5q] { border-bottom: 0; }
.foot-bar[b-utip0qgn5q] {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  align-items: center;
  justify-content: space-between;
  padding-block: 20px 26px;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--mut);
}
.foot-bar a[b-utip0qgn5q] { text-decoration: none; color: var(--mut); }
.foot-bar a:hover[b-utip0qgn5q] { color: var(--ink); }
.foot-links[b-utip0qgn5q] { display: flex; gap: 22px; }
.foot-privacy[b-utip0qgn5q] {
  margin-top: -8px;
  font-family: var(--mono);
  font-size: .56rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
  line-height: 1.8;
}
.foot-fresh[b-utip0qgn5q] {
  padding-bottom: 24px;
  padding-top: 6px;
  font-family: var(--mono);
  font-size: .56rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1.8;
}
.foot-fresh a[b-utip0qgn5q] { text-decoration: none; color: var(--dim); }
.foot-fresh a:hover[b-utip0qgn5q] { color: var(--ink); }

/* ===== desktop ≥980px: six-stage selector rail + fixed detail panel =====
   Same DOM as the mobile accordion: each article turns display:contents, its
   header lands in the left grid column, its drawer (only one is open) spans
   the right column — a fixed panel instead of an inline drawer. The 1fr tail
   row absorbs any panel height beyond the six headers. */
@media (min-width: 980px) {
  /* lead band: H1 left, definition right — the two columns mirror the board
     below so the def sits over the panel */
  .sk-lead[b-utip0qgn5q] {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: clamp(22px, 3vw, 44px);
    align-items: start;
    margin-bottom: 4px;
  }
  .sk-lead .sk-h1[b-utip0qgn5q] { margin-bottom: 0; }
  .sk-lead .sk-def[b-utip0qgn5q] { margin-bottom: 0; }
  .sk-board[b-utip0qgn5q] {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    grid-template-rows: repeat(6, max-content) 1fr;
    column-gap: clamp(22px, 3vw, 44px);
  }
  .sk-row[b-utip0qgn5q] { display: contents; }
  .sk-row-h[b-utip0qgn5q] { grid-column: 1; border-bottom: 1px solid var(--line); }
  .sk-head[b-utip0qgn5q] { padding: 13px 14px; }
  /* compact rail type: the two-line rows keep the whole rail near one screen */
  .sk-outcome[b-utip0qgn5q] { font-size: clamp(1.08rem, 1.1vw, 1.26rem); margin-top: 4px; }
  /* selection grammar replaces expand/collapse: no plus marker on desktop */
  .sk-plus[b-utip0qgn5q] { display: none; }
  /* the open row inverts solid (Koso active-row grammar): the six rows read
     as one selected + five unselected, not as a static index */
  .sk-row.is-open .sk-head[b-utip0qgn5q],
  .sk-row.is-open .sk-head:hover[b-utip0qgn5q] { background: var(--ink); }
  .sk-row.is-open .sk-rolek[b-utip0qgn5q] { color: rgba(246, 244, 239, .72); }
  .sk-row.is-open .sk-outcome[b-utip0qgn5q] { color: var(--paper); }
  /* one panel area: every drawer and the rest-state overview share it.
     Sticky keeps the panel in view while the reader scans the lower rows —
     the sticky top clears the 117px site nav. */
  .sk-overview[b-utip0qgn5q],
  .sk-drawer[b-utip0qgn5q] {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: start;
    position: sticky;
    top: 129px;
  }
  .sk-overview[b-utip0qgn5q] { display: block; }
  .sk-row.is-open .sk-drawer[b-utip0qgn5q] {
    border: 1px solid var(--line);
    background: var(--panel);
  }
  .sk-drawer-in[b-utip0qgn5q] { padding: 18px 20px 6px; }
  /* cap the slide card so the SVG stops scaling with the 7fr column —
     uncapped it alone ate 400px of panel height */
  .sk-board .sk-slide[b-utip0qgn5q] { max-width: 480px; }
  .sk-qa[b-utip0qgn5q] {
    grid-template-columns: 176px minmax(0, 1fr);
    gap: 12px 18px;
  }
  .sk-qa dt[b-utip0qgn5q] { padding-top: 3px; }
}

@media (max-width: 640px) {
  .sk-head[b-utip0qgn5q] { gap: 14px; padding-block: 16px; }
  .sk-outcome[b-utip0qgn5q] { font-size: 1.14rem; }
  .sk-plus[b-utip0qgn5q] { width: 34px; height: 34px; }
}

/* ===== reduced motion ===== */
@media (prefers-reduced-motion: reduce) {
  .sk-slide-art svg[b-utip0qgn5q] { animation: none; }
  .sk-plus[b-utip0qgn5q],
  .sk-plus[b-utip0qgn5q]::before,
  .sk-plus[b-utip0qgn5q]::after { transition: none; }
  .sk-next[b-utip0qgn5q] { transition: none; }
}

/* ---- 2026-08-10 Shape B voice lead (spoken-spine) ----
   Neutral hairline left border = Johanna speaking; action sentence 700,
   motive tail 400. */
.sk-voice[b-utip0qgn5q] {
  margin: 14px 0 0;
  padding: 2px 0 2px 14px;
  border-left: 2px solid rgba(35, 38, 43, .4);
  font-size: 16.5px;
  font-weight: 700;
  line-height: 1.7;
  color: var(--ink);
}
.sk-voice-soft[b-utip0qgn5q] { font-weight: 400; color: var(--ink-soft); }

/* ---- 2026-08-10 Gate 1 feedback: bigger station names ---- */
.sk-rolek[b-utip0qgn5q] { font-size: 14px; }

/* ---- 2026-08-10 header stack: H1 + core line as one two-line lockup ---- */
.sk-lead[b-utip0qgn5q] { display: block; }
.sk-lead .sk-def[b-utip0qgn5q] { margin: 8px 0 0; max-width: 760px; }

/* ---- 2026-08-10 Gate 1 round 4 (koso reference): row arrow affordance +
   drawer content rises from below on station switch. ---- */
.sk-arrow[b-utip0qgn5q] {
  margin-left: auto;
  opacity: .35;
  transition: opacity .15s ease, transform .15s ease;
}
.sk-head:hover .sk-arrow[b-utip0qgn5q] { opacity: .7; transform: translateX(2px); }
.sk-row.is-open .sk-arrow[b-utip0qgn5q] { opacity: 1; color: #fff; transform: translateX(3px); }
.sk-rowtop[b-utip0qgn5q] { display: flex; align-items: center; gap: 10px; }
.sk-row.is-open .sk-drawer-in > *[b-utip0qgn5q] { animation: skRise-b-utip0qgn5q .38s ease both; }
.sk-row.is-open .sk-drawer-in > *:nth-child(2)[b-utip0qgn5q] { animation-delay: .05s; }
.sk-row.is-open .sk-drawer-in > *:nth-child(3)[b-utip0qgn5q] { animation-delay: .1s; }
.sk-row.is-open .sk-drawer-in > *:nth-child(4)[b-utip0qgn5q] { animation-delay: .15s; }
.sk-row.is-open .sk-drawer-in > *:nth-child(5)[b-utip0qgn5q] { animation-delay: .2s; }
.sk-row.is-open .sk-drawer-in > *:nth-child(6)[b-utip0qgn5q] { animation-delay: .25s; }
.sk-row.is-open .sk-drawer-in > *:nth-child(7)[b-utip0qgn5q] { animation-delay: .3s; }
@keyframes skRise-b-utip0qgn5q {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .sk-row.is-open .sk-drawer-in > *[b-utip0qgn5q] { animation: none; }
  .sk-arrow[b-utip0qgn5q], .sk-head:hover .sk-arrow[b-utip0qgn5q] { transition: none; transform: none; }
}
/* arrow rides the right edge (stage chips retired 2026-08-10 recast) */
.sk-arrow[b-utip0qgn5q] { margin-left: auto; }
/* /Components/Pages/PublicSystemData.razor.rz.scp.css */
/* Three-view IA deep view — shares the V9 paper/hairline vocabulary with
   PublicHome.razor.css (scoped CSS cannot be shared across components, so the
   token block is duplicated deliberately; keep values in sync with the home
   and with PublicAiMethod.razor.css). */
.ppv[b-5jbzknire0] {
  color-scheme: light;
  --paper: #f6f4ef;
  --panel: #fffdf8;
  --ink: #23262b;
  --mut: #596662;
  --dim: #65726e;
  --line: rgba(35, 38, 43, .14);
  --line-soft: rgba(35, 38, 43, .08);
  --teal: #4fd1c5;
  --teal-deep: #0f746c;
  --amber-deep: #8a5f00;
  --coral-deep: #b2503f;
  --cta: #d97757;
  --serif: Georgia, "Times New Roman", serif;
  --sans: "Inter", "Noto Sans TC", "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", Consolas, monospace;

  display: block;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
}
.ppv *[b-5jbzknire0],
.ppv *[b-5jbzknire0]::before,
.ppv *[b-5jbzknire0]::after { box-sizing: border-box; }
.ppv [b-5jbzknire0]::selection { background: rgba(79, 209, 197, .3); }
.ppv a[b-5jbzknire0] { color: inherit; }
:where(.ppv) :where(h1, h2, h3, p, ol, ul, figure)[b-5jbzknire0] { margin: 0; padding: 0; }

.ppv-wrap[b-5jbzknire0] {
  max-width: 1360px;
  margin: 0 auto;
  border-inline: 1px solid var(--line);
  padding-inline: clamp(20px, 3.4vw, 48px);
}
.ppv-sec[b-5jbzknire0] { border-bottom: 1px solid var(--line); }

.sd-sr-only[b-5jbzknire0] {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  clip-path: inset(50%);
}

/* ===== receipt-section headers (01 data model / 02 architecture) =====
   eyebrow + serif claim, mirroring the ai-method playbook header vocabulary. */
/* tightened 2026-08-04; retightened 2026-08-05 with the collapsed preview so
   the 02 eyebrow clears the fold at 1280×800 as well as 1440×900 */
.sd-block[b-5jbzknire0] { padding-block: clamp(20px, 2.5vw, 34px); }
.sd-eyebrow[b-5jbzknire0] {
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--mut);
  margin-bottom: 12px;
}
.sd-h[b-5jbzknire0] {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 2.6vw, 2rem);
  line-height: 1.2;
  letter-spacing: -.014em;
  max-width: 30em;
}
.sd-sub[b-5jbzknire0] {
  margin-top: 10px;
  font-family: var(--serif);
  font-size: clamp(1.1rem, 1.6vw, 1.32rem);
  line-height: 1.45;
  letter-spacing: -.008em;
  color: #41474b;
  /* wide enough to hold the lifecycle chain on one line at desktop; when it
     does wrap, `pretty` keeps a lone trailing word off the second line. */
  max-width: 50em;
  text-wrap: pretty;
}
.sd-spec[b-5jbzknire0] {
  margin-top: 10px;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .1em;
  color: var(--mut);
}

/* ===== schema scale contrast =====
   Two readable rows, not a dashboard card: "production schema 24 · shown here
   7" says the system is real AND the slice is chosen. Every number comes from
   the generator's schema-facts.json — never typed by hand. */
.sd-scale[b-5jbzknire0] {
  display: grid;
  gap: 5px;
  margin: 10px 0 0;
}
.sd-scale > div[b-5jbzknire0] { display: flex; align-items: baseline; gap: 16px; }
.sd-scale dt[b-5jbzknire0] {
  font-family: var(--mono);
  font-size: .62rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--amber-deep);
  min-width: 12em;
}
.sd-scale dd[b-5jbzknire0] {
  margin: 0;
  font-family: var(--mono);
  font-size: .8rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ===== PostgreSQL data model — lifecycle overview =====
   The in-page artifact is the generator-built lifecycle overview. On desktop it
   starts as a collapsed preview (2026-08-05 evening owner call, superseding the
   8/4 "no crop, no expand": that ruling guarded a document-grade ERD whose
   Marketing story was invisible; this artifact carries the story in its upper
   half). The crop line is gate-driven, not aesthetic: stage bands, CRM anchors
   and all seven table names stay visible collapsed — viewBox is 1240×444 and
   the deepest table title (linkedin_messages) sits at y≈282, so a 310px stage
   (12px padding + ~298px of a 443px-tall render at full page width → crop at
   viewBox y≈299) keeps every title on screen while the hidden strip is only
   lower field rows; narrower viewports render the SVG shorter and show more.
   Mobile never collapses. Clicking the stage or the foot link still opens the
   full-size detailed ERD, which keeps types, nullability and referential
   actions at documentation density. */
.perd[b-5jbzknire0] { margin-top: clamp(12px, 1.6vw, 18px); }
@media (min-width: 901px) {
  .perd-stage[b-5jbzknire0] { position: relative; }
  .perd-collapsed[b-5jbzknire0] { max-height: 310px; overflow: hidden; }
  /* short fade, honest about "there is more below" without eating the cards —
     32px keeps the deepest table title (≈17px above the crop) readable; the
     reveal button below carries the affordance, the fade only softens the cut.
     The mask lives on the stage in both states so expanding dissolves it over
     320ms of opacity — the stage height itself is never animated (reflow);
     reduced-motion kills the transition below. */
  .perd-stage[b-5jbzknire0]::after {
    content: "";
    position: absolute;
    left: 1px;
    right: 1px;
    bottom: 0;
    height: 32px;
    background: linear-gradient(to bottom, rgba(246, 244, 239, 0), var(--paper));
    pointer-events: none;
    opacity: 0;
    transition: opacity 320ms ease;
  }
  .perd-collapsed[b-5jbzknire0]::after { opacity: 1; }
}
/* The reveal is a first-class, full-width control — not a gradient hint. It
   sits between the stage and the caption bar so the two "see more" moves stay
   distinct: inline expand = finish this overview; the modal = read the
   documentation-density ERD. Hidden on mobile, where nothing is clipped. */
.perd-reveal[b-5jbzknire0] {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  appearance: none;
  border: 1px solid var(--line);
  border-top: 0;
  background: var(--panel);
  padding: 7px 16px;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .06em;
  color: var(--teal-deep);
  cursor: pointer;
}
.perd-reveal:hover[b-5jbzknire0] { color: var(--ink); }
@media (max-width: 900px) { .perd-reveal[b-5jbzknire0] { display: none; } }
/* the stage and foot link are <button>s now — they open the in-page ERD
   window instead of navigating to a bare SVG tab. */
.perd-stage[b-5jbzknire0] {
  display: block;
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  border: 1px solid var(--line);
  background: var(--paper);
  padding: clamp(8px, 1vw, 12px);
  appearance: none;
  font: inherit;
  color: inherit;
  text-align: inherit;
  cursor: zoom-in;
}
.perd-stage img[b-5jbzknire0] {
  display: block;
  width: 100%;
  min-width: 880px;
  height: auto;
}
.perd-foot[b-5jbzknire0] {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 24px;
  border: 1px solid var(--line);
  border-top: 0;
  background: var(--panel);
  padding: 8px 16px;
}
.perd-cap[b-5jbzknire0] {
  font-family: var(--mono);
  font-size: .68rem;
  color: var(--mut);
  line-height: 1.6;
}
.perd-open[b-5jbzknire0] {
  appearance: none;
  border: 0;
  padding: 0;
  background: none;
  font-family: var(--mono);
  font-size: .68rem;
  color: var(--teal-deep);
  text-decoration: underline;
  text-underline-offset: 4px;
  white-space: nowrap;
  cursor: pointer;
}
.perd-open:hover[b-5jbzknire0] { color: var(--ink); }

/* ===== full-size ERD window internals =====
   Rendered inside the Telerik root, outside .ppv — so no var() tokens here;
   the literals mirror the page palette. The image keeps its natural 1600px
   width and the stage scrolls both ways. */
.erd-window-scroll[b-5jbzknire0] {
  overflow: auto;
  height: 100%;
  background: #f6f4ef;
}
.erd-window-img[b-5jbzknire0] {
  display: block;
  width: 1600px;
  max-width: none;
  height: auto;
}
.erd-window-foot[b-5jbzknire0] {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 24px;
  width: 100%;
  font-family: "JetBrains Mono", Consolas, monospace;
  font-size: .68rem;
  color: #75817e;
}
.erd-window-foot a[b-5jbzknire0] { color: #0f746c; text-underline-offset: 4px; }
.erd-window-foot a:hover[b-5jbzknire0] { color: #23262b; }

/* ===== system architecture =====
   Four core subjects, one output removed (2026-08-05 evening owner call: the
   public site left the diagram — a manual does not draw itself; provenance is
   carried by the database node, the boundary by 01's caption and the figure
   caption). Supabase Postgres + SQL views stands as a vertical spine on the
   right; on the left sit the decision workbench and, below it, the operating
   loop (human gate coral, skills teal), which reads evidence and writes only
   after release. One read-only pipe, one governed write pipe — the asymmetry
   between "reads" and "writes only after release" is the whole claim. Below
   900px the spine folds back into the vertical stack. */
.arch[b-5jbzknire0] { margin-top: clamp(24px, 3.2vw, 38px); }
/* The spine holds the load-bearing claim (single source of truth) and the
   longest body copy, so it gets a column wide enough to keep its title on one
   line — at 260px it was a third of the frontend node's measure and wrapped to
   five lines of 13px. */
.arch-grid[b-5jbzknire0] {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(160px, 12vw, 176px) minmax(288px, 304px);
  grid-template-rows: auto 28px auto;
}
.b-back[b-5jbzknire0] { grid-area: 1 / 1; }
.p-read[b-5jbzknire0] { grid-area: 1 / 2; }
.arch-spine[b-5jbzknire0] { grid-area: 1 / 3 / 4 / 4; }
.arch-flows[b-5jbzknire0] { grid-area: 3 / 2; }
.b-loop[b-5jbzknire0] { grid-area: 3 / 1; }
.arch-band[b-5jbzknire0] {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  column-gap: 16px;
}
.arch-spine[b-5jbzknire0] { display: flex; flex-direction: column; }
.arch-spine .arch-lt[b-5jbzknire0] { padding-top: 0; margin-bottom: 8px; }
.arch-spine .arch-node[b-5jbzknire0] { flex: 1; align-content: center; }
.arch-pipe[b-5jbzknire0] {
  position: relative;
  align-self: center;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding-inline: 4px;
}
.arch-pipe[b-5jbzknire0]::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  border-top: 1.4px solid var(--teal-deep);
}
.arch-pipe[b-5jbzknire0]::after {
  content: "";
  position: absolute;
  right: -1px;
  top: 50%;
  transform: translateY(-50%);
  border-top: 3.6px solid transparent;
  border-bottom: 3.6px solid transparent;
  border-left: 5.5px solid var(--teal-deep);
}
.arch-pipe span[b-5jbzknire0] {
  position: relative;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .04em;
  color: var(--teal-deep);
  line-height: 1.5;
  text-align: center;
  background: var(--paper);
  padding-inline: 8px;
}
/* ===== two lanes, one cell (2026-08-10) =====
   The loop↔database exchange used to ride a single line whose one arrow had to
   carry both directions. The causal split gives each direction its own lane in
   the same grid cell: evidence flows out of Postgres into the loop (teal,
   arrow left), and the write path leaves the loop through the gate before it
   reaches Postgres (coral, arrow right). The geometry now states the
   asymmetry the old combined label only implied, without relying on colour. */
.arch-flows[b-5jbzknire0] {
  align-self: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.arch-flows .arch-pipe[b-5jbzknire0] { min-height: 40px; }
.p-evidence[b-5jbzknire0]::after {
  left: -1px;
  right: auto;
  border-left: 0;
  border-right: 5.5px solid var(--teal-deep);
}
/* The write lane is the governed path (2026-08-05 owner call): read lanes stay
   teal — machine-safe reads — while the write line answers in coral, the colour
   this page already gives the human (avatar ring), because a write only happens
   after Johanna's release. The double-bar gate sits at the head of the write
   lane: the path out of the loop passes it before anything reaches Postgres. */
.p-write[b-5jbzknire0]::before { border-top-color: var(--coral-deep); }
.p-write[b-5jbzknire0]::after { border-left-color: var(--coral-deep); }
.p-write span[b-5jbzknire0] { color: var(--coral-deep); }
.arch-gate[b-5jbzknire0] {
  display: inline-block;
  position: relative;
  width: 9px;
  height: 10px;
  margin-inline: 2px;
  vertical-align: -1px;
}
.arch-gate[b-5jbzknire0]::before,
.arch-gate[b-5jbzknire0]::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1.6px;
  background: var(--coral-deep);
}
.arch-gate[b-5jbzknire0]::before { left: 2px; }
.arch-gate[b-5jbzknire0]::after { right: 2px; }
.arch-lt[b-5jbzknire0] {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--dim);
  line-height: 1.5;
  padding-top: 8px;
}
.arch-pair[b-5jbzknire0] {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  column-gap: 14px;
  align-items: center;
}
.arch-node[b-5jbzknire0] {
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 13px 16px;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  column-gap: 12px;
  align-items: start;
}
/* The workbench keeps the grey surface rail: it is where the work becomes
   visible, while the coral/teal rails below mark where the work happens. */
.arch-surface[b-5jbzknire0] { border-left: 3px solid var(--dim); }
.arch-ic[b-5jbzknire0] { width: 20px; height: 20px; color: var(--mut); margin-top: 1px; }
.arch-node b[b-5jbzknire0] {
  display: block;
  font-size: .92rem;
  letter-spacing: -.012em;
  line-height: 1.4;
}
.arch-node p[b-5jbzknire0] {
  font-size: .8rem;
  color: var(--mut);
  line-height: 1.6;
  margin-top: 3px;
}
.arch-human[b-5jbzknire0] { border-left: 3px solid var(--coral-deep); grid-template-columns: 34px minmax(0, 1fr); }
.arch-avatar[b-5jbzknire0] {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid rgba(178, 80, 63, .55);
  box-shadow: 0 0 0 3px rgba(178, 80, 63, .1);
}
/* Agent Skills stays a plain line glyph on purpose: the round-badge pairing
   (tried 2026-08-04) borrowed the avatar's visual grammar, which is the soft
   anthropomorphization the visual brief bans (no agent portraits). Person =
   round photo, written rules = line symbol — the asymmetry is the honest
   statement of what each side is. The glyph itself is the site-wide spark,
   shared with the Skill Roster nav link so both read as the same thing. */
.arch-skill[b-5jbzknire0] { border-left: 3px solid var(--teal-deep); }
.arch-skill .arch-ic[b-5jbzknire0] { color: var(--teal-deep); }
.arch-db[b-5jbzknire0] { border-left: 3px solid var(--ink); }
.arch-db .arch-ic[b-5jbzknire0] { color: var(--ink); }
.arch-x[b-5jbzknire0] {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 10em;
  text-align: center;
  padding-inline: 2px;
}
.arch-x-l[b-5jbzknire0] {
  font-family: var(--mono);
  font-size: .66rem;
  color: var(--mut);
  line-height: 1.55;
}
.arch-x-l[b-5jbzknire0]::before { content: "→ "; color: var(--teal-deep); }
.arch-x-back[b-5jbzknire0]::before { content: "← "; }
.arch-host[b-5jbzknire0] {
  /* These chips flow as inline boxes, and an inline-flex box takes its baseline
     from its first item. A chip whose first item is an <svg> has no baseline to
     offer, so it sat 3.4px above its text-only neighbours once the hosting chip
     joined a row with two of them. Every chip is the same height, so aligning on
     the middle instead of the baseline lines them all up regardless of whether
     they carry a glyph. */
  vertical-align: middle;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 10px;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .04em;
  color: var(--mut);
  border: 1px dashed var(--line);
  border-radius: 999px;
  padding: 3px 11px;
  background: var(--paper);
  white-space: nowrap;
}
.arch-host .arch-ic[b-5jbzknire0] { width: 14px; height: 14px; margin-top: 0; }
/* the four core tables from 01, sitting visibly inside the database node */
.arch-tbls[b-5jbzknire0] { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 11px; }
.arch-tbls span[b-5jbzknire0] {
  font-family: var(--mono);
  font-size: .64rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  border: 1px solid var(--ink);
  padding: 2px 7px;
  background: var(--paper);
  white-space: nowrap;
}
/* Chip spacing rides on the trailing edge, not on the following sibling: with
   four chips the workbench node wraps to a second row, and `+ .arch-host {
   margin-left }` indented that row by 8px against the copy column above it. */
.arch-host[b-5jbzknire0] { margin-right: 8px; }
/* ===== the operating loop reads as one worker (2026-08-05) =====
   Everywhere else on this figure a solid border means something you could point
   at in Azure: two Blazor surfaces, one Postgres. The loop is not that — it is a
   working relationship between a person and a set of written rules — so it takes
   the dashed frame that architecture diagrams reserve for a logical grouping.
   Dashed is the honest word here, not decoration: this is the one box on the
   page you cannot deploy.

   The frame has to read as one body, not a folder holding two files, and that
   is what the second rule buys. Three nested rectangles would have said
   "grouped"; two rails inside one panel say "one worker with two halves". Each
   half keeps only its identity rail — the person coral, the written rules teal
   — so the asymmetry the visual brief depends on survives the merge: a person
   is still not a colleague-shaped agent, and a skill is still a document.
   The rails run the full height so neither half looks like the other's
   attachment, and the single write pipe leaves the frame rather than either
   half: the pair acts on the database as one agent, and only after release. */
.arch-pair[b-5jbzknire0] {
  align-items: stretch;
  column-gap: 18px;
  border: 1.5px dashed rgba(35, 38, 43, .3);
  background: var(--panel);
  padding: 14px 16px;
}
.arch-pair .arch-node[b-5jbzknire0] {
  border: 0;
  border-left: 3px solid var(--line);
  background: none;
  padding: 0 0 0 13px;
  align-content: center;
}
.arch-pair .arch-human[b-5jbzknire0] { border-left-color: var(--coral-deep); }
.arch-pair .arch-skill[b-5jbzknire0] { border-left-color: var(--teal-deep); }
.arch-pair .arch-x[b-5jbzknire0] { justify-content: center; }

/* ===== the surfaces are thinner on purpose =====
   They are where the work becomes visible, not where it happens. Tighter
   padding and a smaller title than the two actors below, so a cold reader lands
   on who does the work before on where they can watch it — which is also the
   order the page argues in. The grey rails already said this in colour against
   the loop's coral and teal; this makes the type agree. */
.arch-surface[b-5jbzknire0] { padding: 9px 14px; }
.arch-surface b[b-5jbzknire0] { font-size: .85rem; }
.arch-surface p[b-5jbzknire0] { margin-top: 2px; }
.arch-surface .arch-host[b-5jbzknire0] { margin-top: 7px; padding: 2px 9px; }

/* The two in-diagram outbound links (GitHub under Agent Skills, the Backstage
   address under the workbench) retired 2026-08-05 when verification actions
   were consolidated into the strip below the figure: at 1440×900 each link and
   its own card were on screen together, 165px apart, so the "diagram for close
   readers, strip for skimmers" split was not real. Their grammar moved intact
   to .vfy-card — outbound ↗ in a new tab, the backstage entry muted with a
   lock, its host derived from the configured URL and never typed. The nodes
   are plain statements again. */

/* The spine fills its column with purpose instead of centring a small block in
   a tall empty frame (2026-08-05 owner call): title and claim at the top, the
   scale chips anchored to the bottom edge. Below 900px the natural flow keeps
   the node at content height, so this stays desktop-only. */
@media (min-width: 901px) {
  .arch-spine .arch-node[b-5jbzknire0] { align-content: stretch; align-items: stretch; }
  .arch-spine .arch-node > div[b-5jbzknire0] { display: flex; flex-direction: column; }
  .arch-spine .arch-tbls[b-5jbzknire0] { margin-top: auto; padding-top: 14px; }
}

.arch-cap[b-5jbzknire0] {
  margin-top: 14px;
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .06em;
  color: var(--mut);
  line-height: 1.8;
}

/* ===== causal entrance (2026-08-10) =====
   The connectors and exchange labels scrub in along the figure's entry into
   the viewport, in causal order: workbench SQL first, then evidence into the
   loop, then the rule exchange, and the gated write path last — the gate and
   its label appear before the line reaches the database. It is a one-pass
   scrub, not a loop: once the figure is fully in view the demonstration is
   complete and the page is static. Nodes never animate, so a reader who stops
   scrolling mid-way still sees every box; a browser without scroll timelines
   falls through the @supports gate to the complete static figure, and
   prefers-reduced-motion kills the animation entirely below. Opacity only —
   the arrowheads position with transforms, and nothing here reflows. */
@supports (animation-timeline: view()) {
  .arch-grid[b-5jbzknire0] { view-timeline: --sd-arch-flow block; }
  .p-read[b-5jbzknire0],
  .p-evidence[b-5jbzknire0],
  .arch-x[b-5jbzknire0],
  .p-write span[b-5jbzknire0],
  .p-write[b-5jbzknire0]::before,
  .p-write[b-5jbzknire0]::after {
    animation: sd-arch-flow-in-b-5jbzknire0 1s linear both;
    animation-timeline: --sd-arch-flow;
  }
  .p-read[b-5jbzknire0] { animation-range: entry 5% entry 30%; }
  .p-evidence[b-5jbzknire0] { animation-range: entry 22% entry 48%; }
  .arch-x[b-5jbzknire0] { animation-range: entry 40% entry 66%; }
  .p-write span[b-5jbzknire0] { animation-range: entry 56% entry 76%; }
  .p-write[b-5jbzknire0]::before,
  .p-write[b-5jbzknire0]::after { animation-range: entry 70% entry 92%; }
}
@keyframes sd-arch-flow-in-b-5jbzknire0 {
  from { opacity: 0; }
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .p-read[b-5jbzknire0],
  .p-evidence[b-5jbzknire0],
  .arch-x[b-5jbzknire0],
  .p-write span[b-5jbzknire0],
  .p-write[b-5jbzknire0]::before,
  .p-write[b-5jbzknire0]::after { animation: none; }
  .perd-stage[b-5jbzknire0]::after { transition: none; }
}

/* ===== verify-the-system strip (2026-08-05) =====
   The scan-layer audit invitation: three cards after 02, one per verifiable
   artifact. The signal works without being clicked — "this page invites an
   audit" raises the credibility of everything above it — so the strip's job is
   to be noticed in a ten-second skim, which the retired in-diagram links never
   were. It is the page's only verification surface: the figure states what the
   system is made of, the strip says where to go and check. Colours are
   inherited, not invented: grey
   lock = the muted backstage grammar, teal = the outbound verification
   grammar, amber = 01's schema/stage colour. Kickers name the artifact; the
   note line carries the evidence claim; no PROOF numbering — the workbench
   card is config-driven, so a hard count would miscount when it is absent. */
.vfy-eyebrow[b-5jbzknire0] { margin-bottom: 14px; }
.vfy-grid[b-5jbzknire0] {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px;
}
a.vfy-card[b-5jbzknire0] {
  display: flex;
  flex-direction: column;
  gap: 7px;
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 13px 16px;
  text-decoration: none;
}
.vfy-workbench[b-5jbzknire0] { border-left: 3px solid var(--dim); }
.vfy-method[b-5jbzknire0] { border-left: 3px solid var(--teal-deep); }
.vfy-schema[b-5jbzknire0] { border-left: 3px solid var(--amber-deep); }
.vfy-kicker[b-5jbzknire0] {
  font-family: var(--mono);
  font-size: .62rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dim);
}
.vfy-obj[b-5jbzknire0] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .02em;
  line-height: 1.5;
  text-decoration: underline;
  text-underline-offset: 3px;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.vfy-workbench .vfy-obj[b-5jbzknire0] { color: var(--mut); }
.vfy-method .vfy-obj[b-5jbzknire0] { color: var(--teal-deep); }
.vfy-schema .vfy-obj[b-5jbzknire0] { color: var(--amber-deep); }
a.vfy-card:hover .vfy-obj[b-5jbzknire0] { color: var(--ink); }
.vfy-ic[b-5jbzknire0] { width: 13px; height: 13px; flex: none; }
.vfy-note[b-5jbzknire0] {
  font-size: .76rem;
  color: var(--mut);
  line-height: 1.6;
}

/* footer (shared canonical footer, same as home) */
.ppv-foot[b-5jbzknire0] { border-bottom: 0; }
.foot-bar[b-5jbzknire0] {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  align-items: center;
  justify-content: space-between;
  padding-block: 20px 26px;
  font-family: var(--mono);
  font-size: .66rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--mut);
}
.foot-bar a[b-5jbzknire0] { text-decoration: none; color: var(--mut); }
.foot-bar a:hover[b-5jbzknire0] { color: var(--ink); }
.foot-links[b-5jbzknire0] { display: flex; gap: 22px; }
.foot-privacy[b-5jbzknire0] { margin-top: -8px; font-family: var(--mono); font-size: .56rem; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); line-height: 1.8; }
.foot-fresh[b-5jbzknire0] { padding-bottom: 24px; padding-top: 6px; font-family: var(--mono); font-size: .56rem; letter-spacing: .1em; text-transform: uppercase; line-height: 1.8; }
.foot-fresh a[b-5jbzknire0] { text-decoration: none; color: var(--dim); }
.foot-fresh a:hover[b-5jbzknire0] { color: var(--ink); }

@media (max-width: 900px) {
  /* the spine folds back into the vertical stack: reader → frontend → data →
     loop, with the pipes rendered as the same left-rail links. */
  .arch-grid[b-5jbzknire0] { display: block; }
  .arch-band[b-5jbzknire0] { grid-template-columns: 1fr; row-gap: 7px; }
  .arch-lt[b-5jbzknire0] { padding-top: 0; }
  .arch-spine .arch-lt[b-5jbzknire0] { margin-bottom: 7px; }
  .arch-pair[b-5jbzknire0] { grid-template-columns: 1fr; }
  /* between stacked partner nodes the exchange becomes a rail annotation */
  .arch-x[b-5jbzknire0] {
    max-width: none;
    text-align: left;
    margin-left: 26px;
    border-left: 1.4px solid var(--line);
    padding: 7px 0 9px 13px;
  }
  .arch-x-l[b-5jbzknire0]::before { content: "↓ "; }
  .arch-x-back[b-5jbzknire0]::before { content: "↑ "; }
  .arch-pipe[b-5jbzknire0] {
    display: block;
    min-height: 0;
    margin-left: 26px;
    border-left: 1.4px solid var(--teal-deep);
    padding: 8px 0 10px 13px;
  }
  .arch-pipe[b-5jbzknire0]::before { display: none; }
  .arch-pipe[b-5jbzknire0]::after {
    left: -4.2px;
    right: auto;
    top: -1px;
    transform: none;
    border-top: 0;
    border-left: 3.6px solid transparent;
    border-right: 3.6px solid transparent;
    border-bottom: 5.5px solid var(--teal-deep);
  }
  .arch-pipe span[b-5jbzknire0] { background: transparent; padding-inline: 0; text-align: left; }
  /* stacked flow keeps the directions readable: evidence drops from the spine
     above into the loop below (teal, arrow at the rail's foot pointing down);
     the write rail keeps the upward arrow — through the gate, back up to
     Postgres. */
  .p-evidence[b-5jbzknire0]::after {
    top: auto;
    bottom: -1px;
    border-top: 5.5px solid var(--teal-deep);
    border-bottom: 0;
  }
  .arch-flows .arch-pipe + .arch-pipe[b-5jbzknire0] { padding-top: 0; }
  .p-write[b-5jbzknire0] { border-left-color: var(--coral-deep); }
  .p-write[b-5jbzknire0]::after { border-bottom-color: var(--coral-deep); }
}

@media (max-width: 720px) {
  /* mobile: the overview pans sideways inside its own stage instead of
     shrinking below legibility; the scale rows stack label-over-numbers. */
  .perd-stage[b-5jbzknire0] { margin-inline: -20px; width: calc(100% + 40px); border-inline: 0; padding-inline: 20px; }
  .perd-foot[b-5jbzknire0] { margin-inline: -20px; border-inline: 0; padding-inline: 20px; }
  .sd-scale > div[b-5jbzknire0] { flex-direction: column; gap: 1px; }
  .sd-scale dt[b-5jbzknire0] { min-width: 0; }
}
