/* ═══════════════════════════════════════════════════════════════════════════
   DESIGN SYSTEM PRIMITIVES — token consumers only (Session 02).

   Every value comes from tokens.css (--tok-*). Guards:
   tests/unit/test_design_shell.py (layer discipline: no raw colors, no
   gradient/blur/shadow, token-only spacing/type/z, selectors locked to
   the .shell* / .ph* namespaces).

   Loaded per-page via the base.html `head_extra` block — during Session 02
   ONLY the isolated preview consumes this file; production pages stay on
   the legacy stylesheet untouched.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── shell — the canonical page frame ──────────────────────────────────────
   Breakpoints derive from AVAILABLE CONTENT SPACE (container queries on
   the shell itself), not from device families: the app frame owns part of
   the viewport (sidebar), so viewport media queries would lie here.

   Collapse threshold, derived: aside 320px + gap 24px + ~560px usable
   main (the reading measure at body size) = 904px → collapse below 960px
   of shell space (rounded up to keep the main column comfortable).      */

.shell {
    container-type: inline-size;
}

.shell__frame {
    max-width: var(--tok-content-max);
    margin-inline: auto;
    /* vertical entry/exit rhythm: section-scale in, page-exit scale out */
    padding: var(--tok-space-6) var(--tok-space-5) var(--tok-space-8);
}

.shell__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--tok-space-5);
    align-items: start;
}

/* the W0 lesson: grid/flex children must be allowed to shrink,
   or one nowrap string drags the page wide on a phone; overflow-wrap
   is the frame's safety net for pathological unbreakable content */
.shell__main,
.shell__aside {
    min-width: 0;
    overflow-wrap: anywhere;
}

.shell--work-aside .shell__grid {
    grid-template-columns: minmax(0, 1fr) var(--tok-aside-max);
}

.shell--reading .shell__main {
    max-width: var(--tok-reading-max);
}

/* available space < 960px → the aside stacks below the main content */
@container (max-width: 959px) {
    .shell--work-aside .shell__grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* tight composition (small phones): gutters step down one spacing stop */
@container (max-width: 599px) {
    .shell__frame {
        padding: var(--tok-space-5) var(--tok-space-4) var(--tok-space-7);
    }
}

/* ── page_head — orientation, never a hero ────────────────────────────────
   Answers "where am I / what is this page for / what state is it in".
   One quiet composition: label above, ONE wrapping H1 on the canonical
   type-title, optional lead at reading width, quiet meta, and the one
   primary action that steps below the text when space runs out.        */

.ph {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--tok-space-3) var(--tok-space-5);
    margin-bottom: var(--tok-space-6);
}

.ph__orient {
    flex: 1 1 auto;
    min-width: 0;
}

.ph__label {
    margin: 0 0 var(--tok-space-1);
    font-size: var(--tok-type-label-size);
    line-height: var(--tok-type-label-line);
    font-weight: var(--tok-type-label-weight);
    color: var(--tok-ink-muted);
}

.ph__title {
    margin: 0;
    font-size: var(--tok-type-title-size);
    line-height: var(--tok-type-title-line);
    font-weight: var(--tok-type-title-weight);
    color: var(--tok-ink);
    /* long CS/EN titles wrap — truncating orientation is lying */
    overflow-wrap: anywhere;
}

.ph__lead {
    margin: var(--tok-space-2) 0 0;
    font-size: var(--tok-type-body-size);
    line-height: var(--tok-type-body-line);
    font-weight: var(--tok-type-body-weight);
    color: var(--tok-ink-2);
    max-width: var(--tok-reading-max);
}

.ph__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tok-space-1) var(--tok-space-3);
    margin: var(--tok-space-2) 0 0;
    padding: 0;
    list-style: none;
    font-size: var(--tok-type-micro-size);
    line-height: var(--tok-type-micro-line);
    font-weight: var(--tok-type-micro-weight);
    color: var(--tok-ink-muted);
}

.ph__action {
    flex: 0 0 auto;
    /* the action may relocate below the text (flex-wrap on .ph), but it
       must never widen the page — its content wraps inside instead */
    min-width: 0;
    max-width: 100%;
}

/* ── section — hierarchy from rhythm and typography, never a box ──────────
   No background, no border, no radius: the chapter reads through its
   heading scale and the canonical vertical rhythm between siblings.   */

.sec + .sec {
    margin-top: var(--tok-space-7);
}

.sec__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--tok-space-1) var(--tok-space-4);
    margin-bottom: var(--tok-space-4);
}

.sec__orient {
    flex: 1 1 auto;
    min-width: 0;
}

.sec__title {
    margin: 0;
    font-size: var(--tok-type-emph-size);
    line-height: var(--tok-type-emph-line);
    font-weight: var(--tok-type-emph-weight);
    color: var(--tok-ink);
    overflow-wrap: anywhere;
}

.sec__lead {
    margin: var(--tok-space-1) 0 0;
    font-size: var(--tok-type-body-size);
    line-height: var(--tok-type-body-line);
    font-weight: var(--tok-type-body-weight);
    color: var(--tok-ink-2);
    max-width: var(--tok-reading-max);
}

.sec__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tok-space-1) var(--tok-space-3);
    margin: var(--tok-space-1) 0 0;
    padding: 0;
    list-style: none;
    font-size: var(--tok-type-micro-size);
    line-height: var(--tok-type-micro-line);
    font-weight: var(--tok-type-micro-weight);
    color: var(--tok-ink-muted);
}

.sec__action {
    flex: 0 0 auto;
    font-size: var(--tok-type-label-size);
    line-height: var(--tok-type-label-line);
    font-weight: var(--tok-type-label-weight);
    color: var(--tok-brand);
    text-decoration: none;
    min-width: 0;
    max-width: 100%;
    overflow-wrap: anywhere;
}

.sec__body {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* ── surface — bounded working context (never a decorative card) ──────────
   Quiet in both themes: tone + hairline do the bounding, typography does
   the talking. No hover, no cursor, no transform on the region itself —
   interactivity belongs to the controls INSIDE it.                     */

.surf {
    background: var(--tok-surface);
    border: 1px solid var(--tok-line);
    border-radius: var(--tok-radius-m);
    padding: var(--tok-space-4);
    min-width: 0;
    overflow-wrap: anywhere;
}

.surf--raised {
    background: var(--tok-surface-raised);
}

.surf--inset {
    background: var(--tok-surface-inset);
    border-color: transparent;
}

/* consecutive surfaces inside one section stay separated by rhythm,
   not by piling borders */
.surf + .surf {
    margin-top: var(--tok-space-4);
}

/* ── metric — evidence, not a billboard ───────────────────────────────────
   The value is prominent but calm (hero-num token, nothing larger); the
   unit stays quiet; context reads; provenance whispers. No background,
   no border, no hover — a metric is text with hierarchy, and the page
   still reads if every metric were plain prose.                        */

.met {
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

.met__label {
    font-size: var(--tok-type-label-size);
    line-height: var(--tok-type-label-line);
    font-weight: var(--tok-type-label-weight);
    color: var(--tok-ink-muted);
}

.met__value {
    margin: var(--tok-space-1) 0 0;
    font-size: var(--tok-type-hero-num-size);
    line-height: var(--tok-type-hero-num-line);
    font-weight: var(--tok-type-hero-num-weight);
    font-variant-numeric: tabular-nums;
    color: var(--tok-state-fact);
}

.met__unit {
    font-size: var(--tok-type-label-size);
    font-weight: var(--tok-type-label-weight);
    color: var(--tok-ink-2);
}

.met__context {
    margin: var(--tok-space-1) 0 0;
    font-size: var(--tok-type-body-size);
    line-height: var(--tok-type-body-line);
    color: var(--tok-ink-2);
    max-width: var(--tok-reading-max);
}

/* neutral by contract: comparison never colors by sign */
.met__comparison {
    margin: var(--tok-space-1) 0 0;
    font-size: var(--tok-type-label-size);
    line-height: var(--tok-type-label-line);
    color: var(--tok-ink-2);
    font-variant-numeric: tabular-nums;
}

.met__provenance {
    margin: var(--tok-space-1) 0 0;
    font-size: var(--tok-type-micro-size);
    line-height: var(--tok-type-micro-line);
    color: var(--tok-ink-muted);
}

/* certainty states — the canonical Session 01 aliases, always paired
   with the textual met__certainty term (meaning is never hue alone) */
.met--declared .met__value {
    color: var(--tok-state-declared);
}

.met--estimate .met__value {
    color: var(--tok-state-estimate);
    font-style: italic;
}

.met--missing .met__value {
    color: var(--tok-state-missing);
}

/* ── metric_group — layout only: related values sit together and wrap ── */
.met-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tok-space-5) var(--tok-space-6);
    align-items: start;
}

.met-row .met {
    flex: 0 1 auto;
}

/* ── action — one canonical action, intent over styling ───────────────────
   Interactive by definition, so pointer + hover ARE meaning here (unlike
   surface/metric). Calm: no fills beyond the single brand lamp, no
   transforms, no shadows; focus is always visible.                     */

.act {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--tok-space-2);
    min-height: var(--tok-touch-min);
    padding: var(--tok-space-2) var(--tok-space-4);
    border: 1px solid transparent;
    border-radius: var(--tok-radius-s);
    background: transparent;
    font-family: inherit;
    font-size: var(--tok-type-body-size);
    line-height: var(--tok-type-label-line);
    font-weight: var(--tok-type-label-weight);
    text-decoration: none;
    cursor: pointer;
    min-width: 0;
    max-width: 100%;
    overflow-wrap: anywhere;
    transition: border-color var(--tok-motion-fast) ease-out,
                color var(--tok-motion-fast) ease-out;
}

.act:focus-visible {
    outline: 2px solid var(--tok-focus);
    outline-offset: 2px;
}

.act--primary {
    background: var(--tok-brand);
    color: var(--tok-ink-on-brand);
}

.act--secondary {
    border-color: var(--tok-line);
    color: var(--tok-ink);
}

.act--secondary:hover {
    border-color: var(--tok-brand);
    color: var(--tok-brand);
}

.act--text {
    color: var(--tok-brand);
    padding-inline: var(--tok-space-1);
}

.act--text:hover {
    text-decoration: underline;
}

.act:disabled,
.act[disabled] {
    color: var(--tok-ink-disabled);
    background: var(--tok-surface-inset);
    border-color: transparent;
    cursor: default;
}

/* loading keeps the label readable; aria-busy carries the semantics —
   the continuous visual indicator arrives with the loading/skeleton
   session (its motion contract does not exist yet) */
.act--loading {
    cursor: progress;
}

/* ═══════════════════════════════════════════════════════════════════════════
   DESIGN SYSTEM v2 PRIMITIVES (Phase 4 — Direction C systemized).
   Contract: docs/design-transformation/MYFINVERSE_DESIGN_SYSTEM_V2.md.
   Same layer discipline as everything above: token consumers only.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── l1 — the Decision/State zone ─────────────────────────────────────────
   Exactly ONE per page. One quiet structured surface; internal separation
   by hairlines, spacing and typography — never nested cards, never a
   widget grid, never a banner. Zones compose page-specific content
   (metric primitives, attention statement); the attention zone is the
   ONLY zone allowed a background, and only the warn tint.              */

.l1 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    background: var(--tok-surface);
    border: 1px solid var(--tok-line);
    border-radius: var(--tok-radius-m);
    overflow: hidden;
    min-width: 0;
}

.l1__zone {
    padding: var(--tok-space-4) var(--tok-space-5);
    min-width: 0;
    overflow-wrap: anywhere;
}

.l1__zone + .l1__zone {
    border-left: 1px solid var(--tok-line);
}

.l1__zone--attention {
    background: var(--tok-warn-tint);
}

@media (max-width: 679px) {
    .l1 {
        grid-template-columns: minmax(0, 1fr);
    }

    .l1__zone + .l1__zone {
        border-left: 0;
        border-top: 1px solid var(--tok-line);
    }
}

/* ── attn — the attention statement ───────────────────────────────────────
   A statement, not an alarm: quiet amber label + short factual lines +
   optional investigation link. Lives inside the L1 attention zone or —
   with the aside variant — standalone in page flow. Never a warning
   card, never an icon parade, never red unless the fact itself is a
   negative financial delta (which then colors ONLY the delta).         */

.attn {
    min-width: 0;
    overflow-wrap: anywhere;
}

.attn__title {
    font-size: var(--tok-type-micro-size);
    line-height: var(--tok-type-micro-line);
    font-weight: 650;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tok-warn);
}

.attn__line {
    margin: var(--tok-space-2) 0 0;
    font-size: var(--tok-type-label-size);
    line-height: var(--tok-type-label-line);
    color: var(--tok-ink-2);
}

.attn__line strong {
    color: var(--tok-ink);
    font-weight: 600;
}

.attn__link {
    color: var(--tok-brand);
    text-decoration: none;
}

.attn__link:hover {
    text-decoration: underline;
}

.attn--aside {
    border-left: 2px solid var(--tok-warn);
    padding-left: var(--tok-space-4);
}

/* ── idm — identity monogram for collection rows ──────────────────────────
   Replaces real company logos in dense collections (Phase 3 evidence:
   muted real logos yield inconsistent dark tiles). Stable 24px box,
   deterministic ticker initials, quiet by contract: it anchors the row
   for scanning and must never compete with the symbol text next to it
   (which carries the accessible name — the monogram is aria-hidden).   */

/* Board reversal 6.8.2026: real logo rides ON the monogram chip; the
   initials stay beneath as the loading/failure fallback. */
.idm { position: relative; overflow: hidden; }

.idm__logo {
    /* 2px breathing room comes from the inset (positioning), not
       padding — the layer-discipline guard rightly rejects raw
       spacing values, and the chip bg behind shows the same color. */
    position: absolute;
    inset: 2px;
    width: calc(100% - 4px);
    height: calc(100% - 4px);
    object-fit: contain;
    background: var(--tok-identity-chip);
    border-radius: inherit;
}

.idm {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--tok-space-5);
    height: var(--tok-space-5);
    flex: 0 0 auto;
    border: 1px solid var(--tok-line);
    border-radius: var(--tok-radius-xs);
    background: var(--tok-surface-raised);
    font-size: var(--tok-type-micro-size);
    line-height: 1;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--tok-ink-muted);
    user-select: none;
}

/* ── tbl — collection density modes (analytical | tabular) ────────────────
   ONE table language, two densities. Analytical (Direction C): portfolio
   evidence, 38px target rows, sublines allowed. Tabular (Direction B
   proven): screener/high-density records, 32px rows, nowrap. Numbers are
   Inter + tabular-nums by token contract — never mono. Color appears
   ONLY on the delta value itself (pos/neg) and the rare attention mark. */

.tbl {
    width: 100%;
    border-collapse: collapse;
}

.tbl th {
    padding: var(--tok-space-2) var(--tok-space-2) var(--tok-space-2) var(--tok-space-4);
    font-size: var(--tok-type-micro-size);
    line-height: var(--tok-type-micro-line);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--tok-ink-muted);
    text-align: right;
    border-bottom: 1px solid var(--tok-line-strong);
    white-space: nowrap;
}

.tbl td {
    padding: var(--tok-space-1) var(--tok-space-2) var(--tok-space-1) var(--tok-space-4);
    font-size: var(--tok-type-data-size);
    line-height: var(--tok-type-data-line);
    font-variant-numeric: tabular-nums;
    text-align: right;
    vertical-align: middle;
    border-bottom: 1px solid var(--tok-line);
    min-width: 0;
}

.tbl th:first-child,
.tbl td:first-child {
    text-align: left;
    padding-left: var(--tok-space-1);
}

.tbl--analytical td {
    height: var(--tok-row-analytical);
}

.tbl--tabular td {
    height: var(--tok-row-tabular);
    white-space: nowrap;
}

.tbl tbody tr:hover {
    background: var(--tok-surface);
}

.tbl__row--selected,
.tbl__row--selected:hover {
    background: var(--tok-surface-raised);
}

.tbl__row:focus-visible {
    outline: 2px solid var(--tok-focus);
    outline-offset: -2px;
}

/* column-group separator (Direction B evidence): between identity /
   valuation / P-L / income groups — never between every column */
.tbl__group {
    border-left: 1px solid var(--tok-line);
}

/* semantic delta — colors the delta VALUE only, never the row */
.tbl__pos {
    color: var(--tok-pos);
    font-weight: 600;
}

.tbl__neg {
    color: var(--tok-neg);
    font-weight: 600;
}

/* missing data: the canonical em dash + muted reason, never 0 */
.tbl__missing {
    color: var(--tok-ink-muted);
}

/* subline / provenance inside a cell (native currency, YoC, reason) */
.tbl__sub {
    font-size: var(--tok-type-micro-size);
    line-height: var(--tok-type-micro-line);
    font-weight: 400;
    color: var(--tok-ink-muted);
}

/* ── disc — mobile progressive disclosure for collections ─────────────────
   <details class="disc"><summary class="disc__summary">…: the summary
   grid exposes symbol + value + P/L + income WITHOUT expansion; the
   detail grid carries the secondary facts. Native details/summary =
   keyboard and screen-reader semantics for free; focus stays visible.  */

.disc {
    border-bottom: 1px solid var(--tok-line);
    min-width: 0;
}

.disc__summary {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: var(--tok-space-1) var(--tok-space-3);
    align-items: center;
    padding: var(--tok-space-3) 0;
    cursor: pointer;
    list-style: none;
}

.disc__summary::-webkit-details-marker {
    display: none;
}

.disc__summary:focus-visible {
    outline: 2px solid var(--tok-focus);
    outline-offset: 2px;
}

.disc__detail {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--tok-space-2) var(--tok-space-4);
    padding: 0 0 var(--tok-space-4);
}

/* ── met variants (v2): the four metric roles ─────────────────────────────
   primary state metric = default .met (hero-num = display/state role);
   supporting metric    = .met--support (body-size value, weight 600);
   inline metric        = .met--inline (label and value on one line);
   table/data metric    = .tbl cell treatment (data role), not a .met.  */

.met--support .met__value {
    font-size: var(--tok-type-body-size);
    line-height: var(--tok-type-body-line);
    font-weight: 600;
}

.met--inline {
    display: flex;
    align-items: baseline;
    gap: var(--tok-space-2);
}

.met--inline .met__value {
    margin: 0;
    font-size: var(--tok-type-body-size);
    line-height: var(--tok-type-body-line);
    font-weight: 600;
}
