/*
 * CollisionSuite — App-screen primitives (cs-app-screens skill)
 *
 * Opt-in classes only: nothing here restyles an existing page until the page
 * adds the class. The rules were decided 2026-10-21 (living reference:
 * /dev/app-screens/); existing pages adopt them as they are touched.
 *
 * How to use each block: .claude/skills/cs-app-screens/SKILL.md
 *
 *   .stat-value     larger number on a SEPARATE stat card (decided 2026-10-21)
 *   .stat-lead      the screen's answer figure, ~1.3x its siblings (rule 1)
 *   .stat-caption   small grey caption under a stat label (rule 1)
 *   .table-stack    table that becomes two-line rows below 640px (rule 6)
 *   .table-quiet    sentence-case grey table headers, no header band
 *   .empty-frame    an empty section keeps its frame + one sentence (rule 5)
 *
 * Every colour reads from Bootstrap 5.3 theme variables, so light and dark
 * themes both work without per-theme overrides.
 */

/* ── Stat cards ──────────────────────────────────────────────────────────────
 * Stat cards stay SEPARATE cards in a gutter row (decided; the divided
 * one-box strip was rejected). Only the number gets bigger:
 *   <div class="row g-3 mb-4">
 *     <div class="col-6 col-lg-3"><div class="card h-100"><div class="card-body text-center">
 *       <div class="stat-value mb-1">12</div>
 *       <small class="text-muted">Open files</small>
 *     </div></div></div>
 *   </div>
 */
.stat-value {
    font-size: 1.75rem;             /* ~24.5px at the 14px base (was h3 = 1.1rem) */
    font-weight: 500;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.stat-value.stat-lead {             /* rule 1: one per screen */
    font-size: 2.3rem;              /* ~32px */
}
.stat-caption {                     /* rule 1 */
    display: block;
    font-size: 0.75rem;
    color: var(--bs-secondary-color);
    margin-top: 0.1rem;
}
/* Bootstrap's text-warning (#ffc107) is ~1.6:1 on white: unreadable as a
   number. On a stat value it uses the theme-aware emphasis tone instead. */
.stat-value.text-warning { color: var(--bs-warning-text-emphasis) !important; }

@media (max-width: 575.98px) {
    .stat-value { font-size: 1.5rem; }
    .stat-value.stat-lead { font-size: 1.9rem; }
}

/* ── Quiet table headers ─────────────────────────────────────────────────────
 * Sentence-case grey headers at label size, regular weight, no fill band.
 * Right-align numeric headers WITH their values (th.text-end + td.text-end;
 * typography.css already gives .text-end cells tabular numerals).
 */
.table-quiet > thead > tr > th {
    font-size: 0.78rem;
    font-weight: 400;
    color: var(--bs-secondary-color);
    text-transform: none;
    letter-spacing: 0;
    background-color: transparent;
    --bs-table-bg-type: transparent;   /* no stripe/band on the header row */
    white-space: nowrap;
}

/* ── Phone two-line rows ─────────────────────────────────────────────────────
 * Add .table-stack to a <table>. Below 640px each <tr> becomes a two-line row:
 *
 *   line 1:  [.ts-primary identity ............] [.ts-key number] [.ts-action]
 *   line 2:  every other cell, small grey, joined by " · "
 *
 * Fields MOVE to line 2, they are never dropped, so don't put d-none on
 * cells of a stacked table (d-none d-md-table-cell would hide them on phones).
 * Optional per-cell prefix shown only when stacked:
 *   <td><span class="ts-label">Updated </span>4</td>
 * Empty cells vanish on phones so no dangling separator appears.
 * Row clicks (onclick on <tr>) keep working; the thead is visually hidden.
 *
 * .ts-force-stack on any ancestor applies the stacked layout at every width.
 * It exists only so /dev/app-screens/ can show the phone rendering inside a
 * 390px frame on a desktop screen; production markup never uses it.
 */
.ts-label { display: none; }

@media (max-width: 639.98px) {
    .table-stack > thead {
        position: absolute !important;
        width: 1px !important;
        height: 1px !important;
        overflow: hidden !important;
        clip: rect(0, 0, 0, 0) !important;
        white-space: nowrap !important;
    }
    .table-stack,
    .table-stack > tbody { display: block; width: 100%; }
    .table-stack > tbody > tr {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        column-gap: 0.4rem;
        row-gap: 0.1rem;
        padding: 0.55rem 0.75rem;
        border-bottom: var(--bs-border-width) solid var(--bs-border-color);
    }
    .table-stack > tbody > tr:last-child { border-bottom: 0; }
    .table-stack > tbody > tr > td {
        display: block;
        padding: 0;
        border: 0;
        background: transparent;
        box-shadow: none !important;
        min-width: 0;
    }
    .table-stack.table-striped > tbody > tr:nth-of-type(odd) { background-color: var(--bs-table-striped-bg); }
    .table-stack.table-hover > tbody > tr:hover { background-color: var(--bs-table-hover-bg); }
    .table-stack > tbody > tr > td.ts-primary {
        order: 1; flex: 1 1 0; font-weight: 500;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .table-stack > tbody > tr > td.ts-key {
        order: 2; flex: none; margin-left: auto; text-align: right;
        font-variant-numeric: tabular-nums; white-space: nowrap;
    }
    .table-stack > tbody > tr > td.ts-action { order: 3; flex: none; align-self: center; }
    .table-stack > tbody > tr::after { content: ""; order: 4; flex-basis: 100%; height: 0; }
    .table-stack > tbody > tr > td:not(.ts-primary, .ts-key, .ts-action) {
        order: 5; flex: none; max-width: 100%;
        font-size: 0.78rem; color: var(--bs-secondary-color); text-align: left;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .table-stack > tbody > tr > td:not(.ts-primary, .ts-key, .ts-action):empty { display: none; }
    .table-stack > tbody > tr > td:not(.ts-primary, .ts-key, .ts-action)
        ~ td:not(.ts-primary, .ts-key, .ts-action):not(:empty)::before {
        content: "\00b7"; margin-right: 0.4rem; color: var(--bs-secondary-color);
    }
    .table-stack > tbody > tr > td small,
    .table-stack > tbody > tr > td .small { font-size: inherit; }
    .table-stack .ts-label { display: inline; }
    .table-stack > tbody > tr > td[colspan] { flex-basis: 100%; }
}

/* Same rules, scoped to the demo frame (kept in sync with the block above). */
.ts-force-stack .table-stack > thead {
    position: absolute !important; width: 1px !important; height: 1px !important;
    overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important;
}
.ts-force-stack .table-stack,
.ts-force-stack .table-stack > tbody { display: block; width: 100%; }
.ts-force-stack .table-stack > tbody > tr {
    display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.4rem; row-gap: 0.1rem;
    padding: 0.55rem 0.75rem; border-bottom: var(--bs-border-width) solid var(--bs-border-color);
}
.ts-force-stack .table-stack > tbody > tr:last-child { border-bottom: 0; }
.ts-force-stack .table-stack > tbody > tr > td {
    display: block; padding: 0; border: 0; background: transparent; box-shadow: none !important; min-width: 0;
}
.ts-force-stack .table-stack > tbody > tr > td.ts-primary {
    order: 1; flex: 1 1 0; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ts-force-stack .table-stack > tbody > tr > td.ts-key {
    order: 2; flex: none; margin-left: auto; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ts-force-stack .table-stack > tbody > tr > td.ts-action { order: 3; flex: none; align-self: center; }
.ts-force-stack .table-stack > tbody > tr::after { content: ""; order: 4; flex-basis: 100%; height: 0; }
.ts-force-stack .table-stack > tbody > tr > td:not(.ts-primary, .ts-key, .ts-action) {
    order: 5; flex: none; max-width: 100%; font-size: 0.78rem; color: var(--bs-secondary-color);
    text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ts-force-stack .table-stack > tbody > tr > td:not(.ts-primary, .ts-key, .ts-action):empty { display: none; }
.ts-force-stack .table-stack > tbody > tr > td:not(.ts-primary, .ts-key, .ts-action)
    ~ td:not(.ts-primary, .ts-key, .ts-action):not(:empty)::before {
    content: "\00b7"; margin-right: 0.4rem; color: var(--bs-secondary-color);
}
.ts-force-stack .table-stack .ts-label { display: inline; }

/* ── Empty section ───────────────────────────────────────────────────────────
 * An empty block keeps its card + header and says one sentence in the body:
 *   <div class="empty-frame">No follow-ups due this week.</div>
 */
.empty-frame {
    border: var(--bs-border-width) dashed var(--bs-border-color);
    border-radius: var(--bs-border-radius);
    padding: 0.6rem 0.9rem;
    color: var(--bs-secondary-color);
    font-size: 0.85rem;
}
