@import '_content/Kanine.Presentation.Pages/Kanine.Presentation.Pages.6kcb8p4wr2.bundle.scp.css';
@import '_content/Kanine.Presentation/Kanine.Presentation.c7af2l12ri.bundle.scp.css';

/* _content/Kanine.Web/Components/Feedback/DiffView.razor.rz.scp.css */
/* Readable unified-diff view (owner-directed 2026-07-14) — per-file, per-line +/- rows. */
.kl-diffview[b-s0s4tlxrms] {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    font-size: 0.78rem;
    line-height: 1.5;
}

.kl-diffview-empty[b-s0s4tlxrms] {
    color: var(--k-text-muted);
    font-size: 0.85rem;
}

.kl-diffview-file[b-s0s4tlxrms] {
    border: 1px solid var(--k-border, #d8dee6);
    border-radius: 8px;
    overflow: hidden;
    background: var(--k-surface, #fff);
}

.kl-diffview-filehead[b-s0s4tlxrms] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.4rem 0.7rem;
    background: var(--k-surface-2, #f2f5f8);
    border-block-end: 1px solid var(--k-border, #d8dee6);
    cursor: pointer;
    font-family: system-ui, sans-serif;
    font-size: 0.8rem;
    font-weight: 600;
    list-style: none;
}

.kl-diffview-filehead[b-s0s4tlxrms]::-webkit-details-marker { display: none; }

.kl-diffview-path[b-s0s4tlxrms] {
    color: var(--k-text, #1a2430);
    word-break: break-all;
}

.kl-diffview-counts[b-s0s4tlxrms] {
    display: inline-flex;
    gap: 0.5rem;
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
}

.kl-diffview-added[b-s0s4tlxrms] { color: #1a7f37; }
.kl-diffview-del[b-s0s4tlxrms] { color: #cf222e; }

.kl-diffview-body[b-s0s4tlxrms] {
    overflow-x: auto;
}

.kl-diffview-line[b-s0s4tlxrms] {
    display: flex;
    align-items: flex-start;
    white-space: pre;
}

.kl-diffview-gutter[b-s0s4tlxrms] {
    flex: 0 0 1.4rem;
    text-align: center;
    user-select: none;
    color: var(--k-text-muted);
    opacity: 0.7;
}

.kl-diffview-text[b-s0s4tlxrms] {
    flex: 1 1 auto;
    padding-inline-end: 0.5rem;
    font: inherit;
    white-space: pre;
    color: var(--k-text, #1a2430);
}

.kl-diffview-line--add[b-s0s4tlxrms] { background: rgba(46, 160, 67, 0.14); }
.kl-diffview-line--add .kl-diffview-gutter[b-s0s4tlxrms] { color: #1a7f37; opacity: 1; }
.kl-diffview-line--del[b-s0s4tlxrms] { background: rgba(207, 34, 46, 0.13); }
.kl-diffview-line--del .kl-diffview-gutter[b-s0s4tlxrms] { color: #cf222e; opacity: 1; }
.kl-diffview-line--hunk[b-s0s4tlxrms] {
    background: var(--k-surface-2, #eef3f8);
    color: var(--k-accent, #2f6fb0);
}
.kl-diffview-line--hunk .kl-diffview-text[b-s0s4tlxrms] { color: var(--k-accent, #2f6fb0); font-style: italic; }

@media (prefers-color-scheme: dark) {
    .kl-diffview-line--add[b-s0s4tlxrms] { background: rgba(46, 160, 67, 0.20); }
    .kl-diffview-line--del[b-s0s4tlxrms] { background: rgba(248, 81, 73, 0.18); }
    .kl-diffview-added[b-s0s4tlxrms] { color: #3fb950; }
    .kl-diffview-del[b-s0s4tlxrms] { color: #f85149; }
}
/* _content/Kanine.Web/Components/Feedback/FeedbackCardDetail.razor.rz.scp.css */
/* The owner merge-decision console — FeedbackCardDetail's OWN scoped sheet. (The page's .razor.css cannot
   style this child component's markup: CSS isolation only stamps the scope attribute on the owning
   component's elements.) Dark overrides use BARE html.dark (the dead-rule trap: :global(html.dark) ships
   verbatim and the browser drops it). Tokens: --k-* design-system variables throughout. */

.kl-fb-detail-head h2[b-lc3t7ob1ea] {
    margin: 0 0 0.15rem;
    font-size: 1.05rem;
}

.kl-fb-detail-sub[b-lc3t7ob1ea] {
    margin: 0;
    color: var(--k-text-muted);
    font-size: 0.82rem;
}

.kl-fb-detail-headactions[b-lc3t7ob1ea] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.kl-fb-copy-note[b-lc3t7ob1ea] {
    font-size: 0.78rem;
    color: var(--k-text-muted);
}

.kl-fb-tabs[b-lc3t7ob1ea] {
    display: flex;
    gap: 0.4rem;
    margin: 0.6rem 0;
    border-bottom: 1px solid var(--k-border);
    padding-bottom: 0.4rem;
}

.kl-fb-tab[b-lc3t7ob1ea] {
    background: none;
    border: 1px solid transparent;
    border-radius: 6px;
    padding: 0.3rem 0.65rem;
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
    color: var(--k-text-muted);
}

.kl-fb-tab:hover[b-lc3t7ob1ea] {
    color: var(--k-text);
    background: var(--k-surface-2);
}

.kl-fb-tab--active[b-lc3t7ob1ea] {
    color: var(--k-text);
    font-weight: 600;
    border-color: var(--k-border);
    background: var(--k-surface-2);
}

/* ---- Decision tab — the merge brief ------------------------------------------------------------- */
.kl-fb-brief-head[b-lc3t7ob1ea] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--k-border);
    border-radius: 8px;
    background: var(--k-surface-2);
    font-size: 0.85rem;
}

.kl-fb-brief-age[b-lc3t7ob1ea] {
    margin-inline-start: auto;
    color: var(--k-text-muted);
    font-size: 0.78rem;
}

.kl-fb-brief-h[b-lc3t7ob1ea] {
    margin: 1rem 0 0.35rem;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

.kl-fb-detail-comment[b-lc3t7ob1ea] {
    margin: 0.25rem 0;
    padding: 0.5rem 0.65rem;
    border-inline-start: 3px solid var(--k-accent);
    background: var(--k-surface-2);
    border-radius: 0 6px 6px 0;
    white-space: pre-wrap;
    word-break: break-word;
}

.kl-fb-steps[b-lc3t7ob1ea] {
    margin: 0.35rem 0 0;
    padding-inline-start: 1.2rem;
    font-size: 0.88rem;
}

.kl-fb-detail-dl[b-lc3t7ob1ea] {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.2rem 0.75rem;
    font-size: 0.9rem;
    margin: 0.35rem 0;
}

.kl-fb-detail-dl dt[b-lc3t7ob1ea] {
    color: var(--k-text-muted);
}

.kl-fb-detail-dl dd[b-lc3t7ob1ea] {
    margin: 0;
    word-break: break-word;
}

.kl-fb-logdigest[b-lc3t7ob1ea] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 0.65rem;
    border: 1px solid var(--k-border);
    border-radius: 8px;
    background: var(--k-surface-2);
}

.kl-fb-logdigest ul[b-lc3t7ob1ea] {
    margin: 0;
    padding-inline-start: 1.1rem;
    font-size: 0.85rem;
}

.kl-fb-diagnosis[b-lc3t7ob1ea] {
    margin: 0.25rem 0;
    white-space: pre-wrap;
    word-break: break-word;
}

.kl-fb-detail-note[b-lc3t7ob1ea] {
    color: var(--k-text-muted);
    font-size: 0.85rem;
}

.kl-fb-fix-files[b-lc3t7ob1ea] {
    margin: 0.25rem 0;
    padding-inline-start: 1.1rem;
    font-size: 0.85rem;
}

.kl-fb-fix-sha[b-lc3t7ob1ea] {
    margin: 0.25rem 0;
    font-size: 0.88rem;
}

.kl-fb-difffold summary[b-lc3t7ob1ea] {
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--k-accent);
}

/* ---- Proof — the centerpiece --------------------------------------------------------------------- */
.kl-fb-proof[b-lc3t7ob1ea] {
    border-radius: 8px;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--k-border);
}

.kl-fb-proof--proven[b-lc3t7ob1ea] {
    border-color: color-mix(in srgb, var(--k-success) 55%, var(--k-border));
    background: color-mix(in srgb, var(--k-success) 8%, var(--k-surface));
}

.kl-fb-proof--proven .kl-fb-proof-verdict[b-lc3t7ob1ea] {
    color: var(--k-success);
}

.kl-fb-proof--unproven[b-lc3t7ob1ea] {
    border: 1px solid color-mix(in srgb, var(--k-caution) 55%, var(--k-border));
    background: color-mix(in srgb, var(--k-caution) 10%, var(--k-surface));
}

.kl-fb-proof--unproven .kl-fb-proof-verdict[b-lc3t7ob1ea] {
    color: var(--k-caution);
}

.kl-fb-proof-verdict[b-lc3t7ob1ea] {
    margin: 0 0 0.35rem;
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.02em;
}

.kl-fb-proof-cmd[b-lc3t7ob1ea] {
    display: block;
    font-size: 0.75rem;
    margin-bottom: 0.4rem;
    word-break: break-all;
}

.kl-fb-proof-run[b-lc3t7ob1ea] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem;
    margin: 0.25rem 0;
    font-size: 0.85rem;
}

.kl-fb-proof-red[b-lc3t7ob1ea] {
    background: color-mix(in srgb, var(--k-critical) 15%, var(--k-surface));
    color: var(--k-critical);
    border: 1px solid color-mix(in srgb, var(--k-critical) 40%, transparent);
}

.kl-fb-proof-green[b-lc3t7ob1ea] {
    background: color-mix(in srgb, var(--k-success) 15%, var(--k-surface));
    color: var(--k-success);
    border: 1px solid color-mix(in srgb, var(--k-success) 40%, transparent);
}

.kl-fb-proof-excerpt[b-lc3t7ob1ea],
.kl-fb-proof-raw[b-lc3t7ob1ea] {
    flex-basis: 100%;
    max-height: 180px;
    overflow: auto;
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: 6px;
    padding: 0.4rem;
    font-size: 0.72rem;
    white-space: pre-wrap;
    word-break: break-word;
    margin: 0.2rem 0 0;
}

.kl-fb-proof-suite[b-lc3t7ob1ea] {
    margin: 0.35rem 0 0;
    font-size: 0.82rem;
    color: var(--k-text-muted);
}

/* ---- Logs tab ------------------------------------------------------------------------------------ */
.kl-fb-log-tokens[b-lc3t7ob1ea] {
    margin: 0.25rem 0;
    padding-inline-start: 1.1rem;
    font-size: 0.82rem;
}

.kl-fb-crumbs[b-lc3t7ob1ea] {
    margin: 0.25rem 0;
    padding-inline-start: 1.25rem;
    font-size: 0.82rem;
}

.kl-fb-crumb[b-lc3t7ob1ea] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.45rem;
    padding: 0.12rem 0;
    border-bottom: 1px dotted var(--k-border);
}

.kl-fb-crumb-t[b-lc3t7ob1ea] {
    min-width: 4.5rem;
    color: var(--k-text-muted);
    font-variant-numeric: tabular-nums;
    font-size: 0.75rem;
}

.kl-fb-crumb-kind[b-lc3t7ob1ea] {
    font-weight: 600;
}

.kl-fb-kvtable[b-lc3t7ob1ea] {
    border-collapse: collapse;
    font-size: 0.82rem;
}

.kl-fb-kvtable th[b-lc3t7ob1ea] {
    text-align: start;
    color: var(--k-text-muted);
    font-weight: 500;
    padding: 0.15rem 0.75rem 0.15rem 0;
}

.kl-fb-kvtable td[b-lc3t7ob1ea] {
    font-variant-numeric: tabular-nums;
}

/* ---- Shared escaped panes + actions -------------------------------------------------------------- */
.kl-fb-dom[b-lc3t7ob1ea],
.kl-fb-bundle[b-lc3t7ob1ea],
.kl-fb-diff[b-lc3t7ob1ea] {
    max-height: 320px;
    overflow: auto;
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: 6px;
    padding: 0.5rem;
    font-size: 0.75rem;
    white-space: pre-wrap;
    word-break: break-word;
}

.kl-fb-detail-shot[b-lc3t7ob1ea] {
    max-width: 100%;
    border: 1px solid var(--k-border);
    border-radius: 6px;
}

/* The Decision-tab inline capture is a PREVIEW — capped so it doesn't dominate the brief; the Report tab
   carries the full-size view. */
.kl-fb-decision-shot[b-lc3t7ob1ea] {
    max-height: 22rem;
    object-fit: contain;
    object-position: left top;
    display: block;
}

.kl-fb-thumb--blocked[b-lc3t7ob1ea] {
    padding: 0.5rem;
    font-size: 0.75rem;
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border: 1px dashed var(--k-border);
    border-radius: 4px;
}

.kl-fb-detail-actions[b-lc3t7ob1ea] {
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--k-border);
}

.kl-fb-reject[b-lc3t7ob1ea],
.kl-fb-verify[b-lc3t7ob1ea],
.kl-fb-park[b-lc3t7ob1ea] {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.4rem;
}

.kl-fb-detail-replay iframe[b-lc3t7ob1ea] {
    width: 100%;
    min-height: 320px;
    border: 1px solid var(--k-border);
    border-radius: 6px;
}

.kl-fb-card-purge[b-lc3t7ob1ea] {
    font-size: 0.75rem;
    color: var(--k-text-muted);
    margin-top: 0.5rem;
}

/* ---- dark (BARE html.dark) ----------------------------------------------------------------------- */
html.dark .kl-fb-brief-head[b-lc3t7ob1ea],
html.dark .kl-fb-logdigest[b-lc3t7ob1ea],
html.dark .kl-fb-detail-comment[b-lc3t7ob1ea],
html.dark .kl-fb-tab--active[b-lc3t7ob1ea],
html.dark .kl-fb-dom[b-lc3t7ob1ea],
html.dark .kl-fb-bundle[b-lc3t7ob1ea],
html.dark .kl-fb-diff[b-lc3t7ob1ea],
html.dark .kl-fb-proof-excerpt[b-lc3t7ob1ea],
html.dark .kl-fb-proof-raw[b-lc3t7ob1ea],
html.dark .kl-fb-thumb--blocked[b-lc3t7ob1ea] {
    background: #16222c;
    border-color: #2c3a45;
}

html.dark .kl-fb-proof--proven[b-lc3t7ob1ea] {
    background: color-mix(in srgb, var(--k-success) 14%, #101a22);
    border-color: color-mix(in srgb, var(--k-success) 45%, #2c3a45);
}

html.dark .kl-fb-proof--unproven[b-lc3t7ob1ea] {
    background: color-mix(in srgb, var(--k-caution) 14%, #101a22);
    border-color: color-mix(in srgb, var(--k-caution) 45%, #2c3a45);
}

/* Phase G R5 — the reporter-rejection banner leading the Decision brief. */
.kl-fb-unresolved-banner strong[b-lc3t7ob1ea] {
    letter-spacing: 0.02em;
}

.kl-fb-unresolved-note[b-lc3t7ob1ea] {
    margin: 0.35rem 0 0;
    font-style: italic;
}

.kl-fb-unresolved-at[b-lc3t7ob1ea] {
    font-size: 0.8rem;
    opacity: 0.8;
}

/* Phase G WP-G2 — the agency-visible public-note editor (the one note-egress field). */
.kl-fb-publicnote[b-lc3t7ob1ea] {
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--k-border);
}

.kl-fb-publicnote-hint[b-lc3t7ob1ea] {
    font-weight: 400;
    font-size: 0.8rem;
    color: var(--k-text-muted);
}

.kl-fb-publicnote-editor[b-lc3t7ob1ea] {
    width: 100%;
    margin-bottom: 0.4rem;
    resize: vertical;
}

/* Full-screen two-column Decision brief (owner-directed 2026-07-08): evidence reads down the left; the
   decision rail (actions + agency note) sits sticky on the right so acting never scrolls away from the
   evidence. Collapses to one column on narrow viewports. */
.kl-fb-decision-grid[b-lc3t7ob1ea] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(300px, 380px);
    gap: 1.5rem;
    align-items: start;
}

.kl-fb-decision-main[b-lc3t7ob1ea] {
    min-width: 0;
}

.kl-fb-decision-rail[b-lc3t7ob1ea] {
    position: sticky;
    top: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem;
    border: 1px solid var(--k-border);
    border-radius: 10px;
    background: var(--k-surface, transparent);
}

.kl-fb-decision-rail .kl-fb-detail-actions[b-lc3t7ob1ea],
.kl-fb-decision-rail .kl-fb-publicnote[b-lc3t7ob1ea] {
    margin: 0;
    padding: 0;
    border-top: none;
}

.kl-fb-decision-rail .kl-fb-publicnote[b-lc3t7ob1ea] {
    padding-top: 0.75rem;
    border-top: 1px solid var(--k-border);
}

@media (max-width: 980px) {
    .kl-fb-decision-grid[b-lc3t7ob1ea] {
        grid-template-columns: 1fr;
    }

    .kl-fb-decision-rail[b-lc3t7ob1ea] {
        position: static;
    }
}

/* Ask-Claude with the prompt-injection review checkbox (owner ruling 2026-07-09). */
.kl-fb-askclaude[b-lc3t7ob1ea] {
    padding-top: 0.75rem;
    border-top: 1px solid var(--k-border);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.kl-fb-askclaude-approve[b-lc3t7ob1ea] {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    font-size: 0.85rem;
    line-height: 1.35;
    cursor: pointer;
}

.kl-fb-askclaude-hint[b-lc3t7ob1ea] {
    color: var(--k-text-muted);
}

/* Injection caution shown only when the operator opts to include reporter prose (fenced-as-untrusted downstream). */
.kl-fb-askclaude-warn[b-lc3t7ob1ea] {
    margin: 0.4rem 0 0;
    padding: 0.4rem 0.55rem;
    border-left: 3px solid #bf8700;
    border-radius: 4px;
    background: color-mix(in srgb, #bf8700 9%, transparent);
    font-size: 0.82rem;
    line-height: 1.35;
}

/* Reporter reply round-trip — the "Reporter replies" section + the awaiting/ask affordances. */
.kl-fb-replies[b-lc3t7ob1ea] {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-bottom: 0.5rem;
}

.kl-fb-reply[b-lc3t7ob1ea] {
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--k-border, #d8dee6);
    border-inline-start: 3px solid var(--k-accent, #3b6ea5);
    border-radius: 0 8px 8px 0;
    background: var(--k-surface-2, #f7f9fc);
}

.kl-fb-reply-when[b-lc3t7ob1ea] {
    font-size: 0.75rem;
    color: var(--k-text-muted);
}

.kl-fb-reply-body[b-lc3t7ob1ea] {
    margin: 0.3rem 0 0;
    white-space: pre-wrap;
}

.kl-fb-reply-atts[b-lc3t7ob1ea] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.kl-fb-reply-thumb[b-lc3t7ob1ea] {
    inline-size: 4rem;
    block-size: 4rem;
    object-fit: cover;
    border-radius: 4px;
    border: 1px solid var(--k-border, #cfd6df);
}

.kl-fb-reply-att[b-lc3t7ob1ea] {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.55rem;
    border: 1px solid var(--k-border, #cfd6df);
    border-radius: 6px;
    background: var(--k-surface, #fff);
    font-size: 0.8rem;
}

.kl-fb-publicnote-actions[b-lc3t7ob1ea] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    margin-top: 0.5rem;
}

.kl-fb-awaiting-reply[b-lc3t7ob1ea] {
    font-size: 0.8rem;
    color: var(--k-text-muted);
    font-style: italic;
}

/* Rescind — the withdrawn banner (muted amber). */
.kl-fb-rescinded-banner[b-lc3t7ob1ea] {
    background: #f7ecd0;
    color: #7a4f00;
    border: 1px solid #e3b341;
}

/* Star — the toggle button's starred state. */
.kl-fb-star-btn.is-starred[b-lc3t7ob1ea] {
    color: #8a6d1f;
    border-color: #e3b341;
    background: #fbf1d3;
}

/* Kanban rework (2026-07-10) — Accept picker, Claude question panel, and the Claude tab. */
.kl-fb-accept[b-lc3t7ob1ea] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
}

.kl-fb-accept-target[b-lc3t7ob1ea] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
}

.kl-fb-merging-note[b-lc3t7ob1ea] {
    background: #e4eefb;
    color: #26538c;
}

.kl-fb-claude-question[b-lc3t7ob1ea] {
    margin-top: 0.9rem;
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--k-border, #d8dee6);
    border-inline-start: 3px solid #7a4fd0;
    border-radius: 0 8px 8px 0;
    background: var(--k-surface-2, #f7f9fc);
}

.kl-fb-claude-question-text[b-lc3t7ob1ea] {
    margin: 0.25rem 0 0.5rem;
    white-space: pre-wrap;
}

.kl-fb-claude-answer[b-lc3t7ob1ea] {
    inline-size: 100%;
    box-sizing: border-box;
    resize: vertical;
    font: inherit;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--k-border, #cfd6df);
    border-radius: 6px;
    margin-bottom: 0.4rem;
}

.kl-fb-claude-answered[b-lc3t7ob1ea] {
    font-size: 0.85rem;
    color: var(--k-text-muted);
}

.kl-fb-claude-tab .kl-fb-claude-feed[b-lc3t7ob1ea] {
    max-block-size: 20rem;
    overflow-y: auto;
    background: #101418;
    color: #d6e2ee;
    border-radius: 8px;
    padding: 0.6rem 0.8rem;
    font-family: ui-monospace, monospace;
    font-size: 0.78rem;
}

.kl-fb-claude-feed-line[b-lc3t7ob1ea] {
    margin: 0 0 0.15rem;
    white-space: pre-wrap;
    word-break: break-word;
}

.kl-fb-claude-round[b-lc3t7ob1ea] {
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--k-border, #d8dee6);
    border-radius: 8px;
    margin-bottom: 0.5rem;
    background: var(--k-surface-2, #f7f9fc);
}

.kl-fb-claude-round-head[b-lc3t7ob1ea] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.kl-fb-claude-round-when[b-lc3t7ob1ea] {
    font-size: 0.75rem;
    color: var(--k-text-muted);
}

.kl-fb-claude-summary[b-lc3t7ob1ea] {
    margin: 0.4rem 0 0;
    white-space: pre-wrap;
    word-break: break-word;
    font-size: 0.8rem;
    background: var(--k-surface, #fff);
    border-radius: 6px;
    padding: 0.5rem 0.6rem;
    max-block-size: 14rem;
    overflow-y: auto;
}

.kl-fb-claude-outcome[b-lc3t7ob1ea] {
    background: #ece4fb;
    color: #4d2f8c;
}

/* Reporter-reply alert (owner-directed 2026-07-12) — top-of-ticket, unmissable across tabs. */
.kl-fb-reply-alert[b-lc3t7ob1ea] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.5rem 0 0.25rem;
    padding: 0.55rem 0.8rem;
    border-radius: 8px;
    border: 1px solid #b9d5f0;
    border-inline-start: 3px solid #2f6fb0;
    background: #eaf2fb;
    color: #204971;
    font-size: 0.9rem;
}

.kl-fb-reply-alert-icon[b-lc3t7ob1ea] { font-size: 1.1rem; }

@media (prefers-color-scheme: dark) {
    .kl-fb-reply-alert[b-lc3t7ob1ea] { background: #16283a; color: #cfe3f7; border-color: #2f5a7a; }
}

/* Stalled round (dead-claim fix, 2026-07-12) — a claimed task whose lease expired; the runner didn't finish. */
.kl-fb-claude-state--stalled[b-lc3t7ob1ea] {
    border: 1px solid #e0b483;
    border-inline-start: 3px solid #d98a2b;
    border-radius: 8px;
    padding: 0.6rem 0.8rem;
    background: #fdf3e6;
}

@media (prefers-color-scheme: dark) {
    .kl-fb-claude-state--stalled[b-lc3t7ob1ea] { background: #3a2a14; border-color: #6b4a20; }
}
/* _content/Kanine.Web/Components/Feedback/FeedbackReviewSurface.razor.rz.scp.css */
/*
    The triage detail surface's own scoped sheet — NEW 2026-09-13, and the reason the panel now reads.

    WHAT WAS WRONG. Every rule below used to live in FeedbackTriage.razor.css. Blazor stamps a component's scope
    attribute onto the markup declared in THAT component only, so a `.kl-feedback-review-dl` rule written in the
    page's sheet compiled to `.kl-feedback-review-dl[b-08ip9qfmq7]` and could never match the <dl>, which this
    component renders. Probed live on /feedback at 1400x900 before the move:

        <dl class="kl-feedback-review-dl">  attributes: ["class"]        <- no scope attribute
        computed display: block             (the sheet asked for grid)
        computed grid-template-columns: none

    So the entire body of the panel rendered as browser-default definition-list markup — labels and values on
    separate lines, no columns, no alignment, no rhythm. "Visually it needs to be more understandable" was, in
    large part, a stylesheet that had never applied. Rules that belong to this component live beside it now.

    ONE RULE SURVIVED THE BUG AND IS WORTH NAMING: `.kl-feedback-review-actions` computed `display:flex` all
    along — not from the page sheet, but from the unscoped `[class$="-actions"]` family in the design system.
    A suffix family can make a dead rule look alive, which is exactly why the probe reads computed style per
    element rather than trusting that a sheet exists.

    CLASS-FAMILY CLEARANCE (the `[class$="-…"]` trap, 69 live families). Deliberate joins: `-actions` (flex +
    justify-content:flex-end, §5d), `-note` (13px muted), `-label` on the outcome captions (13px/600/muted,
    §296) — all wanted, all inherited on purpose. New names checked and free: `-lede`, `-heading`, `-outcomes`,
    `-outcome`, `-frequency`, `-exchange`, `-where`, `-raw`, `-dl`, `-tech`. The `--actual` modifier is written
    BEFORE the base class so the base stays the attribute's ending (Trap T7).
*/

.kl-feedback-review > section[b-l48kmg11bj] {
    margin-block-end: 1.25rem;
}

.kl-feedback-review > section:last-child[b-l48kmg11bj] {
    margin-block-end: 0;
}

/* One heading treatment for every block, so the panel reads as a sequence of named parts rather than a wall.
   h2 for the lede and h3 for the rest keeps the outline honest without two visual sizes. */
.kl-feedback-review-heading[b-l48kmg11bj] {
    margin: 0 0 0.45rem;
    font-family: var(--k-font-display);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

/* THE LEDE — the reporter's own words, first and at reading size. */
.kl-feedback-review-lede[b-l48kmg11bj] {
    padding: 0.9rem 1rem;
    border: 1px solid var(--k-border, #e2e6ec);
    border-inline-start: 4px solid var(--k-accent, #2f6feb);
    border-radius: 8px;
    background: var(--k-surface-2, #f7f9fc);
}

.kl-feedback-review-raw[b-l48kmg11bj] {
    margin: 0;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--k-text);
    max-inline-size: 76ch;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* Expected versus actual, side by side on a desk and stacked on a phone. auto-fit keeps that behaviour in one
   declaration — no media query, and no width at which one column is left orphaned mid-row. */
.kl-feedback-review-outcomes[b-l48kmg11bj] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.6rem;
    margin-block-start: 0.9rem;
}

.kl-feedback-review-outcome[b-l48kmg11bj] {
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--k-border, #e2e6ec);
    border-radius: 6px;
    background: var(--k-surface, #fff);
    min-inline-size: 0;
}

.kl-feedback-review-outcome-label[b-l48kmg11bj] {
    display: block;
    margin-block-end: 0.2rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.kl-feedback-review-outcome p[b-l48kmg11bj] {
    margin: 0;
    font-size: 0.92rem;
    line-height: 1.45;
    overflow-wrap: anywhere;
}

/* "Actual" is the half that is wrong; it carries the only colour in the block so the eye lands there. */
.kl-feedback-review-outcome--actual[b-l48kmg11bj] {
    border-inline-start: 3px solid var(--k-critical);
}

.kl-feedback-review-frequency[b-l48kmg11bj] {
    margin: 0.75rem 0 0;
    font-size: 0.9rem;
    color: var(--k-text-muted);
}

.kl-feedback-review-exchange[b-l48kmg11bj] {
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--k-border, #e2e6ec);
    border-radius: 8px;
}

/* Moved here 2026-09-13 from FeedbackTriage.razor.css, where it was scoped to the page and therefore never
   matched this component's markup. The accent treatment is the original intent, now applied for the first time. */
.kl-feedback-review-publicnote[b-l48kmg11bj] {
    margin: 0;
    padding: 0.5rem 0.75rem;
    border-inline-start: 3px solid var(--k-accent, #2f6feb);
    border-radius: 4px;
    background: color-mix(in srgb, var(--k-accent, #2f6feb) 6%, transparent);
    font-size: 0.95rem;
    line-height: 1.45;
    overflow-wrap: anywhere;
}

.kl-feedback-review-note[b-l48kmg11bj] {
    margin: 0.4rem 0 0;
}

/* THE FACT ROWS. The two-column grid is what makes a label a label: it aligns every value on one axis so the
   eye can run down the values without reading the labels twice. `max-content` (not `auto`) stops a long value
   from stealing the label column's width. */
.kl-feedback-review-dl[b-l48kmg11bj] {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 0.35rem 1rem;
    margin: 0;
    font-size: 0.9rem;
    align-items: baseline;
}

.kl-feedback-review-dl dt[b-l48kmg11bj] {
    font-weight: 600;
    color: var(--k-text-muted);
}

.kl-feedback-review-dl dd[b-l48kmg11bj] {
    margin: 0;
    min-inline-size: 0;
    overflow-wrap: anywhere;
}

.kl-feedback-review-dl dd code[b-l48kmg11bj] {
    font-size: 0.85rem;
}

/* At phone widths the label column would leave a value 12 characters wide, so the pairs stack. The dt keeps its
   muted weight, which is what still marks it as the label once the column is gone. */
@media (max-width: 30rem) {
    .kl-feedback-review-dl[b-l48kmg11bj] {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.1rem;
    }

    .kl-feedback-review-dl dd[b-l48kmg11bj] {
        margin-block-end: 0.45rem;
    }
}

.kl-feedback-review img[b-l48kmg11bj] {
    max-width: 100%;
    border: 1px solid var(--k-border);
    border-radius: 6px;
}

.kl-feedback-review-actions[b-l48kmg11bj] {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* The actions row renders EMPTY on the common path now — the owner's 2026-09-13 ruling removed the agency's
   "Needs info" button, and the step-up request is absent until the CJIS addendum is executed. An empty flex row
   still takes its parent's block margin, which left a stray gap at the foot of every panel. :empty removes it
   without hiding a row that has something in it. */
.kl-feedback-review-actions:empty[b-l48kmg11bj] {
    display: none;
}

html.dark .kl-feedback-review-lede[b-l48kmg11bj] {
    background: #16202a;
}

html.dark .kl-feedback-review-outcome[b-l48kmg11bj] {
    background: #10181f;
}

html.dark .kl-feedback-review img[b-l48kmg11bj] {
    border-color: #2c3a45;
}
/* _content/Kanine.Web/Components/Feedback/FixRunnerCockpit.razor.rz.scp.css */
/* The fix-runner cockpit — calm, instrument-like local tooling (mono feed, quiet pills), visually distinct
   from customer data. Bare html.dark for dark overrides (the :global(html.dark) dead-rule trap). */

.kl-frc[b-0u2skv207z] {
    border: 1px solid var(--k-border);
    border-radius: 8px;
    background: var(--k-surface-2);
    margin-bottom: 0.75rem;
}

.kl-frc-head[b-0u2skv207z] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.5rem 0.9rem;
    background: none;
    border: 0;
    cursor: pointer;
    font: inherit;
    text-align: start;
    color: inherit;
}

.kl-frc-caret[b-0u2skv207z] {
    font-size: 0.7rem;
    color: var(--k-text-muted);
}

.kl-frc-title[b-0u2skv207z] {
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.04em;
}

.kl-frc-subtag[b-0u2skv207z] {
    font-size: 0.7rem;
    color: var(--k-text-muted);
    letter-spacing: 0.03em;
    border: 1px solid var(--k-border);
    border-radius: 999px;
    padding: 0.05rem 0.5rem;
}

/* The state pill — one quiet color per loop state, pushed to the trailing edge. */
.kl-frc-pill[b-0u2skv207z] {
    margin-inline-start: auto;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    border-radius: 999px;
    padding: 0.1rem 0.6rem;
    border: 1px solid var(--k-border);
    color: var(--k-text-muted);
    background: var(--k-surface);
}

.kl-frc-pill--idle[b-0u2skv207z] {
    color: var(--k-info);
    border-color: color-mix(in srgb, var(--k-info) 45%, var(--k-border));
    background: color-mix(in srgb, var(--k-info) 8%, var(--k-surface));
}

.kl-frc-pill--working[b-0u2skv207z] {
    color: var(--k-success);
    border-color: color-mix(in srgb, var(--k-success) 45%, var(--k-border));
    background: color-mix(in srgb, var(--k-success) 8%, var(--k-surface));
}

.kl-frc-pill--stopping[b-0u2skv207z] {
    color: var(--k-caution);
    border-color: color-mix(in srgb, var(--k-caution) 45%, var(--k-border));
    background: color-mix(in srgb, var(--k-caution) 8%, var(--k-surface));
}

.kl-frc-body[b-0u2skv207z] {
    padding: 0 0.9rem 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.kl-frc-note[b-0u2skv207z] {
    margin: 0;
}

.kl-frc-statusline[b-0u2skv207z] {
    display: flex;
    gap: 0.9rem;
    align-items: center;
    flex-wrap: wrap;
    font-size: 0.78rem;
    color: var(--k-text-muted);
    min-height: 1rem;
}

.kl-frc-stoppending[b-0u2skv207z] {
    color: var(--k-caution);
    font-weight: 600;
}

.kl-frc-actions[b-0u2skv207z] {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    flex-wrap: wrap;
}

.kl-frc-confirm-wrap[b-0u2skv207z] {
    display: inline-flex;
    gap: 0.4rem;
    align-items: center;
}

.kl-frc-confirm-copy[b-0u2skv207z] {
    font-size: 0.75rem;
    color: var(--k-text-muted);
}

.kl-frc-confirm-yes[b-0u2skv207z] {
    background: var(--k-critical);
    border-color: var(--k-critical);
    color: #fff;
}

.kl-frc-kill[b-0u2skv207z] {
    color: var(--k-critical);
}

.kl-frc-accountrow[b-0u2skv207z] {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    flex-wrap: wrap;
}

.kl-frc-account-label[b-0u2skv207z] {
    display: inline-flex;
    gap: 0.5rem;
    align-items: center;
    font-size: 0.8rem;
}

.kl-frc-hint[b-0u2skv207z] {
    font-size: 0.72rem;
    color: var(--k-text-muted);
    font-style: italic;
}

/* The headspace feed — a scrollable mono panel, the goal-chain terminal's visual vocabulary:
   asst = normal, tool = accent, info = muted, result = emphasis, raw = dim mono noise. */
.kl-frc-feed[b-0u2skv207z] {
    max-height: 260px;
    overflow-y: auto;
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: 6px;
    padding: 0.5rem;
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 0.72rem;
    line-height: 1.45;
}

.kl-frc-feed-empty[b-0u2skv207z] {
    color: var(--k-text-muted);
    font-style: italic;
}

.kl-frc-line[b-0u2skv207z] {
    white-space: pre-wrap;
    word-break: break-word;
}

.kl-frc-line--tool[b-0u2skv207z] {
    color: var(--k-accent);
}

.kl-frc-line--info[b-0u2skv207z] {
    color: var(--k-text-muted);
}

.kl-frc-line--result[b-0u2skv207z] {
    color: var(--k-success);
    font-weight: 600;
}

.kl-frc-line--raw[b-0u2skv207z] {
    color: var(--k-text-muted);
    opacity: 0.8;
}

html.dark .kl-frc[b-0u2skv207z] {
    background: #16222c;
    border-color: #2c3a45;
}

html.dark .kl-frc-feed[b-0u2skv207z] {
    background: #0c141b;
    border-color: #2c3a45;
}

html.dark .kl-frc-pill[b-0u2skv207z] {
    background: #101a22;
    border-color: #2c3a45;
}
/* _content/Kanine.Web/Components/Layout/AuthLayout.razor.rz.scp.css */
/*
  UI-GUAR-011 (R11) — scoped layout for the CHROMELESS pre-auth shell (AuthLayout). The component foundation
  (cards / inputs / buttons / chips / color-schemes) is inherited GLOBALLY via the <main>'s `kl-shell-main`
  class (kanine-design-system.css). These rules supply ONLY the chromeless page layout the prototype's
  login.html <body> uses ("min-h-screen flex flex-col justify-center items-center"): a full-viewport column
  that vertically centers the login card, with NO rail-beside-content offset. Logical properties throughout so
  it mirrors cleanly under dir="rtl" when the i18n engine lands (PLAT-008 / Phase-6).
*/

.kl-auth[b-8h5fozbdh7] {
    min-block-size: 100vh;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    max-inline-size: 100%;
}

.kl-auth-main[b-8h5fozbdh7] {
    flex: 1 1 auto;
    box-sizing: border-box;
    inline-size: 100%;
    max-inline-size: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    /* Fluid gutters (mirror MainLayout's scale, but no rail to clear): tight on phones, generous on desktops.
       border-box + max-inline-size:100% keep within the §6.2 zero-horizontal-overflow budget at every width. */
    padding-block: clamp(1.5rem, 4vw, 3rem);
    padding-inline: clamp(1rem, 4vw, 2rem);
}

/* The framework error overlay rendered by THIS layout. The base styling (incl. display:none-by-default) is
   otherwise only in MainLayout.razor.css, which is Blazor-SCOPED to MainLayout and so does not reach AuthLayout's
   own #blazor-error-ui — without this the banner would paint visible on the login screen. Mirrors MainLayout's
   block; the framework's blazor.web.js still reveals it via an inline display:block when a circuit error occurs. */
#blazor-error-ui[b-8h5fozbdh7] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-8h5fozbdh7] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* _content/Kanine.Web/Components/Layout/MainLayout.razor.rz.scp.css */
/*
  P5 client-parity (web-first) — the application-shell scoped CSS for MainLayout's own elements: the shell container
  (.kl-shell), the page content region (.kl-shell-main) and the framework error overlay. The shell CHROME itself (the
  left rail + top bar + mobile bottom nav) is ShellNav's, styled globally in kanine-design-system.css §7 — including
  the desktop "rail beside content" offset that pads .kl-shell. Logical properties only (padding-inline / inset) so
  the shell mirrors cleanly under dir="rtl" when the i18n engine lands (PLAT-008 / Phase-6).
*/

.kl-shell[b-8fngpw6lxe] {
  display: flex;
  flex-direction: column;
  min-block-size: 100vh;
  box-sizing: border-box;
  max-inline-size: 100%;
}

.kl-shell-main[b-8fngpw6lxe] {
  flex: 1 1 auto;
  box-sizing: border-box;
  inline-size: 100%;
  max-inline-size: 100%;
  /* Fluid gutters: the content's side (and top/bottom) padding SCALES with the viewport — tight on phones, generous
     on laptops/desktops — so pages read consistently across screen sizes instead of hugging the rail. clamp(min,
     preferred, max): ~1rem at 320px, growing through the mid widths, capped at 4rem (sides) / 2rem (block) on large
     screens. border-box + max-inline-size:100% keep it within the §6.2 zero-horizontal-overflow budget at every width. */
  padding-block: clamp(1rem, 2vw, 2rem);
  padding-inline: clamp(1rem, 4vw, 4rem);
}

/* Mobile + landscape tablet (<=1280px): the bottom nav is a FIXED, bottom-docked bar (kanine-design-system.css §7 —
   out of flow), so the content region must clear it itself or a tall page's last rows hide behind the bar. Keep the
   fluid block gutter and ADD the bar height (+ the iOS safe-area inset the bar absorbs). Lives HERE because this
   scoped sheet owns .kl-shell-main's padding (its padding-block shorthand above would out-order an external
   override).
   THIS QUERY MUST TRACK the drawer/bottom-nav breakpoint in kanine-design-system.css §7 (raised 1024 -> 1280 by the
   owner ruling 2026-07-24 so a ~1280 landscape tablet reclaims the rail's 240px). If the two drift, the content is
   either padded to clear a bar that is not there, or hidden behind a bar that is. */
@media (max-width: 1280px) {
  .kl-shell-main[b-8fngpw6lxe] {
    /* PHONE-LAYOUT P3 (2026-10): plus --k-fab-clearance (kanine-feedback.css), the room for the feedback FAB and the
       capture "+" that float over the page above the bar. Same value as the MAUI head, so the two heads agree. */
    padding-block-end: calc(clamp(1rem, 2vw, 2rem) + var(--k-bottomnav-h, 56px) + env(safe-area-inset-bottom, 0px) + var(--k-fab-clearance, 5rem));
  }
}

/* …UNLESS the user has explicitly PINNED the rail in the 1025-1280 band (owner ruling 2026-07-24): the rail is the
   navigation again, so kanine-design-system.css stands the bottom bar down — and this clearance must stand down
   with it or the page reserves 56px for a bar that is not there. A bare `html[…]` ancestor selector is correct in a
   scoped sheet (the scope attribute lands on .kl-shell-main, the last compound); `:global(…)` would be the dead-rule
   trap. Phones (<=1024) can never reach the pinned state, so their clearance above is untouched. */
@media (min-width: 1025px) and (max-width: 1280px) {
  html[data-shellrail="pinned"] .kl-shell-main[b-8fngpw6lxe] {
    padding-block-end: clamp(1rem, 2vw, 2rem);
  }
}

/* The framework error overlay (rendered by this layout below the shell). Preserved from the template. */
#blazor-error-ui[b-8fngpw6lxe] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-8fngpw6lxe] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* _content/Kanine.Web/Components/MetricTileGrid.razor.rz.scp.css */
/* =============================================================================
   MetricTileGrid — the ONE metric-tile card skin (UI-GUAR-011, restrained-premium)
   -----------------------------------------------------------------------------
   Consolidates the two drifted copies (kl-rel-tile-* on the single-K9 dashboard,
   kl-agency-tile-* on the unit-wide rollup) into one scoped stylesheet, taken
   from the reliability tile (the more refined of the two) plus the agency tile's
   baseline-alignment rule (margin-block-start:auto on the value), which kept the
   headline figures on a common baseline across a grid row regardless of
   name-wrap or chip presence. Consumes the foundation vocabulary (kl-chip,
   --k-* channels); no off-token colour, no gradient — light/dark/outdoor ride
   the flipping channels.
   ========================================================================== */

.kl-mtile-grid[b-1mviakn0k5] {
    display: grid;
    gap: var(--k-space-4);
    grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
    /* No margin-block-end — the .kl-page flex gap already separates the grid from the next
       section; an extra margin doubled the gap here only, breaking the section rhythm. */
}

.kl-mtile[b-1mviakn0k5] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-6) var(--k-space-6) var(--k-space-4);
    /* a quiet teal rail anchors the tile as an evidentiary metric (on-brand accent, not decoration). */
    border-inline-start: 3px solid color-mix(in srgb, var(--k-teal-500) 55%, var(--k-border));
    transition: box-shadow var(--k-dur-2) var(--k-ease), transform var(--k-dur-2) var(--k-ease);
}
.kl-mtile:hover[b-1mviakn0k5] {
    box-shadow: var(--k-elev-2);
    transform: translateY(-1px);
}

.kl-mtile-head[b-1mviakn0k5] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-3);
}
/* The catalog id is machine provenance, not a caption (see the note in MetricTileGrid.razor). Clipped from
   the visual surface, aria-hidden in the markup, and STILL IN THE DOM so its leaf test hook resolves.
   `position:absolute` + a 1px clip is the house sr-only recipe; `display:none` would remove it from the
   accessibility tree AND from textContent, which is what the E2E contract reads.
   Removing the chip also retires the head's `flex-wrap:wrap` + `justify-content:space-between`: both existed
   only to stop a long id ("RPT-006-CERTIFICATION") overhanging the tile's inline-end edge, which was the
   design-skeptic blocker recorded in ProposedUI/docs/UI-OPEN-QUESTIONS.md. Nothing can overhang now. */
.kl-mtile-idhook[b-1mviakn0k5] {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
.kl-mtile-name[b-1mviakn0k5] {
    font-family: var(--k-font-display);
    font-size: 15px;
    font-weight: 700;
    line-height: 1.25;
    margin: 0;
    min-width: 0;
    color: var(--k-text);
}
/* The headline figure — large, display-weight, tabular so columns of figures align. Pushed to the
   tile foot (margin-block-start:auto) so figures share a baseline across a grid row. */
.kl-mtile-value[b-1mviakn0k5] {
    font-family: var(--k-font-display);
    font-size: clamp(28px, 3.2vw, 38px);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.02em;
    margin: 0;
    margin-block-start: auto;
    color: var(--k-text);
    font-variant-numeric: tabular-nums;
}
/* An undefined ("N/A") figure is muted + lighter so it never reads as a real measured value (PLAT-012). */
.kl-mtile-value[data-defined="false"][b-1mviakn0k5] {
    color: var(--k-text-muted);
    font-weight: 700;
    font-size: clamp(20px, 2.2vw, 26px);
}

.kl-mtile-frac[b-1mviakn0k5] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--k-space-1) var(--k-space-3);
    color: var(--k-text-muted);
    font-size: 13px;
}
/* The basis line reads as a SENTENCE, so it wears the text face, not the mono face the fraction wore.
   `tabular-nums` stays: the integers inside the sentence still sit in a column of tiles. */
.kl-mtile-numdenom[b-1mviakn0k5] {
    font-size: 13px;
    color: var(--k-text);
    font-variant-numeric: tabular-nums;
}
.kl-mtile-n[b-1mviakn0k5] {
    color: var(--k-text-muted);
    font-variant-numeric: tabular-nums;
}
/* The universe line is present in the DOM on every tile (so `data-sample` is always readable) but carries
   TEXT only where it adds something. An empty flex child still consumes a `column-gap`, so take the empty
   case out of flow entirely rather than leaving a zero-width span pushing the line. */
.kl-mtile-n:empty[b-1mviakn0k5] { display: none; }
/* ...and when the whole sub-line row has nothing to say - a COUNT tile, whose numerator, denominator and sample
   are all the headline figure - the ROW itself leaves the flow. `:empty` cannot express that: the row still holds
   the universe span (kept so `data-sample` is always readable), so it is not empty in CSS terms, and a zero-height
   flex child still consumes a full `row-gap`. Measured on the count tiles: 12px of nothing, on every one of the
   three RPT-006 cards. Same family as the `*-committed` phantom-gap trap (worklist W2), one level down. */
.kl-mtile-frac:not(:has(> .kl-mtile-numdenom)):has(> .kl-mtile-n:empty)[b-1mviakn0k5] { display: none; }

/* the incomplete-rows caution chip rides the foundation kl-chip--caution; just seat it at the tile foot. */
.kl-mtile-incomplete[b-1mviakn0k5] {
    align-self: flex-start;
}

/* -----------------------------------------------------------------------------
   RPT-013 — the DRILLABLE card (owner ask 2026-09-11: clicking a tile lists the
   records behind it). The card element becomes a <button>, so the only job here
   is to undo the UA button chrome and give the control back the card's own
   geometry and typography. Nothing below changes a size, a colour token or the
   card's layout: a drillable card and an inert one measure identically, which is
   what keeps the two arms of the component honestly interchangeable.
   -------------------------------------------------------------------------- */
.kl-mtile--drillable[b-1mviakn0k5] {
    /* UA reset — appearance, the UA border/background, the centred text and the
       UA font. `inherit` on font is deliberate: a button does NOT inherit the
       page face, and without this the headline figure silently lost its display
       face and its tabular figures. */
    appearance: none;
    -webkit-appearance: none;
    font: inherit;
    color: inherit;
    text-align: start;
    inline-size: 100%;
    cursor: pointer;
    /* A6 — stated explicitly rather than relied upon. The card's own padding puts
       it far past the floor, but the floor is not left to a side effect. */
    min-block-size: var(--k-touch);
}
/* The keyboard affordance the <section> never needed. The house focus ring, not
   the UA outline, and OUTSIDE the card so the 3px teal rail is not overpainted. */
.kl-mtile--drillable:focus-visible[b-1mviakn0k5] {
    outline: 2px solid var(--k-focus, var(--k-teal-500));
    outline-offset: 2px;
}
/* The hover lift already exists on .kl-mtile; a pressed card settles back so the
   card reads as a control rather than as a card that happens to move. */
.kl-mtile--drillable:active[b-1mviakn0k5] {
    transform: none;
    box-shadow: var(--k-elev-1);
}
@media (prefers-reduced-motion: reduce) {
    .kl-mtile--drillable[b-1mviakn0k5] { transition: none; }
    .kl-mtile--drillable:hover[b-1mviakn0k5] { transform: none; }
}
/* _content/Kanine.Web/Components/Pages/ActivityDetail.razor.rz.scp.css */
/* =============================================================================
   ActivityDetail (/activities/{id}) — UI-GUAR-019 read-only activity detail.
   -----------------------------------------------------------------------------
   Single-column, token-only (--k-*) elevated cards mirroring MedicalDetail. No
   fixed px widths / x-overflow clips, so it stays 320px-clean (the RESPONSIVE
   tooth). The identity hero + every section header lead with a large .ki icon
   (the HEADER tooth); the icon flips per-mode via --k-accent.
   ========================================================================== */

.kl-actd-header[b-nzjttsv2k8] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--k-space-4);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-2);
    padding: var(--k-space-6);
}

.kl-actd-identity[b-nzjttsv2k8] {
    display: flex;
    align-items: center;
    gap: var(--k-space-4);
    min-inline-size: 0;
}

.kl-actd-disc[b-nzjttsv2k8] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 48px;
    block-size: 48px;
    border-radius: var(--k-radius-md);
    background: color-mix(in srgb, var(--k-accent) 14%, var(--k-surface));
    color: var(--k-accent);
    font-size: 22px;
    flex-shrink: 0;
}

.kl-actd-identity-text[b-nzjttsv2k8] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--k-space-1);
    min-inline-size: 0;
}

.kl-actd-kind[b-nzjttsv2k8] {
    align-self: flex-start;
}

.kl-actd-title[b-nzjttsv2k8] {
    font-family: var(--k-font-display);
    font-size: 24px;
    font-weight: 700;
    line-height: 1.2;
    margin: 0;
    color: var(--k-text);
    word-break: break-word;
}

.kl-actd-sub[b-nzjttsv2k8] {
    margin: 0;
    font-size: 14px;
    color: var(--k-text-muted);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-actd-actions[b-nzjttsv2k8] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    flex-shrink: 0;
}

/* OWNER ASK 2026-09-15: "most of the cards on this page have too much space between them."

   MEASURED BEFORE THE FIX, on the live page at 1400 / 1280 / 393: 48px between every consecutive
   `.kl-actd-card` (44px at 393). THREE spacers were stacking, and only one of them is the house rhythm:

     1. `.kl-page` is a flex COLUMN carrying `gap: var(--k-space-4)` (16px, tightened to 12px at <=640px by the
        2026-07-24 D11 ruling). That gap IS the product's inter-card rhythm — /records, /notifications and /dogs
        all measure 16px between consecutive blocks, with zero margins anywhere.
     2. the shared `[class$="-card"]` suffix family adds `margin-block-end: var(--k-space-4)`;
     3. this page ALSO wrote `margin-block-start: var(--k-space-4)` of its own.

   SO: 16 + 16 + 16 = 48. THE 48px WAS NOT THE FAMILY'S DOING. The family's trailing margin is the fallback
   rhythm for a container that supplies no gap, and it is correct everywhere it is the only spacer. What this
   page added was a THIRD spacer on top of a container that already had two, and margins do not collapse inside
   a flex container, so all three were paid in full.

   THE FIX IS THEREFORE STRUCTURAL, NOT AN OVERRIDE OF THE FAMILY'S INTENT: inside a gapped flex column a card
   owns no outer margin at all, and `.kl-page`'s own gap is the single spacer. That restores exactly the 16px /
   12px the rest of the product measures, at every width, with one rule and no `!important`. */
.kl-actd-card[b-nzjttsv2k8] {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-6);
    /* Longhands, not the `margin-block` shorthand: the family declares the LONGHAND `margin-block-end`, and a
       shorthand and a longhand for the same box side are two different property names to every guard that reads
       these sheets. Stating both longhands makes the resolved value unambiguous to a reader and to the cascade
       guard that pins this geometry. */
    margin-block-start: 0;
    margin-block-end: 0;
}

/* The glyph/words centre line, the 0.92em glyph and the 8px gutter are all the shared §5a rules now, and so is
   the head size: §5a is 18px since 2026-09-15 and the `font-size: 16px` that stood here was a copy of the old
   shared value, which is what kept nine routes off the shared ramp. */
.kl-actd-section-title[b-nzjttsv2k8] {
    font-family: var(--k-font-display);
    font-weight: 700;
    line-height: 1.3;
    margin: 0 0 var(--k-space-4);
    color: var(--k-text);
}

.kl-actd-facts[b-nzjttsv2k8] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: var(--k-space-4) var(--k-space-6);
    margin: 0;
}

.kl-actd-fact[b-nzjttsv2k8] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
    min-inline-size: 0;
}

.kl-actd-fact-label[b-nzjttsv2k8] {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

.kl-actd-fact-value[b-nzjttsv2k8] {
    font-size: 16px;
    font-weight: 600;
    color: var(--k-text);
    word-break: break-word;
}

/* The flag group leads the Performance card (owner ask 2026-09-14; the 2026-09-08 badge-grouping ruling).
   It sits directly under .kl-actd-section-title, whose own 16px bottom margin is the space ABOVE it, so the
   group owns only the space BELOW it, down to the facts grid. The margin moved from start to end when the
   group moved from the foot of the card to its head; leaving it on start would have doubled the gap under
   the title and butted the chips against the first fact label. */
.kl-actd-flags[b-nzjttsv2k8] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin-block-end: var(--k-space-4);
}

.kl-actd-notes[b-nzjttsv2k8] {
    margin: 0;
    font-size: 15px;
    line-height: 1.55;
    color: var(--k-text);
    white-space: pre-wrap;
    word-break: break-word;
}

.kl-actd-finds[b-nzjttsv2k8] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
}

/* OWNER ASK 2026-09-15 — the enriched find card. It was a hairline-separated pair of text lines, which is the
   right treatment for a two-line read-back and the wrong one for a block that now carries a captioned fact grid
   and can carry a second and third one under their own headings: a single 1px rule cannot say where one find's
   facts stop and the next find's begin once each find is six lines tall.

   The treatment is COPIED, not invented — the inset surface / border / radius this page's own
   `.kl-actd-evidence-link` already uses for a nested block inside a card. No new colour, no new elevation.

   `-find` is not one of the ~58 whole-attribute suffix families, so this class inherits nothing by accident. */
.kl-actd-find[b-nzjttsv2k8] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    padding: var(--k-space-4);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
}

/* Type + outcome chip on one line: the chip is a badge ON the type, not a row of its own. The column flex above
   stretches its children, so without this row the chip would run the full width of the card. */
.kl-actd-find-head[b-nzjttsv2k8] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-actd-find-type[b-nzjttsv2k8] {
    font-weight: 700;
    color: var(--k-text);
}

.kl-actd-find-desc[b-nzjttsv2k8] {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--k-text);
    word-break: break-word;
}

/* The TRAINING and PERSON-SEARCH blocks. They are a second and third vocabulary on the same card, so they are
   set off by a hairline and a caption rather than merged into the incident grid above them — a reader must be
   able to see that "Training amount" is not a seized quantity.

   NAMING: `-group` and `-group-name`, deliberately. `-grid`, `-label`, `-row`, `-facts` and `-value` are all
   live whole-attribute families; a class ending in one silently joins that family's treatment, which is the trap
   that has produced seventeen defects in this campaign. Neither word used here ends a family. */
.kl-actd-find-group[b-nzjttsv2k8] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    padding-block-start: var(--k-space-3);
    border-block-start: 1px solid var(--k-border);
}

.kl-actd-find-group-name[b-nzjttsv2k8] {
    margin: 0;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

/* The standing sentence naming the clock every instant on this page is read on (owner ruling 2026-09-15). It
   takes its 13px muted type from the shared `[class$="-note"]` family — a DELIBERATE membership, stated in the
   markup — so only its spacing is written here. */
.kl-actd-zone-note[b-nzjttsv2k8] {
    margin: var(--k-space-1) 0 0;
}

.kl-actd-state[b-nzjttsv2k8] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--k-space-3);
    text-align: center;
    padding: var(--k-space-12) var(--k-space-6);
    color: var(--k-text-muted);
}

/* The zero-finds pill — the owner's quiet dashed idiom (fdd42545): one line, never an "(0)" card frame. */
.kl-actd-finds-none[b-nzjttsv2k8] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    margin: 0;
    padding: var(--k-space-2) var(--k-space-4);
    border: 1px dashed var(--k-border);
    border-radius: var(--k-radius-full);
    color: var(--k-text-muted);
    font-size: 13px;
    background: var(--k-surface);
}

.kl-actd-finds-none .ki[b-nzjttsv2k8] {
    font-size: 15px;
    opacity: .6;
}

/* The evidence drill-in row (D.17): a full-width quiet link — name + optional count pill + trailing chevron;
   accent identity on hover (the related-record card idiom, 616a6752). */
.kl-actd-evidence-link[b-nzjttsv2k8] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    padding: var(--k-space-3) var(--k-space-4);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
    color: var(--k-text);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    transition: border-color var(--k-dur-1) var(--k-ease), color var(--k-dur-1) var(--k-ease),
                background-color var(--k-dur-1) var(--k-ease);
}

.kl-actd-evidence-link:hover[b-nzjttsv2k8] {
    color: var(--k-accent);
    border-color: color-mix(in srgb, var(--k-accent) 40%, var(--k-border));
    background: color-mix(in srgb, var(--k-accent) 6%, var(--k-surface));
}

.kl-actd-evidence-link .ki[b-nzjttsv2k8] {
    margin-inline-start: auto;
    font-size: 14px;
    color: var(--k-text-muted);
    transition: transform var(--k-dur-1) var(--k-ease), color var(--k-dur-1) var(--k-ease);
}

.kl-actd-evidence-link:hover .ki[b-nzjttsv2k8] {
    color: var(--k-accent);
    transform: translateX(2px);
}

.kl-actd-evidence-link .kl-count[b-nzjttsv2k8] {
    margin-inline-start: var(--k-space-1);
}

/* Dark + outdoor: keep visible card elevation (a flat card on a dark canvas reads
   as missing). The foundation already flips --k-surface/--k-border per mode. */
html.dark .kl-actd-header[b-nzjttsv2k8],
html.dark .kl-actd-card[b-nzjttsv2k8] {
    box-shadow: var(--k-elev-2);
    border-color: var(--k-border);
}

/* Narrow screens: stack the header actions under the identity (no horizontal overflow). */
@media (max-width: 40rem) {
    .kl-actd-header[b-nzjttsv2k8] {
        flex-direction: column;
    }

    .kl-actd-actions[b-nzjttsv2k8] {
        align-self: stretch;
    }
}

/* ── ACTIVITY HISTORY (owner ask 2026-09-14, "make activities auditable") ────────────────────────────────────
   The activity's own app.record_lifecycle_audit trail, mounted as the shared EntityHistoryPanel below the
   evidence card. Matches the block appended to RecordReview.razor.css for the record's trail.

   WHY THIS BLOCK EXISTS AT ALL. A new section with four bare classes is conformance by ABSENCE — the shape
   `unstyled-class-scan.mjs` was written to find. An unstyled <section> is a plain block, so it passes the wrap
   and overflow sweeps by having no rule to violate, and it renders as unframed text hanging off the bottom of a
   page whose every other block is a card.

   The treatment is COPIED, not invented: the same surface / border / radius / elevation / padding as this page's
   own `.kl-actd-card`, and the same title face as `.kl-actd-section-title`. Those are restated rather than shared
   by a selector list, because the head rule and the lede have no counterpart in the card idiom.

   NAMING. `-head` and not `-header`, `-lede` and not `-note`: `[class$="-header"]` and `[class$="-note"]` are
   live unscoped foundation families keyed on where the whole class ATTRIBUTE ends, and a class that ends in a
   family word silently joins that family's padding, surface and border. Fifteen defects in this campaign came
   from that trap, and the house fix is always to rename off the family word — never `!important`. */
.kl-actd-history[b-nzjttsv2k8] {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-6);
    /* The same rhythm correction as `.kl-actd-card` above, for the same reason. This class does NOT end in a
       family word, so it never carried the family's trailing margin — it stood at 32px where the cards stood at
       48px, which is why the owner said "MOST of the cards" and not "all". `.kl-page`'s gap is the one spacer. */
    margin-block-start: 0;
    margin-block-end: 0;
}

.kl-actd-history-head[b-nzjttsv2k8] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--k-space-3);
    margin-block-end: var(--k-space-4);
    padding-block-end: var(--k-space-3);
    border-block-end: 1px solid var(--k-border);
}

.kl-actd-history-title[b-nzjttsv2k8] {
    display: flex;
    align-items: center;
    font-family: var(--k-font-display);
    font-size: 16px;
    font-weight: 700;
    line-height: 1.3;
    margin: 0;
    color: var(--k-text);
}

/* The standing sentence about WHAT this ledger records and that it is append-only. It sits above the table
   rather than under it: a reader who finds one row needs to know the trail is complete before they read it. */
.kl-actd-history-lede[b-nzjttsv2k8] {
    margin: 0 0 var(--k-space-4);
    color: var(--k-text-muted, #5b6169);
    font-size: 14px;
    line-height: 1.55;
}

/* Dark: the same elevation the other cards keep, so the section does not read as missing on the dark canvas. */
html.dark .kl-actd-history[b-nzjttsv2k8] {
    box-shadow: var(--k-elev-2);
    border-color: var(--k-border);
}
/* _content/Kanine.Web/Components/Pages/ActivityEvidence.razor.rz.scp.css */
/* =============================================================================
   ActivityEvidence (activity-evidence.html) — R11 restrained-premium scoped refinement.
   -----------------------------------------------------------------------------
   Consumes the foundation vocabulary (kl-page, kl-btn, kl-chip, k-mono, the
   kl-visually-hidden utility) and adds ONLY the evidence-surface layout this read
   screen needs: the surface card, the action bar, the file-list rows, the per-item
   actions, the verification band, and the reason-capture delete dialog. Tokens only
   (--k-*); no off-token colour and no generic gradient (those red the central R11
   teeth). The body canvas + chips + buttons already flip per mode from the
   foundation; this file just sets borders/elevation that stay legible in dark + outdoor.

   2026-09-14 — THE SURFACE STOPPED BEING A MODAL (owner complaint). The whole route used to
   render inside a KlOverlay scrim, so this file dressed a dialog: a navy header band with a
   close X, a footer holding a Cancel, and a dismissed-state placeholder. All of that is gone.
   `.kl-ev-modal` is renamed `.kl-ev-surface`, because a class called -modal on a page is a lie
   the next reader has to disprove. The crumb + page-head vocabulary below is copied from the
   sibling EvidenceVault.razor.css so the two evidence surfaces read as one product (Blazor
   scoped CSS cannot reach across components, so a copy is the only way to share the shape).
   `-surface` was cleared against the 58 foundation attribute-suffix families first: there is no
   [class$="-surface"] family, so the rename cannot make this section an accidental member of one.
   ========================================================================== */

/* Drill-back crumb: Activity › Activity evidence. The evidence-vault sibling's vocabulary. */
.kl-ev-crumbs[b-ct07w65hto] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-1);
    margin-bottom: var(--k-space-3);
    font-size: 13px;
}

.kl-ev-crumb[b-ct07w65hto] {
    color: var(--k-accent);
    text-decoration: none;
}

.kl-ev-crumb:hover[b-ct07w65hto] {
    text-decoration: underline;
}

.kl-ev-crumb-sep[b-ct07w65hto] {
    color: var(--k-outline);
    font-size: 14px;
}

.kl-ev-crumb-current[b-ct07w65hto] {
    color: var(--k-text-muted);
}

/* The ONE page title (the dialog used to carry a second one of its own). */
.kl-ev-pagehead[b-ct07w65hto] {
    margin-bottom: var(--k-space-6);
}

.kl-ev-pagetitle[b-ct07w65hto] {
    margin: 0 0 var(--k-space-1);
    font-family: var(--k-font-display);
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--k-text);
}

.kl-ev-pagesub[b-ct07w65hto] {
    margin: 0;
    max-width: 60ch;
    color: var(--k-text-muted);
    line-height: 1.5;
}

/* The evidence SURFACE: a page card, not a dialog. Page elevation (elev-1, the level the vault canvas card
   uses), never the elev-3 a floating modal panel carried. */
.kl-ev-surface[b-ct07w65hto] {
    display: flex;
    flex-direction: column;
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    overflow: hidden;
}

/* Body. */
.kl-ev-body[b-ct07w65hto] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-6);
    padding: var(--k-space-6);
}

.kl-ev-actionbar[b-ct07w65hto] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-4);
    flex-wrap: wrap;
}

.kl-ev-count-wrap[b-ct07w65hto] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
}

/* No `font-size` here: §5a sets the shared head size (18px since 2026-09-15) and a page copy of the old 16px
   is what kept nine routes off the shared ramp. */
.kl-ev-section-title[b-ct07w65hto] {
    font-family: var(--k-font-display);
    font-weight: 700;
    margin: 0;
    color: var(--k-text);
}

/* "Add new" is a real file-picker LABEL now — position it so the invisible <InputFile> fills the button (the
   FilesManager idiom); the label class keeps the primary button chrome via the foundation element-gated family. */
.kl-ev-add[b-ct07w65hto] {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-1);
    cursor: pointer;
}

.kl-ev-add .ki[b-ct07w65hto] {
    font-size: 20px;
}

/* (V35) On a completed record Add stays on screen but takes no file: the disabled look of the foundation buttons. */
.kl-ev-add[aria-disabled="true"][b-ct07w65hto] {
    opacity: .55;
    cursor: not-allowed;
}

/* (The invisible <InputFile> overlay uses the GLOBAL .kl-involve-file-input foundation class — a scoped rule cannot
   reach a child component's rendered input.) */

/* An unreadable/over-cap pick surfaces honestly (never a fake green) — the -error suffix rides the foundation
   critical banner family (incl. its dark remap). */
.kl-ev-upload-error[b-ct07w65hto] {
    margin: 0;
}

/* D79.15 — the note above the list on a completed record (Delete is disabled). */
.kl-ev-locked[b-ct07w65hto] {
    margin: 0 0 var(--k-space-2);
    font-size: 13px;
    color: var(--k-text-muted);
}

/* The evidence file list. */
.kl-ev-list[b-ct07w65hto] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
}

.kl-ev-item[b-ct07w65hto] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-4);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-4);
    transition: border-color var(--k-dur-1) ease;
}

.kl-ev-item:hover[b-ct07w65hto] {
    border-color: var(--k-accent);
}

.kl-ev-item-main[b-ct07w65hto] {
    display: flex;
    align-items: center;
    gap: var(--k-space-3);
    min-inline-size: 0;
}

.kl-ev-item-icon[b-ct07w65hto] {
    flex-shrink: 0;
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border-radius: var(--k-radius-sm);
    inline-size: 44px;
    block-size: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.kl-ev-item-meta[b-ct07w65hto] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
    min-inline-size: 0;
}

.kl-ev-item-name[b-ct07w65hto] {
    font-size: 15px;
    font-weight: 600;
    color: var(--k-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kl-ev-item-facts[b-ct07w65hto] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    flex-wrap: wrap;
    font-size: 12px;
    color: var(--k-text-muted);
}

.kl-ev-item-size[b-ct07w65hto] {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.kl-ev-fact-icon[b-ct07w65hto] {
    font-size: 14px;
}

.kl-ev-dot[b-ct07w65hto] {
    opacity: .5;
}

.kl-ev-item-hash[b-ct07w65hto] {
    font-size: 11px;
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border-radius: var(--k-radius-sm);
    padding: 1px var(--k-space-2);
    max-inline-size: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kl-ev-pending[b-ct07w65hto] {
    /* small caution chip when the bytes are still pending a deferred upload */
    font-size: 11px;
}

.kl-ev-item-actions[b-ct07w65hto] {
    display: flex;
    align-items: center;
    gap: var(--k-space-1);
    flex-shrink: 0;
}

.kl-ev-item-btn[b-ct07w65hto] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: var(--k-touch);
    block-size: var(--k-touch);
    border: 0;
    border-radius: var(--k-radius-md);
    background: transparent;
    color: var(--k-text-muted);
    cursor: pointer;
    transition: background var(--k-dur-1) ease, color var(--k-dur-1) ease;
}

.kl-ev-item-btn:hover:not(:disabled)[b-ct07w65hto] {
    background: var(--k-surface-2);
    color: var(--k-text);
}

.kl-ev-item-danger:hover:not(:disabled)[b-ct07w65hto] {
    color: var(--k-critical);
    background: color-mix(in srgb, var(--k-critical) 10%, transparent);
}

.kl-ev-item-btn:disabled[b-ct07w65hto] {
    opacity: .45;
    cursor: not-allowed;
}

/* ── Files attached to the FINDS in this activity (owner ask 2026-09-14) ───────────────────────────
   A visually SEPARATE block, because these files have a different owner from the list above. It is set
   off by a rule and a top gap rather than by a second card, so the reader still sees one page about one
   activity instead of two competing panels.

   CLASS-SUFFIX FAMILIES (kanine-design-system.css keys ~58 families on the class ATTRIBUTE ENDING).
   Every new name below ends in a word that is NOT a family word: -finds, -lede, -group, -origin, -icon,
   -kind, -desc, -files. The one place a family IS wanted is the file list, and it opts in by ALSO
   carrying the existing .kl-ev-list, so the rows look identical to the activity's own rows. */
.kl-ev-finds[b-ct07w65hto] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    padding-block-start: var(--k-space-6);
    border-block-start: 1px solid var(--k-border);
}

/* Says WHY these files are here and that they are not the activity's own. It is body copy, not a note
   family: the reader must read it once, then never again. */
.kl-ev-finds-lede[b-ct07w65hto] {
    margin: 0;
    max-inline-size: 78ch;
    font-size: 13px;
    line-height: 1.55;
    color: var(--k-text-muted);
}

.kl-ev-find-group[b-ct07w65hto] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
}

/* The attribution line: WHICH find these files came from. Wraps rather than truncates — with several
   finds of the same type the description is the only thing telling them apart.
   DELIBERATELY NOT A FLEX ROW. A flex gap is visual only: it puts no character between the spans, so the
   heading's own accessible name came out as "CocaineVacuum-sealed brick…" while looking correctly spaced.
   As a normal inline run the markup's whitespace IS the spacing, so what is read and what is seen agree. */
.kl-ev-find-origin[b-ct07w65hto] {
    margin: 0;
    font-size: 13px;
    font-weight: 400;
    line-height: 1.45;
}

.kl-ev-find-icon[b-ct07w65hto] {
    font-size: 18px;
    color: var(--k-accent);
    vertical-align: -3px;
    margin-inline-end: 2px;
}

.kl-ev-find-kind[b-ct07w65hto] {
    font-weight: 700;
    color: var(--k-text);
}

.kl-ev-find-dash[b-ct07w65hto] {
    color: var(--k-text-muted);
}

.kl-ev-find-desc[b-ct07w65hto] {
    min-inline-size: 0;
    color: var(--k-text-muted);
}

/* Inset the group's files under their attribution line, so the grouping is legible without a box. */
.kl-ev-find-files[b-ct07w65hto] {
    padding-inline-start: var(--k-space-3);
    border-inline-start: 2px solid color-mix(in srgb, var(--k-accent) 32%, var(--k-border));
}

/* Verification band — a quiet accented info card (prototype parity). */
.kl-ev-verify[b-ct07w65hto] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-3);
    background: color-mix(in srgb, var(--k-accent) 6%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-accent) 28%, var(--k-border));
    border-radius: var(--k-radius-md);
    padding: var(--k-space-4);
}

.kl-ev-verify-icon[b-ct07w65hto] {
    color: var(--k-accent);
    flex-shrink: 0;
}

.kl-ev-verify-title[b-ct07w65hto] {
    font-size: 13px;
    font-weight: 700;
    margin: 0 0 2px;
    color: var(--k-text);
}

.kl-ev-verify-body[b-ct07w65hto] {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--k-text-muted);
}

/* The reason-capture delete dialog (opened by a row's Delete; absent until then). */
.kl-ev-delete-dialog[b-ct07w65hto] {
    margin-block-start: var(--k-space-6);
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    background: var(--k-surface);
    border: 1px solid color-mix(in srgb, var(--k-critical) 30%, var(--k-border));
    border-inline-start: 4px solid var(--k-critical);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-2);
    padding: var(--k-space-6);
}

.kl-ev-delete-title[b-ct07w65hto] {
    font-family: var(--k-font-display);
    font-size: 18px;
    font-weight: 700;
    margin: 0;
    color: var(--k-text);
}

.kl-ev-delete-body[b-ct07w65hto] {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--k-text-muted);
}

.kl-ev-delete-reason[b-ct07w65hto] {
    inline-size: 100%;
    resize: vertical;
}

.kl-ev-delete-actions[b-ct07w65hto] {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--k-space-3);
}

/* Empty state (centered, present-not-abandoned). The dismissed state went with the modal. */
.kl-ev-empty[b-ct07w65hto] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--k-space-3);
    text-align: center;
    padding: var(--k-space-12) var(--k-space-6);
    color: var(--k-text-muted);
}

.kl-ev-state-icon[b-ct07w65hto] {
    font-size: 32px;
    opacity: .55;
    margin: 0;
}

.kl-ev-empty-msg[b-ct07w65hto] {
    margin: 0;
    font-size: 15px;
}

/* Dark + outdoor: keep visible card elevation/borders (a flat card on a dark canvas
   reads as missing). The foundation already flips --k-surface/--k-border. */
html.dark .kl-ev-surface[b-ct07w65hto] {
    box-shadow: var(--k-elev-3);
    border-color: var(--k-border);
}

html.dark .kl-ev-find-files[b-ct07w65hto] {
    border-inline-start-color: color-mix(in srgb, var(--k-accent) 48%, var(--k-border));
}

html.dark .kl-ev-verify[b-ct07w65hto] {
    background: color-mix(in srgb, var(--k-accent) 14%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-accent) 44%, var(--k-border));
}

html.dark .kl-ev-delete-dialog[b-ct07w65hto] {
    box-shadow: var(--k-elev-2);
}

/* Narrow screens: stack each item's actions under its meta. */
@media (max-width: 40rem) {
    .kl-ev-item[b-ct07w65hto] {
        flex-direction: column;
        align-items: stretch;
    }

    .kl-ev-item-actions[b-ct07w65hto] {
        justify-content: flex-end;
        border-block-start: 1px solid var(--k-border);
        padding-block-start: var(--k-space-3);
    }

    /* The find rail costs horizontal room a phone does not have; the attribution heading already groups. */
    .kl-ev-find-files[b-ct07w65hto] {
        padding-inline-start: 0;
        border-inline-start: 0;
    }
}
/* _content/Kanine.Web/Components/Pages/ActivityFindsEntry.razor.rz.scp.css */
/* =============================================================================
   activity-finds-entry (/records/{id}/activity) — R11 page-scoped refinement.
   -----------------------------------------------------------------------------
   The foundation (kanine-design-system.css §5/§8) already supplies the cards
   (suffix -card / -card-title), the form kit (kf-field / kf-label / kf-select /
   kf-input / kf-textarea / kf-checkbox, incl. per-mode color-scheme on the native
   date/time widgets), the kl-btn primary/secondary/ghost system at the 48px touch
   target, the page measure (kl-page--wide), the section head, the failure banner
   (kl-failure), and the top-layer dialog (kl-dialog). This file adds ONLY the
   page-specific composition the prototype calls for: the responsive card grid
   (narrative is the wide lead card), the in-subset card-title glyph, the
   two-up field rows, the performance-metrics check column, the DATA-017
   find-field groups, the finds card head + composed empty state + find rows,
   and the footer action bar holding the SINGLE teal primary. Every value
   is an on-brand --k-* token (mode-adaptive: flips with light / dark / outdoor) —
   NO gradient, NO off-token colour, no body-bg change → the R11 token/canvas gate
   holds. Nothing here touches a tested data-anchor / data-testid; presentation
   only. Scoped-component CSS (Blazor adds [b-*]); selectors are also qualified to
   the page root (.kl-afe) for belt-and-braces specificity over the shared rules.
   ========================================================================== */

/* ---- Lede under the page title — a calm one-line orienting caption ---------- */
.kl-afe .kl-afe-lede[b-4kd2c0vdzb] {
    flex-basis: 100%;
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--k-text-muted);
}

/* ---- Card grid — the prototype's 12-col composition, responsive ------------
   Narrative leads as the wide card; Times & Performance + Environmental sit
   beside it on wide viewports; Finds & evidence spans the full row. Collapses to
   a single column under the grid min so nothing crushes on a phone. */
.kl-afe .kl-afe-grid[b-4kd2c0vdzb] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--k-space-4);
    align-items: start;
}

/* Narrative leads as a wide card spanning both rows. align-self:stretch overrides
   the grid's align-items:start so the card FILLS its 2-row height (else it sizes to
   its short content and the col-1 row-2 track paints as bare canvas beside the
   Environmental card — the R11 "awkward empty gap" finding); display:flex lets the
   inner .kf-field--grow / .kl-afe-narrative textarea flex up to fill that height. */
.kl-afe .kl-afe-card--narrative[b-4kd2c0vdzb] {
    grid-row: span 2;
    align-self: stretch;
    display: flex;
    flex-direction: column;
}
.kl-afe .kl-afe-card--finds[b-4kd2c0vdzb] { grid-column: 1 / -1; }

/* The grid cards carry a --modifier (--narrative / --env / --finds), so the WHOLE
   class attribute no longer ends in "-card" and the foundation
   .kl-shell-main [class$="-card"] chrome rule MISSES them (the documented multi-class
   suffix gap — kanine-design-system.css §5a / line ~963). Only the single-class
   Times & Performance card matched, so Environmental floated bare on the page bg (the
   R11 "no card chrome / inconsistent with the card above" finding). Apply the
   surface/border/radius/elevation/padding EXPLICITLY via the .kl-afe-card CLASS (which
   matches every card regardless of its modifier) so narrative / env / finds all read as
   proper cards. Mirrors the foundation -card tokens; trailing margin zeroed so the grid
   gap owns the rhythm. */
.kl-afe .kl-afe-card[b-4kd2c0vdzb] {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-6);
    margin-block-end: 0;
}

@media (max-width: 760px) {
    .kl-afe .kl-afe-grid[b-4kd2c0vdzb] { grid-template-columns: minmax(0, 1fr); }
    .kl-afe .kl-afe-card--narrative[b-4kd2c0vdzb] { grid-row: auto; }
}

/* ---- Card title glyph — a quiet teal foreground accent (in-subset icon) -----
   Only the COLOUR is this page's. The centre line, the 0.92em size and the 8px gutter are the shared §5a
   rules now. The `gap` that used to sit on `.kl-afe-card-title` would COMPOSE with §5a's glyph margin and
   open all four heads to 16px, and the `font-size: 20px` made the glyph larger than its own heading. */
.kl-afe .kl-afe-card-icon[b-4kd2c0vdzb] {
    color: var(--k-accent);
}

/* The finds card leads with a title + trailing actions on one row. */
.kl-afe .kl-afe-card-head[b-4kd2c0vdzb] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
    margin-block-end: var(--k-space-4);
}

.kl-afe .kl-afe-card-head .kl-afe-card-title[b-4kd2c0vdzb] { margin: 0; }

.kl-afe .kl-afe-card-head-actions[b-4kd2c0vdzb] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
}

/* ---- Two-up field rows (base/activity type, start/end time) ----------------- */
.kl-afe .kl-afe-row2[b-4kd2c0vdzb] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--k-space-4);
}

@media (max-width: 460px) {
    .kl-afe .kl-afe-row2[b-4kd2c0vdzb] { grid-template-columns: minmax(0, 1fr); }
}

/* The narrative card stretches its textarea to fill the tall (row-span-2) card. */
.kl-afe .kf-field--grow[b-4kd2c0vdzb] {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}

.kl-afe .kl-afe-narrative[b-4kd2c0vdzb] {
    min-block-size: 12rem;
    flex: 1 1 auto;
}

/* ---- End Time + its one-tap "Now" stamp, on ONE line -----------------------
   Owner ruling 2026-08-10: End Time opens empty with a one-tap stamp beside it.
   Same idiom as the shipped Daily Log create dialog (dl-start-now / dl-end-now)
   rather than a second shape for the same job.

   ⚠️ NOT named "…-row". The foundation's §5l suffix family
   :where([class^="kl-"])[class$="-row"] turns ANY class ending in -row into a
   bordered, tinted, 12px/16px-padded LIST ROW pill. Measured with that name: a
   17px inline inset on both children, a 1px border round the pair, and the cell
   grew from 69px to 151px. The class-suffix-family trap, live.

   flex-basis 0 on the input, deliberately: flexbox picks line breaks by summing
   BASES before any floor is consulted, so a content-sized basis pushed the button
   onto a second line inside the 225px desk cell (measured) while leaving 34px of
   slack unused. With basis 0 the pair never breaks by itself and the input takes
   every remaining pixel. flex-wrap stays as the honest last resort. Both keep
   their 48px block size — nothing here trades away A6. */
.kl-afe .kl-afe-endstamp[b-4kd2c0vdzb] {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: var(--k-space-2);
}

.kl-afe .kl-afe-endstamp > .kf-input[b-4kd2c0vdzb] {
    flex: 1 1 0;
    min-inline-size: 0;
}

.kl-afe .kl-afe-endstamp > .kl-btn[b-4kd2c0vdzb] {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* The window row carries a control the taxonomy row does not, so it splits its
   track a little in End's favour — a measured delta, not a guess: the native
   datetime-local's max-content is 228px and an even split gives each end 225px,
   which leaves the stamp nothing to sit in. Start keeps 191px (it holds no inline
   action).

   Gated ABOVE the 460px collapse on purpose. The modifier and the collapse rule
   are both (0,2,0), so an ungated version wins on sheet order and re-imposes TWO
   columns on a phone — measured: the 393px cells went 311 → 125 / 170 and the
   date controls were unusable. Guarding by width is the fix; raising specificity
   would only have hidden the conflict. */
@media (min-width: 461px) {
    .kl-afe .kl-afe-row2--window[b-4kd2c0vdzb] {
        grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    }
}

/* ---- Inline validation (End before Start) ----------------------------------
   The house treatment for a field-attached problem (.kl-cc-problem on
   CertificationCreate): critical colour, no card, no icon — one sentence
   attached to the control it is about. NOT named "…-error": that suffix family
   (§5f) paints a full tinted banner with a border, which is chrome this cell
   cannot spare. */
.kl-afe .kl-afe-problem[b-4kd2c0vdzb] {
    margin: var(--k-space-1) 0 0;
    font-size: 13px;
    line-height: 1.35;
    color: var(--k-critical);
}

/* ---- A disabled control's stated precondition ------------------------------
   Owner ruling 2026-08-10. The button and its reason are ONE unit pinned to the
   card head's trailing edge, so the note reads as belonging to the control and
   not as a stray caption. Text-align follows the flex alignment for the same
   reason. Muted, hint-sized: it is an explanation, not an alarm. */
.kl-afe .kl-afe-find-gate[b-4kd2c0vdzb] {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--k-space-1);
}

.kl-afe .kl-afe-gate-reason[b-4kd2c0vdzb] {
    margin: 0;
    max-inline-size: 32ch;
    font-size: 13px;
    line-height: 1.4;
    text-align: end;
    color: var(--k-text-muted);
}

/* At phone width the card head wraps to a column and the gate is no longer pinned
   to a trailing edge, so end-alignment would read as ragged. flex-start, NOT
   stretch: stretch made the BUTTON as wide as its own note (measured 119 → 219px
   at 393px as the reason text lengthened), so the control changed size every time
   the message did. The note stretches instead — it is the thing that should wrap. */
@media (max-width: 640px) {
    .kl-afe .kl-afe-find-gate[b-4kd2c0vdzb] { align-items: flex-start; }
    .kl-afe .kl-afe-gate-reason[b-4kd2c0vdzb] {
        align-self: stretch;
        max-inline-size: none;
        text-align: start;
    }
}

/* ---- Muted captions under fields (hint text) ------------------------------- */
.kl-afe .kl-afe-hint[b-4kd2c0vdzb] {
    margin: var(--k-space-1) 0 0;
    font-size: 13px;
    line-height: 1.4;
    color: var(--k-text-muted);
}

/* ---- Read-only lock: a sealed record locks the whole form (item 5) ------------
   The fieldset only carries `disabled` to every control inside it, so it draws nothing of its own. */
.kl-afe .kl-afe-lock[b-4kd2c0vdzb] {
    border: 0;
    margin: 0;
    padding: 0;
    min-inline-size: 0;
}

.kl-afe .kl-afe-sealed-note[b-4kd2c0vdzb] {
    margin: 0 0 var(--k-space-3);
}

/* ---- DATA-017 conditional find-field groups ---------------------------------
   Mirrors the build surface's .kl-rb-find-group treatment: a quiet token-bordered
   card replacing the UA-default 2px groove fieldset chrome. */
.kl-afe .kl-rb-find-group[b-4kd2c0vdzb] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-4);
    margin: 0;
    min-inline-size: 0;
}

.kl-afe .kl-rb-find-group > legend[b-4kd2c0vdzb] { padding-inline: 0; }

/* ---- Performance-metrics check column -------------------------------------- */
.kl-afe .kf-afe-perf-metrics[b-4kd2c0vdzb] {
    border: 0;
    margin: 0;
    padding: 0;
}

.kl-afe .kf-afe-perf-metrics .kf-label[b-4kd2c0vdzb] {
    display: block;
    margin-block-end: var(--k-space-2);
}

.kl-afe .kf-afe-check[b-4kd2c0vdzb] {
    display: flex;
    align-items: center;
    gap: var(--k-space-3);
    padding: var(--k-space-2) var(--k-space-2);
    border-radius: var(--k-radius-sm);
    font-size: 15px;
    color: var(--k-text);
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease);
}

.kl-afe .kf-afe-check:hover[b-4kd2c0vdzb] {
    background: var(--k-surface-2);
}

/* The native brand-accented checkbox keeps its real tick (kf-checkbox handles
   the accent-color + size); just guarantee it does not shrink in the flex row. */
.kl-afe .kf-afe-check .kf-checkbox[b-4kd2c0vdzb] {
    flex: 0 0 auto;
}

/* ---- Composed empty state --------------------------------------------------- */
/* The empty state is a composed, titled card — never an emoji on a void. A
   calm token-tinted tile + a clear title + a muted note. */
.kl-afe .kl-afe-empty[b-4kd2c0vdzb] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--k-space-1);
    padding: var(--k-space-8) var(--k-space-4);
    text-align: center;
    border: 1px dashed var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
}

.kl-afe .kl-afe-empty-icon[b-4kd2c0vdzb] {
    font-size: 32px;
    color: var(--k-accent);
    opacity: .85;
}

.kl-afe .kl-afe-empty-title[b-4kd2c0vdzb] {
    margin: var(--k-space-1) 0 0;
    font-family: var(--k-font-display);
    font-size: 15px;
    font-weight: 700;
    color: var(--k-text);
}

.kl-afe .kl-afe-empty-note[b-4kd2c0vdzb] {
    margin: 0;
    max-inline-size: 40ch;
    font-size: 13px;
    line-height: 1.5;
    color: var(--k-text-muted);
}

/* ---- REC-020 finds sub-section (mirrors the record-build add-find / find-list) */
.kl-afe .kl-afe-finds-block[b-4kd2c0vdzb] {
    margin-block-start: var(--k-space-6);
    padding-block-start: var(--k-space-4);
    border-block-start: 1px solid var(--k-border);
}

/* The add-find form — a token-tinted inset panel grouping the type combobox,
   description, and its actions (mirrors the record-build .kl-rb-add-find). */
.kl-afe .kl-afe-add-find[b-4kd2c0vdzb] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    margin-block-end: var(--k-space-4);
    padding: var(--k-space-4);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
}

.kl-afe .kl-afe-add-find-actions[b-4kd2c0vdzb] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
}

.kl-afe .kl-afe-find-list[b-4kd2c0vdzb] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}

.kl-afe .kl-afe-find[b-4kd2c0vdzb] {
    display: flex;
    align-items: center;
    gap: var(--k-space-3);
    padding: var(--k-space-3) var(--k-space-4);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
    font-size: 14px;
    color: var(--k-text);
}

.kl-afe .kl-afe-find-glyph[b-4kd2c0vdzb] {
    flex: 0 0 auto;
    font-size: 20px;
    color: var(--k-accent);
}

.kl-afe .kl-afe-find-type[b-4kd2c0vdzb] {
    font-weight: 700;
    color: var(--k-text);
}

.kl-afe .kl-afe-find-desc[b-4kd2c0vdzb] {
    flex: 1 1 auto;
    min-inline-size: 0;
    color: var(--k-text-muted);
}

.kl-afe .kl-afe-find-remove[b-4kd2c0vdzb] {
    flex: 0 0 auto;
    margin-inline-start: auto;
}

/* ---- Failure banner — icon-led, the foundation kl-failure supplies the skin -- */
.kl-afe .kl-afe-failure[b-4kd2c0vdzb] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-afe .kl-afe-failure-icon[b-4kd2c0vdzb] {
    flex: 0 0 auto;
    font-size: 20px;
    color: var(--k-critical);
}

/* ---- Footer action bar — ONE teal primary; tonal secondary; saved status ---- */
.kl-afe .kl-afe-actionbar[b-4kd2c0vdzb] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--k-space-3);
    margin-block-start: var(--k-space-2);
    padding-block-start: var(--k-space-4);
    border-block-start: 1px solid var(--k-border);
}

.kl-afe .kl-afe-actionbar-buttons[b-4kd2c0vdzb] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-3);
    margin-inline-start: auto;
}

/* The saved-progress confirmation reads as a quiet success status (not chrome). */
.kl-afe .kl-afe-saved[b-4kd2c0vdzb] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-1);
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: color-mix(in srgb, var(--k-success) 70%, var(--k-text));
}

.kl-afe .kl-afe-saved-icon[b-4kd2c0vdzb] { font-size: 18px; }

/* The Confirm primary carries a leading glyph; keep the icon/label aligned. */
.kl-afe .kf-btn-confirm-activity .ki[b-4kd2c0vdzb] {
    font-size: 18px;
}

/* =============================================================================
   Dark + dark-outdoor remaps — load-bearing legibility. The empty-state dashed
   border + evidence row borders can wash out on the dark surface; push them a
   touch harder so the composition keeps its edges (mirrors the foundation §5/§8
   pattern: a slightly stronger border on dark). No colour change beyond border
   contrast — the token canvas is unchanged.
   ========================================================================== */
html.dark .kl-afe .kl-afe-empty[b-4kd2c0vdzb] {
    border-color: color-mix(in srgb, var(--k-border) 78%, var(--k-text));
}

html.dark .kl-afe .kl-afe-find[b-4kd2c0vdzb],
html.dark .kl-afe .kl-afe-add-find[b-4kd2c0vdzb] {
    border-color: color-mix(in srgb, var(--k-border) 78%, var(--k-text));
}

html.dark .kl-afe .kl-afe-saved[b-4kd2c0vdzb] {
    color: color-mix(in srgb, var(--k-success) 55%, var(--k-text));
}

/* Dark-outdoor (html.dark[data-outdoor="true"]) — sunlight-legibility variant:
   firm the section dividers + empty-state edge a step further. */
html.dark[data-outdoor="true"] .kl-afe .kl-afe-actionbar[b-4kd2c0vdzb],
html.dark[data-outdoor="true"] .kl-afe .kl-afe-finds-block[b-4kd2c0vdzb] {
    border-block-start-color: color-mix(in srgb, var(--k-border) 70%, var(--k-text));
}

html.dark[data-outdoor="true"] .kl-afe .kl-afe-empty[b-4kd2c0vdzb] {
    border-color: color-mix(in srgb, var(--k-border) 65%, var(--k-text));
}
/* _content/Kanine.Web/Components/Pages/AdminOverview.razor.rz.scp.css */
/* =============================================================================
   AdminOverview — R11 page-scoped refinement (UI-GUAR-011, restrained-premium)
   -----------------------------------------------------------------------------
   The agency/admin LANDING (admin-overview.html): a bento launchpad of deep-link
   tiles into the built admin/operational subsystems. Consumes the foundation
   vocabulary (kl-page, kl-section-head, kl-chip, kl-btn, k-mono); adds ONLY the
   bento surfaces those do not cover. Every surface rides the flipping --k-*
   channels so light/dark/outdoor hold with no off-token colour or gradient.
   ========================================================================== */

.kl-admin-subtitle[b-sngje8zdy4] {
    margin: 0;
    color: var(--k-text-muted);
    font-size: 15px;
}

/* ---- Bento grid ----------------------------------------------------------- */
.kl-admin-bento[b-sngje8zdy4] {
    display: grid;
    grid-template-columns: repeat(1, minmax(0, 1fr));
    gap: var(--k-space-4);
    margin-block-start: var(--k-space-4);
    grid-auto-rows: min-content;
}
@media (min-width: 48rem) {
    .kl-admin-bento[b-sngje8zdy4] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 64rem) {
    .kl-admin-bento[b-sngje8zdy4] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ---- Tile shell ----------------------------------------------------------- */
.kl-admin-tile[b-sngje8zdy4] {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-4);
    min-block-size: 7.5rem;
}
.kl-admin-tile--2[b-sngje8zdy4] { grid-column: span 1; }
@media (min-width: 48rem) {
    .kl-admin-tile--2[b-sngje8zdy4] { grid-column: span 2; }
    .kl-admin-tile--full[b-sngje8zdy4] { grid-column: 1 / -1; }
}
@media (min-width: 64rem) {
    .kl-admin-tile--full[b-sngje8zdy4] { grid-column: 1 / -1; }
}
.kl-admin-tile--caution[b-sngje8zdy4] { border-inline-start: 3px solid var(--k-caution); }

.kl-admin-tile-head[b-sngje8zdy4] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-2);
    margin-block-end: var(--k-space-2);
}
.kl-admin-tile-title[b-sngje8zdy4] {
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    color: var(--k-text);
}
.kl-admin-tile-title--muted[b-sngje8zdy4] { color: var(--k-text-muted); font-weight: 600; }
.kl-admin-tile-sub[b-sngje8zdy4] { margin: 0; color: var(--k-text-muted); font-size: 12px; }
.kl-admin-tile-sub--defer[b-sngje8zdy4] { opacity: .75; }

/* ---- Stat numbers --------------------------------------------------------- */
.kl-admin-stat[b-sngje8zdy4] {
    margin: 0;
    font-size: 34px;
    font-weight: 800;
    line-height: 1.05;
    color: var(--k-text);
}
.kl-admin-stat--sm[b-sngje8zdy4] { font-size: 26px; }
.kl-admin-stat--muted[b-sngje8zdy4] { color: var(--k-text-muted); }
.kl-admin-stat-unit[b-sngje8zdy4] { font-size: 16px; font-weight: 600; color: var(--k-text-muted); margin-inline-start: 2px; }

/* ---- Installed-pack chip row (PLAT-002 tile) ------------------------------ */
/* The chips themselves are the foundation .kl-chip; this adds only the wrapping row, which the
   foundation does not cover. A long pack label wraps instead of widening the bento cell. */
.kl-admin-packs[b-sngje8zdy4] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-1);
    margin: 0;
    margin-block-end: var(--k-space-2);
}

/* ---- Seats meter ---------------------------------------------------------- */
.kl-admin-seats[b-sngje8zdy4] { display: flex; flex-direction: column; gap: var(--k-space-2); }
.kl-admin-seats-row[b-sngje8zdy4] { display: flex; justify-content: space-between; color: var(--k-text-muted); font-size: 14px; }
.kl-admin-meter[b-sngje8zdy4] {
    inline-size: 100%;
    block-size: .5rem;
    background: var(--k-bg);
    border: 1px solid var(--k-border);
    border-radius: 999px;
    overflow: hidden;
}
.kl-admin-meter-fill[b-sngje8zdy4] { display: block; block-size: 100%; background: var(--k-accent); border-radius: 999px; }
.kl-admin-seats-pending[b-sngje8zdy4] { margin: 0; color: var(--k-caution); font-size: 13px; }

/* ---- Health cells --------------------------------------------------------- */
.kl-admin-health[b-sngje8zdy4] { display: grid; grid-template-columns: 1fr 1fr; gap: var(--k-space-3); }
.kl-admin-health-cell[b-sngje8zdy4] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    background: var(--k-bg);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-2);
}
.kl-admin-health-label[b-sngje8zdy4] { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--k-text-muted); }
.kl-admin-health-value[b-sngje8zdy4] { font-size: 16px; font-weight: 700; color: var(--k-text); }
.kl-admin-health-value--ok[b-sngje8zdy4] { color: var(--k-success); }
/* Warning/Error sync states — previously EMITTED by SyncHealthCssClass but never styled, so "Attention"
   rendered as plain text (status color absent AND emphasis absent). Canonical dark text remaps below. */
.kl-admin-health-value--warn[b-sngje8zdy4] { color: var(--k-caution); }
.kl-admin-health-value--err[b-sngje8zdy4] { color: var(--k-critical); }
.kl-admin-health-icon[b-sngje8zdy4] { margin-inline-end: var(--k-space-1); font-size: 14px; }
/* Canonical dark status palette (design-system §5f) — the fixed status hues do not flip on their own. */
html.dark .kl-admin-health-value--ok[b-sngje8zdy4] { color: #9ce6c1; }
html.dark .kl-admin-health-value--warn[b-sngje8zdy4] { color: #f4c884; }
html.dark .kl-admin-health-value--err[b-sngje8zdy4] { color: #f6ab9d; }

/* ---- Roles activity + launch link ----------------------------------------- */
.kl-admin-roles-activity[b-sngje8zdy4] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    color: var(--k-text);
    font-size: 14px;
    padding-block: var(--k-space-2);
    border-block-end: 1px solid var(--k-border);
}
.kl-admin-ago[b-sngje8zdy4] { margin-inline-start: auto; color: var(--k-text-muted); font-size: 12px; }
.kl-dot[b-sngje8zdy4] { inline-size: .5rem; block-size: .5rem; border-radius: 999px; flex-shrink: 0; background: var(--k-text-muted); }
.kl-dot--caution[b-sngje8zdy4] { background: var(--k-caution); }
.kl-admin-launch[b-sngje8zdy4] {
    margin-block-start: var(--k-space-3);
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-1);
    align-self: flex-start;
    color: var(--k-accent);
    font-size: 14px;
    text-decoration: none;
    font-weight: 600;
}
.kl-admin-launch:hover[b-sngje8zdy4] { text-decoration: underline; }
/* A6 - the deep-link CTA is a real 44px target, not a 14px line of text. Applied to the CLASS because the
   2026-09-12 drill-down pass adds four more of these (three "Show the rows" buttons and the route links);
   the pre-existing "Launch Why Denied" anchor was under the floor for the same reason and is fixed by the
   same declaration. `align-items: center` is already set above, so the extra height is centred, not padded. */
.kl-admin-launch[b-sngje8zdy4] {
    min-block-size: var(--k-touch);
}
/* The three drill triggers are BUTTONS, not links - they open a dialog, and a control that goes nowhere must
   not be an anchor. That means undoing the UA button chrome so they read as the same CTA as their anchor
   siblings. `text-align: start` matters: a <button> centres its text and the anchors do not, so without it a
   tile would show two CTAs on two different alignments. */
.kl-admin-drill-open[b-sngje8zdy4] {
    background: none;
    border: 0;
    padding: 0;
    text-align: start;
    font: inherit;
    color: var(--k-accent);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

/* The seat percentage's own arithmetic, under the meter. Muted and small: it is the CHECK on the figure
   above it, not a second figure competing with it. */
.kl-admin-seats-basis[b-sngje8zdy4] {
    margin: 0;
    color: var(--k-text-muted);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}
.kl-admin-launch-denied[b-sngje8zdy4] { margin-block-start: var(--k-space-3); margin-block-end: 0; color: var(--k-text-muted); font-size: 13px; }

/* ---- Config feed ---------------------------------------------------------- */
.kl-admin-config[b-sngje8zdy4] { display: flex; align-items: flex-start; gap: var(--k-space-2); font-size: 14px; color: var(--k-text-muted); }
.kl-admin-config-tag[b-sngje8zdy4] {
    background: var(--k-bg);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-sm);
    padding: 1px 4px;
    color: var(--k-text);
    flex-shrink: 0;
    font-size: 12px;
}

/* ---- Audit cells ---------------------------------------------------------- */
.kl-admin-audit[b-sngje8zdy4] { display: flex; gap: var(--k-space-3); }
.kl-admin-audit-cell[b-sngje8zdy4] {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    background: var(--k-bg);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-3);
}

/* ---- Tenant display defaults (the live DATA-010 fact) ---------------------- */
.kl-admin-defaults[b-sngje8zdy4] { margin: 0; color: var(--k-text); font-size: 15px; font-weight: 600; }
.kl-admin-packs[b-sngje8zdy4] { display: flex; gap: var(--k-space-1); }

/* A stat-shaped tile that IS a deep-link (Tenant Settings) — the link affordance of the
   reports tile without its centered layout. */
.kl-admin-tile--nav[b-sngje8zdy4] { cursor: pointer; transition: border-color .12s ease; }
.kl-admin-tile--nav:hover[b-sngje8zdy4] { border-color: var(--k-accent); }
.kl-admin-tile--nav:focus-visible[b-sngje8zdy4] { outline: 2px solid var(--k-accent); outline-offset: 2px; }

/* Tile-head glyphs — the glanceable-launchpad law (doctrine A.1): every tile title leads
   with a small accent glyph so the eye lands before it reads. */
.kl-admin-tile-icon[b-sngje8zdy4] { color: var(--k-accent); margin-inline-end: var(--k-space-2); font-size: 14px; }

/* ---- Reports-surface link tile -------------------------------------------- */
.kl-admin-tile--link[b-sngje8zdy4] {
    align-items: center;
    justify-content: center;
    text-align: center;
    cursor: pointer;
    transition: border-color .12s ease;
}
.kl-admin-tile--link:hover[b-sngje8zdy4] { border-color: var(--k-accent); }
.kl-admin-tile--link:focus-visible[b-sngje8zdy4] { outline: 2px solid var(--k-accent); outline-offset: 2px; }
.kl-admin-tile-linkicon[b-sngje8zdy4] { font-size: 26px; color: var(--k-accent); }

/* ---- Drafts & backlog halves (deep-links) --------------------------------- */
.kl-admin-backlog[b-sngje8zdy4] { display: flex; gap: var(--k-space-3); }
.kl-admin-backlog-half[b-sngje8zdy4] {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    background: var(--k-bg);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-3);
    text-decoration: none;
    color: var(--k-text);
    transition: border-color .12s ease;
}
.kl-admin-backlog-half:hover[b-sngje8zdy4] { border-color: var(--k-accent); }
.kl-admin-backlog-half:focus-visible[b-sngje8zdy4] { outline: 2px solid var(--k-accent); outline-offset: 2px; }

/* ---- Agency-activity chart -------------------------------------------------
   OWNER ASK 2026-09-13. The bars alone said nothing: they are scaled to the series
   max, so the tallest bucket is always full height, and at two equal buckets BOTH
   were full height — two 494px slabs with every number hidden in a title tooltip.
   The plot is now one part of the card; the caption, the scale, the column labels
   and the summary carry the numbers, and all four hold at 2 buckets and at 20.

   CLASS-FAMILY CLEARANCE (the [class$="-..."] foundation families): -caption,
   -scale, -plot, -col, -track, -bar, -num, -when, -axis, -summary and -what are
   each checked against the 40+ suffix families in the shared CSS and belong to
   none of them. The families that WOULD have bitten here are -label, -value,
   -row, -grid, -chip, -note and -empty; every one of them is avoided by name.
   ------------------------------------------------------------------------- */
.kl-admin-viewall[b-sngje8zdy4] { font-size: 13px; }

/* WHAT the chart plots. Rendered in every state, loading and empty included. */
.kl-admin-spark-caption[b-sngje8zdy4] { margin: var(--k-space-2) 0 0; font-size: 13px; color: var(--k-text); }

.kl-admin-spark[b-sngje8zdy4] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-2);
    /* inline-size: 100%, and NOT fit-content. fit-content was tried here to make the frame hug a two-bucket
       series, and it MEASURED CLEAN AND WRONG: past the direct-label limit a column holds only a bar, which has
       no intrinsic width, so every column contributed 0 to the frame max-content and 19 buckets rendered as 19
       bars of width 0 inside a 93px frame. Bar HEIGHTS were still correct, the console was clean and no width
       overflowed — nothing on the page could report it. A full-width frame with a short row of columns is the
       honest picture of a time axis that has two months in it. */
    inline-size: 100%;
    background: var(--k-bg);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-2);
    margin-block: var(--k-space-2);
}

/* THE SCALE — the series max at the top of the track and 0 at the baseline. Its
   block-size is the track's, so the two marks sit exactly at the two ends of the
   bars they explain. */
.kl-admin-spark-scale[b-sngje8zdy4] {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 0 0 auto;
    margin: 0;
    block-size: 5rem;
    font-size: 11px;
    line-height: 1;
    color: var(--k-text-muted);
    text-align: end;
}

.kl-admin-spark-plot[b-sngje8zdy4] {
    display: flex;
    align-items: flex-start;
    gap: 3px;
    flex: 1 1 auto;
    min-inline-size: 0;
}

/* One column per bucket. CAPPED, so a two-bucket series is two columns and not two
   half-page slabs — the shape that started this.

   THE FLEX BASIS IS 56px AND MUST NOT GO BACK TO 0. With `flex: 1 1 0` inside the
   fit-content frame above, the frame resolves to the SUM OF THE BASES, which is
   zero — measured at 19 buckets as 19 bars of width 0 in a 93px frame, with every
   bar HEIGHT still correct and the page still free of overflow. Nothing reported a
   problem: the chart was simply invisible. A real basis is what makes the frame
   hug two columns and still fill the card at nineteen. */
.kl-admin-spark-col[b-sngje8zdy4] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 56px;
    min-inline-size: 0;
    max-inline-size: 72px;
}

.kl-admin-spark-track[b-sngje8zdy4] { display: flex; align-items: flex-end; block-size: 5rem; }
.kl-admin-spark-bar[b-sngje8zdy4] { inline-size: 100%; flex: 1 1 auto; background: var(--k-text-muted); border-radius: 2px 2px 0 0; opacity: .45; }
.kl-admin-spark-bar--accent[b-sngje8zdy4] { background: var(--k-accent); opacity: 1; }

/* The per-column value and bucket, printed while the columns are wide enough to
   carry text. `anywhere` rather than an ellipsis: a truncated bucket label hides
   data, and a wrapped one does not. */
.kl-admin-spark-num[b-sngje8zdy4] { font-size: 11px; line-height: 1.3; text-align: center; color: var(--k-text); }
.kl-admin-spark-when[b-sngje8zdy4] { font-size: 10px; line-height: 1.3; text-align: center; color: var(--k-text-muted); overflow-wrap: anywhere; }

/* Past the direct-label limit the span is still readable at constant cost. */
.kl-admin-spark-axis[b-sngje8zdy4] {
    display: flex;
    justify-content: space-between;
    gap: var(--k-space-2);
    margin: 0 0 var(--k-space-2);
    font-size: 11px;
    color: var(--k-text-muted);
}

/* The numbers as numbers: the same three figures whether there are 2 buckets or 20. */
.kl-admin-spark-summary[b-sngje8zdy4] {
    display: flex;
    flex-wrap: wrap;
    gap: 2px var(--k-space-3);
    margin: 0 0 var(--k-space-2);
    font-size: 12px;
    color: var(--k-text-muted);
}

/* Empty-law (B.6): the empty chart is one quiet line, never a full-height bordered void.
   ("-none", never "-empty" — the foundation suffix family would center-balloon it.) */
.kl-admin-spark-none[b-sngje8zdy4] { margin: var(--k-space-2) 0; color: var(--k-text-muted); font-size: 13px; }

/* DEVICE SYNC — a different metric from the chart. Named, and set off by a rule, because
   unlabelled under the bars it was read as the chart's caption. */
.kl-admin-lastsync[b-sngje8zdy4] {
    display: flex;
    flex-wrap: wrap;
    gap: 2px var(--k-space-2);
    margin: 0;
    padding-block-start: var(--k-space-2);
    border-block-start: 1px solid var(--k-border);
    color: var(--k-text-muted);
    font-size: 13px;
}
.kl-admin-lastsync-what[b-sngje8zdy4] { color: var(--k-text); }

/* Owner ask (running list 2026-07-02): the running build's git commit — quiet mono footer,
   the clone of /account's .kl-account-build. */
.kl-admin-build[b-sngje8zdy4] { margin: var(--k-space-2) 0 0; font-size: 12px; color: var(--k-text-muted); text-align: right; }

/* =============================================================================
   UI-GUAR-018 / R2-07 — the "Sample data" mock-flag chip on the bento tiles.
   -----------------------------------------------------------------------------
   Per the collect-by-default ladder, a tile whose value is not yet wired to a live
   read renders this restrained, legible chip alongside an in-source TODO:WIRE marker
   so no number poses as live telemetry. Light text on a desaturated surface-mix fill;
   holds in light/dark/outdoor on the flipping --k-* channels (no off-token colour).
   ========================================================================== */
.kl-mock-chip[b-sngje8zdy4] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-inline-start: auto;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--k-text-muted);
    background: color-mix(in srgb, var(--k-text-muted) 14%, var(--k-surface));
    border: 1px solid var(--k-border);
    white-space: nowrap;
}
/* The corner variant pins to the tile's top-inline-end (the 1x1 stat tiles place the
   req-code chip there already; the mock chip sits just inside it). */
.kl-mock-chip--corner[b-sngje8zdy4] {
    position: absolute;
    inset-block-start: var(--k-space-3);
    inset-inline-end: var(--k-space-3);
    margin: 0;
    transform: translateY(1.6rem);
}

/* ═══ THE DRILL-DOWN POPUP ═══════════════════════════════════════════════════════════════════════════════
   INHERITED FROM /reliability (ReliabilityDashboard.razor.css, 2026-09-12), which measured every one of the
   faults these declarations close. This is a second page-scoped copy of that geometry and it is recorded as
   such in app/tools/page-review/OPEN-DECISIONS.md: the right home is the shared design system, and the
   promotion is deliberately NOT done in this pass because /reliability is a proven surface that another
   agent may be holding. What is NOT duplicated is anything shared already provides - the scrim, centering and
   dismiss come from <KlOverlay>, and the phone collapse from .kl-tablewrap + .kl-table-cards.

   A CENTRED POPUP per A12 - a selected item's detail never renders below its list.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.kl-drill-dialog[b-sngje8zdy4] {
    max-inline-size: 44rem;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    /* The .kl-dialog base sets padding-inline on children and padding-block-start on the first; the last child
       needs the matching foot pad or the pager sits on the panel's edge. */
    padding-block-end: var(--k-space-6);

    /* ── CONTAINMENT - WHY THESE TWO DECLARATIONS EXIST (D48) ──────────────────────────────────────────────
       The sheet ships NO universal `* { box-sizing: border-box }`. Its only two resets are `.kl-shell-main > *`
       (direct children of the shell main, which this panel is not) and the form-control rule. So .kl-dialog is
       CONTENT-BOX, its `max-block-size: calc(100dvh - 2 * var(--k-space-4))` caps the CONTENT box, and the
       `padding-block-end: var(--k-space-6)` above - 24px - is added OUTSIDE that cap. On /reliability that put
       the panel 24px past its own computed max-height and 8px past the bottom of the screen at every viewport
       measured, because the overlay's 16px inset absorbed 16 of the 24 and the remaining 8 overran.
       `border-box` makes the declared cap the TRUE outer height, whatever padding the panel is later given.
       THAT LINE IS NOW IN THE BASE and was removed from here on 2026-09-13: `.kl-dialog` declares
       `box-sizing: border-box` itself, naming this panel as one of the three that had bought the fix
       privately. The private copy is redundant, and a redundant copy is how the two drift apart. Only
       `overflow: hidden` remains, because that one REVERSES the base rather than repeating it.

       `overflow: hidden` - the base declares `overflow-y: auto` on .kl-dialog, which would make the PANEL a
       scroll container as well as the row list inside it. A dialog that scrolls AND contains a scroller is the
       defect; .kl-drill-body below is the one scroll region. */
    overflow: hidden;
}

/* ── THE ONE SCROLL REGION ────────────────────────────────────────────────────────────────────────────────
   The basis and the rows. The header above and the pager below are pinned, so the reader can always see WHICH
   figure this is and WHICH rows of how many are on screen, however far down the list they are.

   `min-block-size: 0` is load-bearing: a flex item's `min-height: auto` is its content height, so without it
   this refuses to shrink and pushes the panel past its cap - the same fault the note above records, one level
   down. */
.kl-drill-body[b-sngje8zdy4] {
    flex: 1 1 auto;
    min-block-size: 0;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
}
/* NOTHING INSIDE THE SCROLL REGION MAY SHRINK. Same trap, one level further in, and MEASURED on /reliability
   after the first fix: the row wrapper's `overflow-x: auto` forces its used `overflow-y` to `auto` (CSS
   Overflow 3), which makes its flex `min-height: auto` resolve to ZERO - so it shrank and scrolled on its own,
   putting a second scroll region inside the first. `flex: none` makes every child keep its content height. */
.kl-drill-body > *[b-sngje8zdy4] {
    flex: none;
}
/* A ring only when the engine judges the focus KEYBOARD-driven - the case that needs it, because a sighted
   keyboard user who pressed Next has no other way to see focus moved to the top of the new page. Never a bare
   `outline: none`, which would suppress the keyboard ring too. */
.kl-drill-body:focus:not(:focus-visible)[b-sngje8zdy4] {
    outline: none;
}

/* The pinned halves, named explicitly rather than left to `flex-shrink: 1`, so neither is squeezed into
   illegibility on a short viewport while the rows still have room. */
.kl-drill-head[b-sngje8zdy4],
.kl-drill-pager[b-sngje8zdy4] {
    flex: none;
}

.kl-drill-head[b-sngje8zdy4] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--k-space-4);
}
/* min-inline-size: 0 so a long title shrinks instead of pushing Close off the panel's trailing edge. */
.kl-drill-headtitle[b-sngje8zdy4] {
    min-inline-size: 0;
}
/* The figure the rows belong to. Display face + tabular figures so it reads as the SAME number the tile
   behind the scrim is showing. */
.kl-drill-figure[b-sngje8zdy4] {
    margin: var(--k-space-1) 0 0;
    font-family: var(--k-font-display);
    font-size: clamp(22px, 3vw, 30px);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--k-text);
    font-variant-numeric: tabular-nums;
}
/* A6 - the header Close is a real 44px target, not a 24px glyph. */
.kl-drill-iconbtn[b-sngje8zdy4] {
    min-inline-size: var(--k-touch);
    min-block-size: var(--k-touch);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    padding: 0;
}

/* WHAT SELECTS THESE ROWS. A definition list, because each line is genuinely a term and its value, and
   because a screen reader then announces the pairing rather than three loose sentences. */
.kl-drill-basis[b-sngje8zdy4] {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--k-space-1) var(--k-space-4);
    margin: 0;
    font-size: 13px;
}
.kl-drill-basis dt[b-sngje8zdy4] {
    color: var(--k-text-muted);
    font-weight: 600;
}
.kl-drill-basis dd[b-sngje8zdy4] {
    margin: 0;
    color: var(--k-text);
    /* A long scope sentence must wrap inside the panel, never widen it. */
    overflow-wrap: anywhere;
}
/* At phone widths the two-column pairing costs more than it gives: the value column narrows to a few
   characters and every sentence becomes a paragraph of one-word lines. Stack the pairs instead. */
@media (max-width: 26rem) {
    .kl-drill-basis[b-sngje8zdy4] {
        grid-template-columns: 1fr;
        gap: 0;
    }
    .kl-drill-basis dd[b-sngje8zdy4] {
        margin-block-end: var(--k-space-2);
    }
}
/* THE SCOPE AND THE RECONCILIATION STAY ON SCREEN WHILE THE ROWS MOVE. On a court-facing surface a list whose
   basis has scrolled away is the trap the basis exists to close. HEIGHT-GATED: below 34rem of viewport height
   the pinned header, this block and the pinned pager together leave the rows a single line, and a block
   pinned over an empty list is worse than one the reader scrolls past. The background is required - a sticky
   element paints over what scrolls beneath it only where it has one - and --k-surface is the panel's own, so
   it is correct in both themes. */
@media (min-height: 34rem) {
    .kl-drill-basis[b-sngje8zdy4] {
        position: sticky;
        inset-block-start: 0;
        z-index: 1;
        background: var(--k-surface);
        margin-block: calc(-1 * var(--k-space-2)) calc(-1 * var(--k-space-2));
        padding-block: var(--k-space-2);
    }
}

/* The empty state DELIBERATELY ends in "-empty": the design system's §5h state kit keys on
   [class$="-empty"] and turns it into the centred, muted state box, which is exactly the shape a
   "the figure really is zero" answer wants inside a dialog. (The sparkline's empty line on this same page
   deliberately does NOT end in "-empty", because there a full-height centred box is the wrong answer. The
   family is a tool, not a hazard - it just has to be chosen.) */
.kl-drill-empty[b-sngje8zdy4] {
    margin: 0;
}

/* THE TABLE SCROLLS SIDEWAYS INSIDE ITS OWN CONTAINER, never the page.

   `overflow-y: visible` IS THE FIX, not decoration. The shared `.kl-shell-main .kl-tablewrap` declares
   `overflow-y: hidden`, and a flex item whose overflow is not `visible` takes `min-height: auto` as ZERO - so
   it shrinks to whatever the column has left and then CLIPS the overflow with no scrollbar and no scroll. On
   /reliability that was measured at 1400x900 as a 553px window over 1,114px of rows, with 8 of 16 rows
   unreachable by any gesture. Restoring `visible` in the block axis means this box can never clip a row: its
   height is always its content, and the scrolling is done once, by .kl-drill-body around it. */
.kl-drill-tablewrap[b-sngje8zdy4] {
    overflow-x: auto;
    overflow-y: visible;
    -webkit-overflow-scrolling: touch;
}
.kl-drill-table[b-sngje8zdy4] {
    inline-size: 100%;
    border-collapse: collapse;
    font-size: 13px;
}
.kl-drill-table th[b-sngje8zdy4],
.kl-drill-table td[b-sngje8zdy4] {
    text-align: start;
    padding: var(--k-space-2) var(--k-space-3);
    border-block-end: 1px solid var(--k-border);
    vertical-align: top;
}
.kl-drill-table th[b-sngje8zdy4] {
    color: var(--k-text-muted);
    font-weight: 600;
    white-space: nowrap;
}
.kl-drill-table tbody tr:last-child td[b-sngje8zdy4] {
    border-block-end: 0;
}
.kl-drill-rowmeta[b-sngje8zdy4] {
    color: var(--k-text-muted);
}

/* The row link. A6: the whole cell is the target, so the hit area is the row's height rather than the 13px
   of the label. */
.kl-drill-link[b-sngje8zdy4] {
    display: flex;
    align-items: center;
    min-block-size: var(--k-touch);
    color: var(--k-text);
    text-decoration: none;
}
.kl-drill-link:hover .kl-drill-rowname[b-sngje8zdy4],
.kl-drill-link:focus-visible .kl-drill-rowname[b-sngje8zdy4] {
    text-decoration: underline;
}
.kl-drill-link:focus-visible[b-sngje8zdy4] {
    outline: 2px solid var(--k-focus, var(--k-teal-500));
    outline-offset: 2px;
    border-radius: var(--k-radius-sm);
}
.kl-drill-rowname[b-sngje8zdy4] {
    font-weight: 600;
}
/* The shared card primitive assumes a one-line title and sets `white-space: nowrap; overflow: hidden;
   text-overflow: ellipsis` on `.kl-table-cards .kl-tcard-title > *`. A lookup DisplayName is a human
   identifier and half of one is worse than a wrapped one, so wrapping is restored for this cell. */
.kl-drill-table .kl-drill-link[b-sngje8zdy4] {
    overflow: visible;
    white-space: normal;
}
.kl-drill-table .kl-drill-rowname[b-sngje8zdy4] {
    white-space: normal;
    overflow: visible;
    overflow-wrap: anywhere;
}

.kl-drill-pager[b-sngje8zdy4] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
}
.kl-drill-range[b-sngje8zdy4] {
    margin: 0;
    color: var(--k-text-muted);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}
.kl-drill-pagerbtns[b-sngje8zdy4] {
    display: flex;
    gap: var(--k-space-2);
}
.kl-drill-pagerbtns .kl-btn[b-sngje8zdy4] {
    min-block-size: var(--k-touch);
}
/* _content/Kanine.Web/Components/Pages/CjisAddendum.razor.rz.scp.css */
/* Phase G WP-G5 — the CJIS addendum execution ceremony. */

.kl-addendum-lede[b-tnn6tpejc1] {
    max-width: 68ch;
    color: var(--k-text-muted);
}

.kl-addendum-doc[b-tnn6tpejc1] {
    max-height: 22rem;
    overflow-y: auto;
    padding: 1rem 1.25rem;
    border: 1px solid var(--k-border);
    border-radius: 8px;
    background: var(--k-surface, transparent);
}

.kl-addendum-doc pre[b-tnn6tpejc1] {
    margin: 0;
    white-space: pre-wrap;
    font-family: inherit;
    font-size: 0.9rem;
    line-height: 1.5;
}

.kl-addendum-meta[b-tnn6tpejc1] {
    font-size: 0.8rem;
    color: var(--k-text-muted);
}

.kl-addendum-attest[b-tnn6tpejc1] {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.75rem 0 1rem;
    max-width: 68ch;
    cursor: pointer;
}

.kl-addendum-state-chip--agency_signed[b-tnn6tpejc1] {
    background: color-mix(in srgb, #bf8700 18%, transparent);
    color: #9a6700;
}

.kl-addendum-state-chip--executed[b-tnn6tpejc1] {
    background: color-mix(in srgb, #1a7f37 16%, transparent);
    color: #1a7f37;
}

html.dark .kl-addendum-state-chip--agency_signed[b-tnn6tpejc1] {
    color: #d4a72c;
}

html.dark .kl-addendum-state-chip--executed[b-tnn6tpejc1] {
    color: #3fb950;
}

.kl-addendum-pending[b-tnn6tpejc1] {
    border-left: 3px solid #bf8700;
}

.kl-addendum-executed[b-tnn6tpejc1] {
    border-left: 3px solid #1a7f37;
}
/* _content/Kanine.Web/Components/Pages/CustomFields.razor.rz.scp.css */
/* =============================================================================
   CustomFields (custom-fields.html) — page-scoped R11 refinement (UI-GUAR-011).
   The PLAT-031 tenant-defined custom-field DEFINITION admin console. The shared
   design system (kanine-design-system.css) gives the page shell (kl-page), the
   form atoms (kf-field / kf-label / kf-input / kf-select), the buttons (kl-btn)
   and the icon primitive; this stylesheet adds ONLY the page-specific structure
   the system does NOT provide and which, until now, rendered UNSTYLED on the live
   host (there was no co-located CSS at all): the titled header + capacity chip,
   the two-pane (field-list rail + definition workspace) split, the selectable
   field-list rows with a mono key + type chip + governance pill, the readonly
   x_-prefix key input, the grouped definition form, the governance disclosure,
   and the composed empty states.

   Every colour resolves through --k-* tokens so the three modes (light / dark /
   outdoor) flip correctly and the R11 token/canvas gate holds — no raw hex, no
   gradient, no off-token fill. The spacing scale is --k-space-1/2/3/4/6/8/12/16
   (there is NO --k-space-5 / -7 / -9 …); every value below is a real step.
   NOTE (corrected 2026-07-02): scoped CSS CAN reach the dark ancestor — write a
   BARE `html.dark .my-class` rule (it is `:global(html.dark)` that ships verbatim
   and dies; Lookups.razor.css:340 is the proven in-repo pattern). The fixed
   status hues (--k-critical/--k-success/--k-caution) do NOT flip on their own,
   so the tinted badges below carry the canonical dark text remaps (§5f).
   ========================================================================== */

/* (Page width + centering + the column gap come from the foundation's .kl-page /
   .kl-page--wide — not re-declared here.) */

/* ---- Titled header: the page anchor (title + the real defined-field count) beside
   the capacity chip + the primary New Field action. ------------------------------ */
/* The root .kl-page is a flex column with its own gap, so the header owns NO bottom
   margin (that would double the rhythm against the gap). */
.kl-section-head[b-6k34tc87jy] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--k-space-4);
}
.kl-section-head h1[b-6k34tc87jy] {
    margin: 0 0 var(--k-space-1);
}
.kl-section-head .kl-muted[b-6k34tc87jy] {
    margin: 0;
    color: var(--k-text-muted);
}
.kl-head-actions[b-6k34tc87jy] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-3);
    /* Keep the actions from being squeezed when the title wraps. */
    flex: 0 0 auto;
}

/* Capacity chip: a quiet, mode-aware status pill of the per-entity 50-cap usage —
   a tinted bordered chip (not bare text) so the headroom reads at a glance, and it
   shifts to the caution channel once the cap is reached. */
.kl-capacity[b-6k34tc87jy] {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--k-touch);
    padding-block: 0;
    padding-inline: var(--k-space-4);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .01em;
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-full);
    white-space: nowrap;
}
/* Owner ruling 2026-08-09 ("only as approached"): the chip does not exist below the 80% threshold, so the only two
   states it ever paints are WARNING (approaching) and FULL (at the cap). There is no calm resting state to design. */
.kl-capacity--warn[b-6k34tc87jy],
.kl-capacity--full[b-6k34tc87jy] {
    color: var(--k-caution);
    background: color-mix(in srgb, var(--k-caution) 14%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-caution) 36%, var(--k-surface));
}
.kl-capacity--full[b-6k34tc87jy] {
    color: var(--k-critical);
    background: color-mix(in srgb, var(--k-critical) 14%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-critical) 38%, var(--k-surface));
}
/* Canonical dark status text (design-system §5f) — the fixed status hues do not flip on their own. */
html.dark .kl-capacity--warn[b-6k34tc87jy] { color: #f4c884; }
html.dark .kl-capacity--full[b-6k34tc87jy] { color: #f6ab9d; }

/* At the cap the disabled New-field button must SAY why. A quiet full-width line under the header, never a card.
   NOT named *-note: the shared sheet sweeps [class$="-note"] into the standalone NOTICE family. */
.kl-capacity-atcap[b-6k34tc87jy] {
    margin: 0;
    padding: var(--k-space-3) var(--k-space-4);
    color: var(--k-text-muted);
    font-size: 13px;
    line-height: 1.55;
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-inline-start: 3px solid var(--k-caution);
    border-radius: var(--k-radius-md);
}

/* ---- Two-pane split: a fixed-width field-list rail beside the fluid definition
   workspace (collapses to a stack on narrow viewports). --------------------------- */
.kl-split[b-6k34tc87jy] {
    display: flex;
    align-items: stretch;
    gap: var(--k-space-6);
}
@media (max-width: 900px) {
    .kl-split[b-6k34tc87jy] {
        flex-direction: column;
    }
}

/* OWNER RULING 2026-09-11 - MAKE THE SPLIT FILL HONESTLY.
   On arrival nothing is selected, so the detail pane holds only its empty state and the rail holds the
   list's 18rem reserve. Measured at 1400x900 the whole split was 406.9px tall and stopped at y=571.9 in
   a 900px viewport - two short cards floating above a 328px void.

   The fill is EXACT and carries no magic number. .kl-shell (the layout) is already a min-height:100dvh
   flex column and .kl-shell-main is already flex:1 1 auto, so the working area is the right height
   ALREADY; the page simply did not stretch inside it, because .kl-shell-main is display:block and
   .kl-page is a normal block child. Percentages cannot fix that: .kl-shell's height is min-height and
   so indefinite, which is why a min-block-size:100% on .kl-page resolves to nothing (measured - it
   changed the geometry by 0px). Making .kl-shell-main a flex column instead lets .kl-page absorb the
   free space by FLEXING, which needs no definite height and no constant. That one rule cannot live in
   this page-scoped sheet (.kl-shell-main is the layout's element, not this component's), so it sits in
   the web head's app.css behind :has(> .kl-cf-fill) and is inert on every other route.

   A fixed offset was tried first and REJECTED on measurement: .kl-shell-main's padding is viewport
   derived (18.02 / 20.48 / 25.6 / 28 / 32px at 901 / 1024 / 1280 / 1400 / 1920, and its padding-bottom
   is 74.02px at 901 against 28px at 1400), so calc(100dvh - 113px) overflowed the viewport by 8px at
   1920x1080 and introduced a scrollbar that was not there before.

   min-block-size, never block-size: a SELECTED field renders a long form, and the split must keep
   growing past the viewport and scroll (measured 1479px tall, page scrollHeight 1688) rather than clip.

   The list scrolls INSIDE the filled rail and keeps its 18rem floor, so the rail is a taller surface
   but never a column of stretched empty rows (the ruling's "do not stretch an empty list to no
   purpose"). Desktop only: at <=900px the split is already a stack and already fills. */
@media (min-width: 901px) {
    .kl-cf-fill[b-6k34tc87jy] {
        flex: 1 1 auto;
        min-block-size: 0;
    }

    .kl-split[b-6k34tc87jy] {
        flex: 1 1 auto;
        min-block-size: 0;
    }

    .kl-list-pane[b-6k34tc87jy] {
        min-block-size: 0;
    }

    .kl-list[b-6k34tc87jy] {
        flex: 1 1 auto;
    }
}

/* ---- Left rail: the target-entity selector + the scrollable field list. -------- */
.kl-list-pane[b-6k34tc87jy] {
    flex: 0 0 20rem;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    padding: var(--k-space-4);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}
@media (max-width: 900px) {
    .kl-list-pane[b-6k34tc87jy] {
        flex-basis: auto;
    }
}
/* The entity-selector field inside the rail owns no extra bottom margin (the rail
   gap already spaces it from the list). */
.kl-list-pane .kf-field[b-6k34tc87jy] {
    margin-block-end: 0;
}

/* The field list itself: a calm, scannable column of selectable rows. A reserved
   min height keeps the rail a stable surface whether it holds three rows or one
   (CLS guard — the list never collapses to nothing while the first query settles). */
.kl-list[b-6k34tc87jy] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    min-block-size: 18rem;
    overflow-y: auto;
}

/* A field-list row — the whole row is the select affordance. Generous touch target,
   a clear resting / hover / selected hierarchy. */
.kl-list-item[b-6k34tc87jy] {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--k-space-1);
    min-block-size: var(--k-touch);
    padding: var(--k-space-3);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    cursor: pointer;
    transition: background-color var(--k-dur-1) var(--k-ease),
                border-color var(--k-dur-1) var(--k-ease);
}
.kl-list-item:hover[b-6k34tc87jy] {
    background: var(--k-surface-2);
    border-color: var(--k-outline);
}
.kl-list-item:focus-visible[b-6k34tc87jy] {
    outline: 3px solid var(--k-focus);
    outline-offset: 2px;
}
/* The selected row carries the navy/teal identity: a left accent bar + a tinted fill
   (mirroring the signed-off OrgUnits tree + Lookups rail). --k-accent flips per mode. */
.kl-list-item--selected[b-6k34tc87jy] {
    position: relative;
    background: color-mix(in srgb, var(--k-accent) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-accent) 30%, var(--k-surface));
}
.kl-list-item--selected[b-6k34tc87jy]::before {
    content: "";
    position: absolute;
    inset-block: 8px;
    inset-inline-start: 0;
    inline-size: 3px;
    border-radius: var(--k-radius-full);
    background: var(--k-accent);
}

/* Owner ruling 2026-08-10: the row is two explicit lines, not one wrapping line. The HEAD
   line carries the label + its governance badge; the META line carries the machine key +
   type chip. A wrap-driven layout put the badges wherever the widths happened to land — a
   long key could push a badge onto a third line, and the badge read as a property of the
   key rather than of the field. */
.kl-list-item-head[b-6k34tc87jy],
.kl-list-item-meta[b-6k34tc87jy] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    min-inline-size: 0;
}

/* Ruling 3 inverted the identity of a field: the LABEL is what an admin recognises, so it
   leads the row and the machine key follows it as a quiet mono token. It takes the head
   line's flexible width, which is what parks the governance badge at the trailing edge. */
.kl-list-item-name[b-6k34tc87jy] {
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    color: var(--k-text);
}
.kl-list-item--selected .kl-list-item-name[b-6k34tc87jy] {
    color: var(--k-accent);
}

/* The namespaced key — the row's machine identifier, a quiet mono token. It takes the
   meta line's flexible width so the type chip sits at that line's trailing edge. */
.kl-list-item-key[b-6k34tc87jy] {
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--k-font-mono, ui-monospace, monospace);
    font-size: 13px;
    color: var(--k-text);
}
.kl-list-item--selected .kl-list-item-key[b-6k34tc87jy] {
    color: var(--k-accent);
    font-weight: 600;
}
/* The field-type chip: a small neutral capsule (Text / Number / Lookup …). */
.kl-list-item-type[b-6k34tc87jy] {
    flex: 0 0 auto;
    padding-block: 2px;
    padding-inline: var(--k-space-2);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-sm);
    white-space: nowrap;
}

/* ---- Governance badges: PII (critical) / Analyzable (success) — tinted, bordered
   pills (not bare coloured text) so the data-governance state reads at a glance; every
   channel resolves through its status token so the chip flips across the three modes. */
.kl-badge[b-6k34tc87jy] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    padding-block: 2px;
    padding-inline: var(--k-space-2);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    line-height: 1.4;
    border: 1px solid transparent;
    border-radius: var(--k-radius-full);
    white-space: nowrap;
}
.kl-badge--pii[b-6k34tc87jy] {
    color: var(--k-critical);
    background: color-mix(in srgb, var(--k-critical) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-critical) 34%, var(--k-surface));
}
/* OWNER RULING 2026-09-11 - the analytics mark was INVERTED (see CustomFields.razor). It no longer
   says "this field is analyzable" on every row; it marks the EXCEPTION, the field kept off reports.
   Two deliberate differences from .kl-badge--pii, both following from that:
     - NEUTRAL, not a status colour. This is a quiet fact about where a field can be used, not an
       alarm, and it must not compete with the critical-toned PII chip beside it on the same line.
     - It reads as a PHRASE. The shared .kl-badge sets uppercase + .05em tracking, which is right for
       the acronym "PII" and wrong for two ordinary words: "OFF REPORTS" is the shouty system voice
       the ruling removed. Un-setting both is what makes it the reader's language and not a constant.
   Suffix check (trap T7): the class ATTRIBUTE ends "-offreports", which matches no [class$=] family
   in the shared sheet. */
.kl-badge--offreports[b-6k34tc87jy] {
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border-color: var(--k-border);
    text-transform: none;
    letter-spacing: normal;
    font-size: 11px;
    font-weight: 600;
}
/* Canonical dark status text remaps (design-system §5f — the UI-GUAR-027 bug class the Lookups pills fixed):
   the surface mixes above re-point via var(--k-surface), but the fixed status TEXT hues need the dark palette. */
html.dark .kl-badge--pii[b-6k34tc87jy] { color: #f6ab9d; }
/* The off-reports chip resolves entirely through --k-text-muted / --k-surface-2 / --k-border, which
   the dark palette already re-points, so it needs no fixed dark remap the way the status hues do. */

/* ---- Empty list state: a quiet, centred line inside the reserved rail height (not a
   void). Token-driven so it flips cleanly. ---------------------------------------- */
.kl-list .kl-muted[b-6k34tc87jy] {
    margin: auto 0;
    padding: var(--k-space-6) var(--k-space-3);
    text-align: center;
    color: var(--k-text-muted);
}

/* ---- Right pane: the definition workspace. A quiet accent top edge gives the
   workspace presence as the page anchor without shouting (the Lookups/OrgUnits
   precedent). --------------------------------------------------------------------- */
.kl-detail-pane[b-6k34tc87jy] {
    flex: 1 1 0;
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    padding: var(--k-space-6);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-block-start: 2px solid color-mix(in srgb, var(--k-accent) 38%, var(--k-border));
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}

/* The workspace heading (Field Definition). */
.kl-section-title[b-6k34tc87jy] {
    margin: 0;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -.005em;
    color: var(--k-text);
}

/* ---- The definition form: a single calm column. The structural envelope fields
   (entity / key / label / type) read top-down; the grouped sections follow. -------- */
.kl-form-grid[b-6k34tc87jy] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
}
/* Neutralise the foundation's bottom margin on the fields inside (the form gap owns
   the rhythm) so the column spacing stays even. */
.kl-form-grid .kf-field[b-6k34tc87jy] {
    margin-block-end: 0;
}

/* The readonly x_-prefix key input: a joined prefix capsule + the suffix input, so the
   immutable namespace reads as part of one control.

   THE WRAPPER IS -affix AND NOT -input, AND THAT IS LOAD-BEARING. The foundation styles anything whose class
   ATTRIBUTE ends in "-input" as a text field (kanine-design-system.css §[class$="-input"]). Named
   .kl-key-input, this wrapper therefore took an input's own border, background and PADDING — and that padding
   put a visible gap between the field's left edge and the x_ capsule, so the affix read as a box floating
   inside a box. Owner review 2026-08-07. Fifth collision of this kind found in the campaign; see
   class-suffix-family-trap. */
.kl-key-affix[b-6k34tc87jy] {
    display: flex;
    align-items: stretch;
}
.kl-key-prefix[b-6k34tc87jy] {
    display: inline-flex;
    align-items: center;
    padding-inline: var(--k-space-3);
    font-family: var(--k-font-mono, ui-monospace, monospace);
    font-size: 15px;
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border: 1px solid var(--k-outline);
    border-inline-end: 0;
    border-start-start-radius: var(--k-radius-sm);
    border-end-start-radius: var(--k-radius-sm);
}
/* Square off the input's leading corners so it butts cleanly against the prefix. */
.kl-key-affix .kf-input[b-6k34tc87jy] {
    border-start-start-radius: 0;
    border-end-start-radius: 0;
}

/* ---- Grouped sections (Data Governance / Behavioral Logic): NOT nested cards —
   they read as quiet hairline-separated groups WITHIN the one definition surface
   (the prototype idiom). Override the foundation's [class$="-section"] card. ------- */
.kl-form-section[b-6k34tc87jy] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    margin-block: 0;
    padding: var(--k-space-6) 0 0;
    background: transparent;
    border: 0;
    border-block-start: 1px solid color-mix(in srgb, var(--k-border) 70%, transparent);
    border-radius: 0;
    box-shadow: none;
}
.kl-form-section-title[b-6k34tc87jy] {
    margin: 0;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--k-text);
}
.kl-form-section .kf-field[b-6k34tc87jy] {
    margin-block-end: 0;
}

/* (The switch rows — PII and Required — were declared HERE until 2026-09-12. The rules are now the shared
   `label.kf-field--switch` block in kanine-design-system.css §5b-sw, which also carries the §A6 var(--k-touch)
   floor these copies never had: the activating label measured 18px tall, the same size as its own checkbox.
   Three pages had hand-rolled the same row. A1: the switch row is declared once, for both heads.) */

/* Field help text under a control (kf-help is not a foundation -note suffix). */
.kf-help[b-6k34tc87jy] {
    font-size: 13px;
    line-height: 1.5;
    color: var(--k-text-muted);
}

/* The PII effect note (ruling 2026-09-11). It is a <p> SIBLING of the .kf-field--switch label rather
   than a child of it, so a reader clicking the explanation does not toggle the box. It therefore owns
   its own rhythm: the switch's own -field family margin already spaces the pair from what follows, so
   this pulls up tight under the control it explains and adds no trailing space of its own. */
.kl-cf-effect[b-6k34tc87jy] {
    margin-block: calc(var(--k-space-2) * -1) 0;
    max-inline-size: 46rem;
}

/* ---- Governance disclosure: a quiet accent toggle + a tinted note panel. -------- */
.kl-disclosure[b-6k34tc87jy] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}
/* A6 (measured live 2026-08-09 at 320/375/393/430/1400: this rendered 38px, below the WCAG 2.5.8
   line, on BOTH disclosures — the pre-existing governance note and the new Advanced key panel).
   It is a role="button" thumb target, so it takes the house floor like every other hit target. */
.kl-disclosure-toggle[b-6k34tc87jy] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    align-self: flex-start;
    min-block-size: var(--k-touch);
    color: var(--k-accent);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.kl-disclosure-toggle:focus-visible[b-6k34tc87jy] {
    outline: 3px solid var(--k-focus);
    outline-offset: 2px;
    border-radius: var(--k-radius-sm);
}
.kl-disclosure-panel[b-6k34tc87jy] {
    margin: 0;
    padding: var(--k-space-3) var(--k-space-4);
    color: var(--k-text-muted);
    font-size: 13px;
    line-height: 1.55;
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
}

/* ---- Form actions: trailing-aligned, a hairline rule above. -------------------- */
.kl-form-actions[b-6k34tc87jy] {
    display: flex;
    justify-content: flex-end;
    gap: var(--k-space-3);
    margin-block-start: var(--k-space-2);
    padding-block-start: var(--k-space-6);
    border-block-start: 1px solid color-mix(in srgb, var(--k-border) 70%, transparent);
}

/* Inline save error under the form. */
.kl-error[b-6k34tc87jy] {
    margin: 0;
    color: var(--k-critical);
    font-size: 0.9rem;
}
html.dark .kl-error[b-6k34tc87jy] { color: #f6ab9d; }

/* ---- A cautionary inline line (the PII/search coupling, a disambiguated key, an advanced
   expression being preserved). A quiet tinted line, never a card — §B4. Deliberately NOT
   named *-note / *-notice / *-banner: those are shared suffix FAMILIES. -------------------- */
.kl-inline-warn[b-6k34tc87jy] {
    margin: 0;
    padding: var(--k-space-2) var(--k-space-3);
    color: var(--k-text-muted);
    font-size: 13px;
    line-height: 1.55;
    background: color-mix(in srgb, var(--k-caution) 10%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-caution) 30%, var(--k-surface));
    border-radius: var(--k-radius-sm);
}
/* The RETIRED rule (owner ruling 2026-09-11 #2). A stored visibility rule the builder cannot show
   as rows is rendered read-only here — seen, then replaced on the next save — because the raw
   expression box it used to fall back into is gone. It is static text, never an input: the whole
   point of the ruling is that the builder is the only way to author one. The block carries two
   paragraphs, so the shared warn line's zero margin has to be restated for the children. */
.kl-inline-warn p[b-6k34tc87jy] {
    margin: 0;
}
.kl-inline-warn p + p[b-6k34tc87jy] {
    margin-block-start: var(--k-space-2);
}
.kl-exprretired[b-6k34tc87jy] {
    color: var(--k-text);
    font-family: var(--k-font-mono, ui-monospace, monospace);
    font-size: 12px;
    overflow-wrap: anywhere;
}

.kl-inline-warn code[b-6k34tc87jy] {
    font-family: var(--k-font-mono, ui-monospace, monospace);
    font-size: 12px;
    color: var(--k-text);
}

/* An inline text action inside a sentence (Replace it with simple conditions). It is a real
   <button>, so it must not inherit the button chrome — and it keeps a 48px hit box via padding
   on a line that already stands 48px tall, so A6 is met without a block of dead space. */
.kl-linkbtn[b-6k34tc87jy] {
    display: inline;
    margin: 0;
    padding: 0;
    color: var(--k-accent);
    font: inherit;
    font-weight: 600;
    text-decoration: underline;
    background: none;
    border: 0;
    cursor: pointer;
}
.kl-linkbtn:focus-visible[b-6k34tc87jy] {
    outline: 3px solid var(--k-focus);
    outline-offset: 2px;
    border-radius: var(--k-radius-sm);
}

/* ---- The Advanced (field key) disclosure body: a real panel with stacked content, so it
   overrides the governance note's single-paragraph metrics. ------------------------------- */
.kl-disclosure-panel[b-6k34tc87jy] {
    display: block;
}
#cf-advanced-panel[b-6k34tc87jy] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}
/* The key row grows a trailing Copy affordance (ruling 3). */
.kl-key-input .kl-key-copy[b-6k34tc87jy] {
    flex: 0 0 auto;
    min-block-size: var(--k-touch);
    margin-inline-start: var(--k-space-2);
    white-space: nowrap;
}
.kl-key-input .kf-input[b-6k34tc87jy] {
    flex: 1 1 auto;
    min-inline-size: 0;
}

/* =============================================================================
   The KEL expression builders (owner ruling 1, 2026-08-09).
   A composed rule is a stack of ROWS; each row is [join] [field] [operator]
   [value] [remove]. At desk width a row is one line; at phone width it wraps to a
   readable block WITHOUT any control shrinking below var(--k-touch) (A6) and
   without the page ever gaining horizontal scroll.
   ========================================================================== */
.kl-exprfield[b-6k34tc87jy] {
    gap: var(--k-space-2);
}
.kl-exprbuilder[b-6k34tc87jy] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
}
.kl-exprbuilder--rows[b-6k34tc87jy] {
    flex-direction: column;
    align-items: stretch;
    gap: var(--k-space-3);
    padding: var(--k-space-3);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
}
/* The default-value builder is a short inline pair (mode + its one argument), so its two
   controls share a row and each keeps a usable minimum before wrapping. */
.kl-exprbuilder > .kf-select[b-6k34tc87jy],
.kl-exprbuilder > .kf-input[b-6k34tc87jy] {
    flex: 1 1 12rem;
    min-inline-size: 0;
    min-block-size: var(--k-touch);
}

.kl-exprrow[b-6k34tc87jy] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
}
.kl-exprrow-addline[b-6k34tc87jy] {
    justify-content: flex-start;
}
.kl-exprrow .kf-select[b-6k34tc87jy],
.kl-exprrow .kf-input[b-6k34tc87jy] {
    min-block-size: var(--k-touch);
    min-inline-size: 0;
}
/* The join cell is a fixed narrow lead-in so every row's field picker starts on one column. */
.kl-exprjoin[b-6k34tc87jy] {
    flex: 0 0 5rem;
    inline-size: 5rem;
}
.kl-exprjoin--fixed[b-6k34tc87jy] {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--k-touch);
    color: var(--k-text-muted);
    font-size: 13px;
    font-weight: 600;
}
.kl-exprfieldpick[b-6k34tc87jy] { flex: 1 1 11rem; }
.kl-exproppick[b-6k34tc87jy]    { flex: 1 1 9rem; }
.kl-exprvalue[b-6k34tc87jy]     { flex: 1 1 9rem; }
.kl-exprremove[b-6k34tc87jy] {
    flex: 0 0 auto;
    min-block-size: var(--k-touch);
    color: var(--k-text-muted);
}

/* The emitted rule, shown so the builder is auditable rather than a black box. */
.kl-exprpreview[b-6k34tc87jy] {
    margin: 0;
    padding: var(--k-space-2) var(--k-space-3);
    color: var(--k-text-muted);
    font-family: var(--k-font-mono, ui-monospace, monospace);
    font-size: 12px;
    line-height: 1.5;
    overflow-wrap: anywhere;
    background: var(--k-surface-2);
    border: 1px dashed var(--k-border);
    border-radius: var(--k-radius-sm);
}

/* Phone: a five-control row cannot stay one line at 393px without shrinking something below
   the touch floor, so the row becomes a block — the join and field on one line, the operator
   and value on the next, and Remove full width beneath. Nothing shrinks; only the wrap point
   moves (A6 is never traded for width). */
@media (max-width: 640px) {
    .kl-exprrow[b-6k34tc87jy] {
        gap: var(--k-space-2);
        padding: var(--k-space-2);
        background: var(--k-surface);
        border: 1px solid var(--k-border);
        border-radius: var(--k-radius-sm);
    }
    .kl-exprjoin[b-6k34tc87jy],
    .kl-exprjoin--fixed[b-6k34tc87jy] {
        flex: 0 0 4rem;
        inline-size: 4rem;
    }
    .kl-exprfieldpick[b-6k34tc87jy] { flex: 1 1 8rem; }
    .kl-exproppick[b-6k34tc87jy],
    .kl-exprvalue[b-6k34tc87jy]     { flex: 1 1 100%; }
    .kl-exprremove[b-6k34tc87jy]    { flex: 1 1 100%; }
    .kl-exprbuilder > .kf-select[b-6k34tc87jy],
    .kl-exprbuilder > .kf-input[b-6k34tc87jy] {
        flex: 1 1 100%;
    }
}

/* ---- Detail-pane empty state: a composed, centred placeholder (an inline glyph in a
   tinted disc + a heading + one line of guidance) matching the OrgUnits caliber — the
   right pane never reads as a bare void. The glyph is an inline SVG (no icon-font
   dependency, so no FOUT/CLS risk), token-stroked so it flips across the modes. ----- */
.kl-detail-empty[b-6k34tc87jy] {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: var(--k-space-3);
    min-block-size: 18rem;
    padding: var(--k-space-8) var(--k-space-6);
}
.kl-detail-empty-disc[b-6k34tc87jy] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 64px;
    block-size: 64px;
    margin-block-end: var(--k-space-1);
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    color: var(--k-accent);
}
.kl-detail-empty-title[b-6k34tc87jy] {
    margin: 0;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--k-text);
}
.kl-detail-empty-msg[b-6k34tc87jy] {
    margin: 0;
    max-inline-size: 44ch;
    color: var(--k-text-muted);
    font-size: 14px;
    line-height: 1.55;
}
/* _content/Kanine.Web/Components/Pages/EditEvent.razor.rz.scp.css */
/* R11 — Edit event (scheduling).
   The Location was a hydrate-only status line (.kl-ee-location-note) styled to look deliberately inert, because it
   could not be edited. It is a real <select> now (owner ask 2026-09-12), so it takes the ordinary .kf-select
   chrome every other editable field on this form uses and that rule is gone: keeping a dashed muted box around a
   live control would say "read-only" about a control that writes. */

/* The visibility consequence line — quiet by default, and it must stay legible in every brand mode. */
.kl-ee-visibility-note[b-46ybih957n] {
    margin: var(--k-space-2) 0 0 0;
    font-size: 12px;
    color: var(--k-text-muted);
}

/* Start / End date+time pairs sit side by side inside their field (the old Date-column/Time-column split made one
   instant zig-zag across two grid columns). */
.kl-ee-when-row[b-46ybih957n] {
    display: flex;
    gap: var(--k-space-2);
}

.kl-ee-when-row .kf-input[b-46ybih957n] {
    flex: 1 1 8rem;
    min-inline-size: 0;
}

/* The recurrence editor. It began as a calm hydrate-only status line, in the same treatment as the Location
   line, because the interactive switch was write-less. It is a real editor now. It is also the TAIL of the Start
   cell. EditEvent.razor states why it is not a third grid cell.

   THE MARGIN IS var(--k-space-2) BECAUSE .kl-ee-quickfill USES var(--k-space-2). Both cells of .kl-ee-grid open
   with a .kf-label and a .kl-ee-when-row of two inputs. .kf-field lays each cell out as a flex COLUMN with one
   shared gap. Give the two tails the same top margin, and they begin at the same offset inside their own cell.
   "Recurring event / Does not repeat" then occupies ONE band with the +1 / +3 / +8 buttons. Nothing here sums a
   height or measures dead space. If the Start cell grows, both tails move together, because the text above each
   tail is the same shape. This was var(--k-space-4) while the block was the grid's next SIBLING and owned a
   full-width row of its own (owner ruling 2026-09-15). */
.kl-ee-recurring[b-46ybih957n] {
    margin-block-start: var(--k-space-2);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2) var(--k-space-3);
}

/* The frequency select rides the -field family. That family carries margin-block-end: var(--k-space-4), so
   stacked form fields breathe. On ONE flex line that margin is not space between fields. It is 16px of phantom
   box. align-items centers MARGIN boxes, so the line measured 64px while every visible control in it measured
   48px or less. The select painted flush to the top of a box 16px too tall. Zeroing the margin makes the line
   48px. That is the exact height of .kl-ee-quickfill beside it, so the two tails match top and bottom. The rule
   is bounded to a DIRECT child. The fields inside .kl-ee-recur-detail keep the stacking margin they need. */
.kl-ee-recurring > .kl-ee-field[b-46ybih957n] {
    margin-block-end: 0;
}

.kl-ee-recurring-label[b-46ybih957n] {
    font-size: 13px;
    font-weight: 600;
    color: var(--k-text-muted);
}

.kl-ee-recurring-status[b-46ybih957n] {
    margin: 0;
    padding: var(--k-space-1) var(--k-space-3);
    color: var(--k-text-muted);
    font-size: 13px;
    font-style: italic;
    background: var(--k-surface-2);
    border: 1px dashed var(--k-border);
    border-radius: var(--k-radius-full);
}

/* Add-personnel row: the picker takes the room, Add sits beside it. */
.kl-ee-add-row[b-46ybih957n] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-2);
}

.kl-ee-add-picker[b-46ybih957n] {
    flex: 1 1 16rem;
    min-inline-size: 0;
}

/* Attendee rows: quiet bordered rows (the ul reset rides the foundation -list family), an initials avatar disc,
   and the identity pair; Remove rides the foundation -delete danger family. */
.kl-ee-attendee[b-46ybih957n] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
    padding: var(--k-space-2) var(--k-space-3);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface);
}

.kl-ee-attendee + .kl-ee-attendee[b-46ybih957n] {
    margin-block-start: var(--k-space-2);
}

.kl-ee-attendee-identity[b-46ybih957n] {
    display: flex;
    align-items: center;
    gap: var(--k-space-3);
    min-inline-size: 0;
}

.kl-ee-attendee-avatar[b-46ybih957n] {
    flex: 0 0 auto;
    inline-size: 32px;
    block-size: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--k-radius-full);
    background: color-mix(in srgb, var(--k-accent) 14%, var(--k-surface));
    color: var(--k-accent);
    font-size: 12px;
    font-weight: 700;
}

.kl-ee-attendee-handler[b-46ybih957n] {
    font-weight: 600;
    color: var(--k-text);
}

.kl-ee-attendee-dog[b-46ybih957n] {
    color: var(--k-text-muted);
    font-size: 13px;
}

/* The zone the date and time boxes on this form are typed in. Quiet: it qualifies the fields below it. */
.kl-ee-zone-note[b-46ybih957n] {
    margin: 0 0 var(--k-space-2) 0;
    font-size: 12px;
    color: var(--k-text-muted);
}

/* The end-time quick-fill row (owner ask). Scoped CSS never crosses components, so EventCreate carries the same
   rule under its own .kl-ee-quickfill — the two are deliberate twins. Wraps so three buttons never force a
   horizontal scroll at 320px, and every button keeps the A6 44px touch floor. */
.kl-ee-quickfill[b-46ybih957n] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin-block-start: var(--k-space-2);
}

.kl-ee-quickfill-btn[b-46ybih957n] {
    min-block-size: var(--k-touch);
    min-inline-size: var(--k-touch);
    flex: 0 1 auto;
}

/* The "off-site address was cleared" note (owner ask 2026-09-14). Deliberate twin of EventCreate.razor.css: scoped
   CSS never crosses components, so the same one-line rule has to exist on both surfaces. Type comes from the
   foundation `-note` family; this adds only the space under the Location field. */
.kl-ee-address-note[b-46ybih957n] {
    margin: var(--k-space-2) 0 0 0;
}
/* _content/Kanine.Web/Components/Pages/EntityManage.razor.rz.scp.css */
/* =============================================================================
   EntityManage (manage.html) — page-scoped styling for the PLAT-030 GENERIC,
   pack-agnostic entity management surface. The shared design system
   (kanine-design-system.css) gives the page shell (kl-page), the form atoms
   (kf-field / kf-label / kf-input), the buttons (kl-btn), the dialog primitive
   (kl-dialog) and the section head; this stylesheet adds ONLY the structure the
   system does NOT provide: the registered-entity catalog cards, the two-pane
   (list rail + detail) split (mirroring the signed-off CustomFields/OrgUnits),
   the selectable list rows, the Records/Registry tabs, the registry table, the
   governance badges, and the "Restricted" placeholder for a redacted field.

   Every colour resolves through --k-* tokens so the three modes (light / dark /
   outdoor) flip correctly (R11 token/canvas gate). NOTE: bare `html.dark .x` IS
   reachable from scoped CSS (the proven app-wide pattern; the old "cannot reach"
   claim here was false) — used below only where a fixed status colour needs the
   canonical dark remap; everything else stays token-driven.
   ========================================================================== */

.kl-section-head[b-6cquiw3uub] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--k-space-4);
}
.kl-section-head h1[b-6cquiw3uub] { margin: 0 0 var(--k-space-1); }
.kl-section-head .kl-muted[b-6cquiw3uub] { margin: 0; color: var(--k-text-muted); }
.kl-head-actions[b-6cquiw3uub] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-3);
    flex: 0 0 auto;
}
.kl-muted[b-6cquiw3uub] { color: var(--k-text-muted); }

/* ---- The registered-entity catalog (the /manage index): a responsive grid of
   linkable entity cards. Each card is a navy/teal-accented surface. ------------- */
.kl-em-catalog[b-6cquiw3uub] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: var(--k-space-4);
}
.kl-em-card[b-6cquiw3uub] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    padding: var(--k-space-4);
    text-decoration: none;
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-block-start: 2px solid color-mix(in srgb, var(--k-accent) 38%, var(--k-border));
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    transition: background-color var(--k-dur-1) var(--k-ease), border-color var(--k-dur-1) var(--k-ease);
}
.kl-em-card:hover[b-6cquiw3uub] { background: var(--k-surface-2); border-color: var(--k-outline); }
.kl-em-card:focus-visible[b-6cquiw3uub] { outline: 3px solid var(--k-focus); outline-offset: 2px; }
.kl-em-card-name[b-6cquiw3uub] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--k-text);
}
.kl-em-card-glyph[b-6cquiw3uub] { color: var(--k-accent); font-size: 16px; }
.kl-em-card-key[b-6cquiw3uub] { font-size: 12px; color: var(--k-text-muted); }
.kl-em-card-tags[b-6cquiw3uub] { display: flex; flex-wrap: wrap; gap: var(--k-space-2); margin-block-start: var(--k-space-1); }
.kl-em-tag[b-6cquiw3uub] {
    display: inline-flex;
    align-items: center;
    padding-block: 2px;
    padding-inline: var(--k-space-2);
    font-size: 11px;
    font-weight: 600;
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-full);
}
.kl-em-tag--registry[b-6cquiw3uub] {
    color: var(--k-accent);
    background: color-mix(in srgb, var(--k-accent) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-accent) 30%, var(--k-surface));
}

/* ---- Tabs: Records / Registry — a quiet underline-active tab strip. ------------ */
.kl-em-tabs[b-6cquiw3uub] {
    display: flex;
    gap: var(--k-space-2);
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 70%, transparent);
}
.kl-em-tab[b-6cquiw3uub] {
    appearance: none;
    min-block-size: var(--k-touch);
    padding-inline: var(--k-space-4);
    background: transparent;
    border: 0;
    border-block-end: 2px solid transparent;
    color: var(--k-text-muted);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}
.kl-em-tab:hover[b-6cquiw3uub] { color: var(--k-text); }
.kl-em-tab:focus-visible[b-6cquiw3uub] { outline: 3px solid var(--k-focus); outline-offset: 2px; border-radius: var(--k-radius-sm); }
.kl-em-tab--active[b-6cquiw3uub] { color: var(--k-accent); border-block-end-color: var(--k-accent); }

/* ---- Two-pane split (list rail + detail workspace) — the CustomFields idiom. --- */
.kl-split[b-6cquiw3uub] { display: flex; align-items: stretch; gap: var(--k-space-6); }
@media (max-width: 900px) { .kl-split[b-6cquiw3uub] { flex-direction: column; } }

.kl-list-pane[b-6cquiw3uub] {
    flex: 0 0 20rem;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    padding: var(--k-space-4);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}
@media (max-width: 900px) { .kl-list-pane[b-6cquiw3uub] { flex-basis: auto; } }
.kl-list-pane .kf-field[b-6cquiw3uub] { margin-block-end: 0; }

.kl-list[b-6cquiw3uub] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    /* B6: no reserved 18rem floor — an empty list sizes to its note, never a void. */
    overflow-y: auto;
}
.kl-list .kl-muted[b-6cquiw3uub] {
    margin: auto 0;
    padding: var(--k-space-6) var(--k-space-3);
    text-align: center;
    color: var(--k-text-muted);
}

.kl-list-item[b-6cquiw3uub] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    min-block-size: var(--k-touch);
    padding: var(--k-space-3);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    cursor: pointer;
    transition: background-color var(--k-dur-1) var(--k-ease), border-color var(--k-dur-1) var(--k-ease);
}
.kl-list-item:hover[b-6cquiw3uub] { background: var(--k-surface-2); border-color: var(--k-outline); }
.kl-list-item:focus-visible[b-6cquiw3uub] { outline: 3px solid var(--k-focus); outline-offset: 2px; }
.kl-list-item--selected[b-6cquiw3uub] {
    position: relative;
    background: color-mix(in srgb, var(--k-accent) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-accent) 30%, var(--k-surface));
}
.kl-list-item--selected[b-6cquiw3uub]::before {
    content: "";
    position: absolute;
    inset-block: 8px;
    inset-inline-start: 0;
    inline-size: 3px;
    border-radius: var(--k-radius-full);
    background: var(--k-accent);
}
.kl-list-item-key[b-6cquiw3uub] {
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 14px;
    color: var(--k-text);
}
.kl-list-item--selected .kl-list-item-key[b-6cquiw3uub] { color: var(--k-accent); font-weight: 600; }

/* ---- Governance tags: PII / Restricted (critical channel) — a tinted bordered
   pill on the page's OWN kl-em-tag base (never .kl-badge — that namespace is
   reserved for the canonical lifecycle RecordStatusBadge family). ---------------- */
.kl-em-tag--pii[b-6cquiw3uub] {
    flex: 0 0 auto;
    font-size: 10px;
    letter-spacing: .05em;
    text-transform: uppercase;
    line-height: 1.4;
    white-space: nowrap;
    color: var(--k-critical);
    background: color-mix(in srgb, var(--k-critical) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-critical) 34%, var(--k-surface));
}

/* Canonical dark status text (the status constants do not flip; E.20). */
html.dark .kl-em-tag--pii[b-6cquiw3uub] { color: #f6ab9d; }

/* ---- Right pane: the create/edit/detail workspace. ----------------------------- */
.kl-detail-pane[b-6cquiw3uub] {
    flex: 1 1 0;
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    padding: var(--k-space-6);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-block-start: 2px solid color-mix(in srgb, var(--k-accent) 38%, var(--k-border));
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}
.kl-section-title[b-6cquiw3uub] {
    margin: 0;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -.005em;
    color: var(--k-text);
}

.kl-form-grid[b-6cquiw3uub] { display: flex; flex-direction: column; gap: var(--k-space-4); }
.kl-form-grid .kf-field[b-6cquiw3uub] { margin-block-end: 0; }
.kf-field .kl-em-tag[b-6cquiw3uub] { margin-inline-start: var(--k-space-2); }

.kl-form-actions[b-6cquiw3uub] {
    display: flex;
    justify-content: flex-end;
    gap: var(--k-space-3);
    margin-block-start: var(--k-space-2);
    padding-block-start: var(--k-space-6);
    border-block-start: 1px solid color-mix(in srgb, var(--k-border) 70%, transparent);
}
.kl-error[b-6cquiw3uub] { margin: 0; color: var(--k-critical); font-size: 0.9rem; }

/* ---- The "Restricted" placeholder for a redacted (gated) field value. ---------- */
.kf-readonly[b-6cquiw3uub],
.kl-em-restricted[b-6cquiw3uub] {
    padding: var(--k-space-3);
    color: var(--k-text-muted);
    font-size: 14px;
    font-style: italic;
    background: var(--k-surface-2);
    border: 1px dashed var(--k-border);
    border-radius: var(--k-radius-md);
}

/* ---- Read-only detail list (a selected row, not in edit). ----------------------- */
.kl-em-detail-list[b-6cquiw3uub] { display: flex; flex-direction: column; gap: var(--k-space-3); margin: 0; }
.kl-em-detail-row[b-6cquiw3uub] { display: flex; flex-direction: column; gap: 2px; }
.kl-em-detail-row dt[b-6cquiw3uub] { font-size: 12px; font-weight: 600; color: var(--k-text-muted); }
.kl-em-detail-row dd[b-6cquiw3uub] { margin: 0; color: var(--k-text); }
.kl-em-detail-row dd.kl-em-restricted[b-6cquiw3uub] { display: inline-block; padding: 2px var(--k-space-2); }

/* ---- Registry table (the reusable/master master-record browser). ---------------- */
.kl-em-registry[b-6cquiw3uub] { display: flex; flex-direction: column; gap: var(--k-space-4); }
.kl-em-table[b-6cquiw3uub] { inline-size: 100%; border-collapse: collapse; }
.kl-em-table th[b-6cquiw3uub], .kl-em-table td[b-6cquiw3uub] {
    padding: var(--k-space-3);
    text-align: start;
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 70%, transparent);
    color: var(--k-text);
}
.kl-em-table th[b-6cquiw3uub] { font-size: 12px; font-weight: 600; color: var(--k-text-muted); }
.kl-em-td-name[b-6cquiw3uub] { font-weight: 600; }
.kl-em-td-attrs[b-6cquiw3uub] { color: var(--k-text-muted); font-size: 13px; }
.kl-em-th-actions[b-6cquiw3uub], .kl-em-td-actions[b-6cquiw3uub] { text-align: end; white-space: nowrap; }

/* A compact ghost button for the per-row registry action. */
.kl-btn--sm[b-6cquiw3uub] { min-block-size: 32px; padding-inline: var(--k-space-3); font-size: 13px; }

/* ---- Detail-pane empty state (composed, not a void) — the CustomFields caliber. - */
.kl-detail-empty[b-6cquiw3uub] {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: var(--k-space-3);
    min-block-size: 18rem;
    padding: var(--k-space-8) var(--k-space-6);
}
.kl-detail-empty-disc[b-6cquiw3uub] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 64px;
    block-size: 64px;
    margin-block-end: var(--k-space-1);
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    color: var(--k-accent);
}
.kl-detail-empty-title[b-6cquiw3uub] {
    margin: 0;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--k-text);
}
.kl-detail-empty-msg[b-6cquiw3uub] {
    margin: 0;
    max-inline-size: 44ch;
    color: var(--k-text-muted);
    font-size: 14px;
    line-height: 1.55;
}
/* _content/Kanine.Web/Components/Pages/Error.razor.rz.scp.css */
/* UI-GUAR-003 / R3 + R11 — scoped styling for the prototype error card (ProposedUI/pages/error.html), mapped onto the
   kl-* / kf-* design tokens (restrained-premium register). The button APPEARANCE comes from the global .kl-btn /
   .kl-btn--primary / .kl-btn--ghost rules; this scoped sheet only owns the centered card, the critical-toned icon,
   the heading/lead type, the diagnostic block, and the action row. Logical properties throughout (zero horizontal
   overflow 320px to 1920px). */

.kl-err-wrap[b-kl37zgobmu] {
    display: flex;
    align-items: center;
    justify-content: center;
    min-block-size: 70vh;
    padding: var(--k-space-6);
}

.kl-err-card[b-kl37zgobmu] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    inline-size: 100%;
    max-inline-size: 42rem;
    box-sizing: border-box;
    padding: var(--k-space-8, 32px);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}

/* Critical-toned status mark — a soft critical container with a ring, matching the prototype error icon. */
.kl-err-icon[b-kl37zgobmu] {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 4rem;
    block-size: 4rem;
    margin-block-end: var(--k-space-6, 24px);
    border-radius: var(--k-radius-full);
    background: color-mix(in srgb, var(--k-critical) 12%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-critical) 30%, transparent);
}

.kl-err-icon-glyph[b-kl37zgobmu] {
    /* No font-family/weight here — the .ki icon face must win (a scoped font-family out-specified it and
       rendered the glyph codepoint as tofu). */
    color: var(--k-critical);
    font-size: 28px;
    line-height: 1;
}

.kl-err-title[b-kl37zgobmu] {
    margin: 0 0 var(--k-space-4);
    font-family: var(--k-font-display, inherit);
    font-size: clamp(24px, 4vw, 32px);
    font-weight: 800;
    line-height: 1.2;
    color: var(--k-text);
}

.kl-err-lead[b-kl37zgobmu] {
    margin: 0 0 var(--k-space-8, 32px);
    max-inline-size: 34rem;
    font-size: 16px;
    line-height: 1.55;
    color: var(--k-text-muted);
}

/* Diagnostic block — the preserved Request ID surface. */
.kl-err-diag[b-kl37zgobmu] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--k-space-1);
    inline-size: 100%;
    box-sizing: border-box;
    margin-block-end: var(--k-space-8, 32px);
    padding: var(--k-space-4);
    background: var(--k-bg);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-sm);
}

.kl-err-diag-label[b-kl37zgobmu] {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

.kl-err-diag-code[b-kl37zgobmu] {
    font-family: var(--k-font-mono, ui-monospace, monospace);
    font-size: 13px;
    color: var(--k-text);
    word-break: break-all;
}

/* Action row — stacks on narrow widths, side-by-side on wider. */
.kl-err-actions[b-kl37zgobmu] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    inline-size: 100%;
    justify-content: center;
}

.kl-err-action[b-kl37zgobmu] {
    min-inline-size: 12.5rem;
}

@media (min-width: 480px) {
    .kl-err-actions[b-kl37zgobmu] {
        flex-direction: row;
    }

    .kl-err-action[b-kl37zgobmu] {
        flex: 0 1 auto;
    }
}
/* _content/Kanine.Web/Components/Pages/EventCreate.razor.rz.scp.css */
/* R11 — Event create (scheduling). EventCreate deliberately shares the kl-ee-* vocabulary with EditEvent via the
   GLOBAL shims (kl-ee-card / kl-ee-crumb in the design system) — this scoped sheet adds ONLY what the shims do not
   provide: the Start/End date+time pairing row (scoped CSS never crosses components, so EditEvent's when-row rule
   cannot reach here). Tokens only; flips per brand mode. */
.kl-ce-when-row[b-ewrghuppgi] {
    display: flex;
    gap: var(--k-space-2);
}

.kl-ce-when-row .kf-input[b-ewrghuppgi] {
    flex: 1 1 8rem;
    min-inline-size: 0;
}

/* The zone the date and time boxes on this form are typed in. Quiet: it qualifies the fields below it. */
.kl-ee-zone-note[b-ewrghuppgi] {
    margin: 0 0 var(--k-space-2) 0;
    font-size: 12px;
    color: var(--k-text-muted);
}

/* The end-time quick-fill row (owner ask). Scoped CSS never crosses components, so EditEvent carries the same
   rule under its own .kl-ee-quickfill — the two are deliberate twins (the ARITHMETIC is shared and tested; these
   few CSS lines are not, so a change to one must be made to the other by hand). Wraps so
   three buttons never force a horizontal scroll at 320px, and every button keeps the A6 44px touch floor. */
.kl-ee-quickfill[b-ewrghuppgi] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin-block-start: var(--k-space-2);
}

.kl-ee-quickfill-btn[b-ewrghuppgi] {
    min-block-size: var(--k-touch);
    min-inline-size: var(--k-touch);
    flex: 0 1 auto;
}

/* The "off-site address was cleared" note (owner ask 2026-09-14). It takes its whole type register from the
   foundation `-note` family (13px, muted) — the same register the conflict note beside it reads in — and adds only
   the space it needs to sit under the Location field instead of against it. Deliberately NOT an error colour: the
   clear is a correct consequence of the venue the reader just chose, and painting it red would read as a fault. */
.kl-ee-address-note[b-ewrghuppgi] {
    margin: var(--k-space-2) 0 0 0;
}
/* _content/Kanine.Web/Components/Pages/FeedbackTriage.razor.rz.scp.css */
/* Phase-B WP6 — the /feedback triage queue + detail drawer. Scoped CSS also gives this page a b-scope,
   self-demonstrating the WP1 map (regenerate kanine-scope-map.json when this file changes composition). */

.kl-feedback-triage .kl-feedback-egress-label[b-08ip9qfmq7] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
    color: var(--k-text-muted);
}

.kl-feedback-triage tbody tr[b-08ip9qfmq7] {
    cursor: pointer;
}

/* Phase G WP-G2 — the .ksb status-bundle import. ::deep reaches the <InputFile> component's native input
   (CSS isolation doesn't stamp the scope onto a child component's output); the wrapping <label> still opens
   the picker while the input is display:none — the board's .kfb import idiom. */
.kl-feedback-import-label[b-08ip9qfmq7] {
    cursor: pointer;
}

.kl-feedback-import-label[b-08ip9qfmq7]  .kl-feedback-import-input {
    display: none;
}

/* Phase G R1 — the read-only operator-mirror chip. RETARGETED 2026-09-13, and dead before that: it was written
   as `.kl-feedback-review .kl-feedback-mirror-chip`, and `.kl-feedback-review` is the ROOT of a different
   component, so this page's scope attribute never landed on it. The chip now lives in this page's own detail
   header (the surface stopped repeating the identity chips), so the selector points at markup this file really
   declares and the rule applies for the first time. The publicnote rule that sat beside it was dead for the same
   reason and moved to FeedbackReviewSurface.razor.css, beside the element it styles. */
.kl-feedback-detail-head-main .kl-feedback-mirror-chip[b-08ip9qfmq7] {
    vertical-align: middle;
}

.kl-feedback-detail-panel[b-08ip9qfmq7] {
    width: min(560px, 92vw);
    /* NO block cap here. `max-height: 100vh` used to sit on this line. The overlay reserves
       `var(--k-space-4)` top AND bottom, so 100vh is 2 * --k-space-4 MORE than the space the
       panel is given, at every viewport. It was latent (the -full rule below always won it) and
       it is deleted rather than corrected: .kl-dialog §5i already declares the one right budget,
       `calc(100dvh - 2 * var(--k-space-4))`, and a page that restates it can only drift from it.
       `max-height` and `max-block-size` are the SAME cascaded property in horizontal-tb, so a
       page declaration does not combine with the shared cap — it REPLACES it. */
    overflow-y: auto;
    padding: 1.25rem;
}

/* Full-screen detail (owner-directed 2026-07-09) — defeats the 30rem .kl-dialog clamp + the 560px panel width. */
.kl-feedback-detail-full[b-08ip9qfmq7] {
    max-inline-size: none;
    width: min(900px, 96vw);
    /* The block cap is INHERITED from .kl-dialog (§5i): `calc(100dvh - 2 * var(--k-space-4))`.
       This rule declared `max-height: 92vh` from 2026-07-09, FIFTEEN DAYS BEFORE the shared cap
       existed (219a2253, 2026-07-24) — so it was never an opt-out from the shared cap, it was a
       per-page guess at the same intent. Measured 2026-09-13 at 1400x900 / 393x852 / 780x360 it
       was wrong in BOTH directions: 40px SHORTER than the panel is allowed on a desk, and 3.19px
       TALLER than it is allowed at 780x360 (a phone held sideways), because N vh exceeds
       `100vh - 2 * --k-space-4` on any viewport under `2 * --k-space-4 / (1 - N)` px. */
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}

.kl-feedback-detail-head-full[b-08ip9qfmq7] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.8rem 1.2rem;
    border-bottom: 1px solid var(--k-border, #e2e6ec);
    flex: 0 0 auto;
}

.kl-feedback-detail-head-main[b-08ip9qfmq7] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    min-inline-size: 0;
}

.kl-feedback-detail-head-actions[b-08ip9qfmq7] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 0 auto;
    flex-wrap: wrap;
}

.kl-feedback-rescind-confirm-wrap[b-08ip9qfmq7] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
}

.kl-feedback-detail-body[b-08ip9qfmq7] {
    padding: 1rem 1.25rem 1.4rem;
    overflow-y: auto;
    flex: 1 1 auto;
}

/* MOVED OUT 2026-09-13 — every `.kl-feedback-review-*` rule that used to sit here now lives in
   Components/Feedback/FeedbackReviewSurface.razor.css, beside the component that renders that markup.

   They were DEAD here. Blazor stamps this page's scope attribute (`b-08ip9qfmq7`) onto the markup declared in
   THIS file only, and `.kl-feedback-review-dl` is rendered by FeedbackReviewSurface — a different component,
   which never carries this page's attribute. So the compiled `.kl-feedback-review-dl[b-08ip9qfmq7]` matched
   nothing, and the whole detail body rendered with browser-default definition-list styling. Probed live before
   the move: the <dl> had a `class` attribute and no scope attribute, and computed `display: block` against a
   sheet that asked for `display: grid`.

   `.kl-feedback-review-editor` was dropped rather than moved: the bless editor it styled was removed by the
   owner's 2026-07-09 ruling and no element has carried that class since. */

/* Empty-state title + message (the EvidenceVault kl-ev-empty-* idiom; the two <p>s previously
   rendered unstyled — TEST-EFFICACY A1 unstyled-element finding). */
.kl-approvals-empty-title[b-08ip9qfmq7] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--k-text);
}

.kl-approvals-empty-message[b-08ip9qfmq7] {
    margin: 0;
    max-width: 46ch;
    color: var(--k-text-muted);
}

/* Phase G WP-G6 — the admin step-up queue + manifest review + "shipped with data" chips. */
.kl-feedback-stepup-queue[b-08ip9qfmq7] {
    margin: 0 0 1rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--k-border);
    border-left: 4px solid var(--k-accent, #2f6feb);
    border-radius: 8px;
}

.kl-feedback-stepup-queue h2[b-08ip9qfmq7] {
    font-size: 1rem;
    margin: 0 0 0.5rem;
}

.kl-feedback-stepup-card[b-08ip9qfmq7] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.45rem 0;
    border-top: 1px solid var(--k-border);
}

.kl-feedback-stepup-dialog[b-08ip9qfmq7] {
    max-inline-size: none;   /* defeat the .kl-dialog 30rem clamp */
    width: min(760px, 94vw);
    /* The block cap is INHERITED from .kl-dialog (5i), exactly as the detail panel above inherits it.
       This rule declared `max-height: 90vh` and D56-R handed it back as "exactly on the boundary": at a
       320px viewport 90vh is 288px, which is the reserve the overlay leaves to the pixel. It passed the
       guard on equality alone.

       Equality is not the same as correctness, and two facts settle it against keeping the line.

       FIRST, this element carries `kl-dialog`, and `max-height` and `max-block-size` are the SAME cascaded
       property in horizontal-tb. A page declaration therefore REPLACES the shared cap instead of combining
       with it. So `90vh` was not a second opinion beside the shared budget - it was the whole budget, and
       the shared one never applied here at all.

       SECOND, the shared cap is `dvh` and this was `vh`. On a phone `vh` measures the viewport as if the
       browser chrome were retracted, so 90vh can exceed the space that actually exists while still reading
       as 90 percent. The `dvh` line in the shared rule exists precisely for that, and restating the cap in
       `vh` opted this panel out of it.

       Inheriting also removes the standing hazard D56-R named: a change to `--k-space-4` moves the reserve
       and leaves a hard-coded 90vh on the wrong side of it, silently. */
    padding: 1.25rem;
}

.kl-feedback-stepup-note[b-08ip9qfmq7] {
    font-size: 0.85rem;
    color: var(--k-text-muted);
}

.kl-feedback-stepup-actions[b-08ip9qfmq7] {
    display: flex;
    gap: 0.5rem;
}

.kl-feedback-shipped[b-08ip9qfmq7] {
    margin-bottom: 0.6rem;
}

.kl-feedback-shipped-chip[b-08ip9qfmq7] {
    background: color-mix(in srgb, #8250df 16%, transparent);
    color: #8250df;
    font-weight: 600;
}
/* _content/Kanine.Web/Components/Pages/Home.razor.rz.scp.css */
/* =============================================================================
   Home — Lovable refresh (BRANCH EXPERIMENT: design/home-lovable-refresh)
   -----------------------------------------------------------------------------
   The designer's two-pane dashboard layout (premium cards, ambient accents, calm
   motion) remapped onto OUR navy + signal-teal --k-* palette. Every icon rule is mapped
   back to the FontAwesome .ki glyph font (font-size + colour), NOT the export's
   placeholder squares. The tight spacing + softer radii come from the home-scoped token
   block in kanine-redesign.css (.kl-shell-main:has(.kl-home-dash)). This REPLACES the
   prior R11 Home scoped sheet on this branch; `git checkout main -- <this file>` reverts.
   ========================================================================== */

/* ---- Welcome header: gradient wordmark ---- */
.kl-shell-main > h1[b-dp2nzm2qgc] {
  font-size: clamp(28px, 3.2vw, 40px);
  font-weight: 800; line-height: 1.05; letter-spacing: -0.02em;
  background: linear-gradient(180deg, var(--k-text), color-mix(in oklab, var(--k-text) 68%, var(--k-accent)));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
[data-testid="home-welcome"][b-dp2nzm2qgc] { color: var(--k-text-muted); font-size: 15px; margin: var(--k-space-4) 0 0; }
[data-testid="home-welcome"] strong[b-dp2nzm2qgc] {
  color: var(--k-accent); font-family: var(--k-font-mono); font-size: 12px; font-weight: 600;
  letter-spacing: .04em; padding: 1px 8px; margin-left: 4px;
  border-radius: var(--k-radius-sm);
  background: color-mix(in oklab, var(--k-accent) 14%, transparent);
}

/* ---- Signed-out sign-in CTA (owner 2026-07-06: welcome + ONE primary sign-in button, nothing else) ---- */
.kl-home-signin[b-dp2nzm2qgc] { margin-block-start: var(--k-space-6); }

/* ---- Two-pane dashboard ---- */
.kl-home-dash[b-dp2nzm2qgc] {
  display: grid; grid-template-columns: minmax(0,1fr) 380px; gap: var(--k-space-9);
  margin-block-start: var(--k-space-10);
}
/* Setup checklist tile placement: the card TOPS the Readiness column (col 2, auto row 1); Operations
   explicitly spans both rows of col 1; the Readiness aside auto-flows into col 2's next row. When the
   checklist is absent (done / skipped / non-admin) the aside auto-places straight into row 1 — no gap. */
.kl-home-dash > .kl-home-setup[b-dp2nzm2qgc] { grid-column: 2; align-self: start; }
.kl-home-pane--operations[b-dp2nzm2qgc] { grid-column: 1; grid-row: 1 / span 2; }
.kl-home-pane--readiness[b-dp2nzm2qgc] { grid-column: 2; }
@media (max-width: 1100px) {
  .kl-home-dash[b-dp2nzm2qgc] { grid-template-columns: 1fr; }
  /* Single column: everything stacks in DOM order — the setup checklist (first child) leads the page. */
  .kl-home-dash > .kl-home-setup[b-dp2nzm2qgc], .kl-home-pane--readiness[b-dp2nzm2qgc] { grid-column: 1; }
  .kl-home-pane--operations[b-dp2nzm2qgc] { grid-column: 1; grid-row: auto; }
}
.kl-home-pane[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: var(--k-space-7); min-width: 0; }
.kl-home-pane-head[b-dp2nzm2qgc] {
  display: flex; align-items: center; gap: var(--k-space-4);
  padding-bottom: var(--k-space-5); border-bottom: 1px solid var(--k-border);
}
.kl-home-pane-icon[b-dp2nzm2qgc] { color: var(--k-accent); font-size: 18px; }
.kl-home-pane-title[b-dp2nzm2qgc] {
  margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .22em;
  text-transform: uppercase; color: var(--k-text-muted);
}
.kl-home-pane--operations .kl-home-pane-title[b-dp2nzm2qgc] { color: var(--k-accent); }

/* Task4 (owner 2026-07-23): the compact "Weather unavailable" badge that replaces the full weather card in the
   genuine unavailable/error state, sharing the Readiness header row instead of a mostly-empty card below it.
   margin-inline-start:auto right-aligns it using the row's own flex layout (the same pattern .kl-home-card-title
   and .kl-count already use), never a fixed offset. */
.kl-home-pane-head-badge[b-dp2nzm2qgc] {
  margin-inline-start: auto; flex-shrink: 0;
  font-family: var(--k-font-mono); font-size: 11px; font-weight: 600; letter-spacing: .02em;
  color: var(--k-text-muted); white-space: nowrap;
  padding: 3px 10px; border-radius: var(--k-radius-full); border: 1px dashed var(--k-outline);
}

.kl-home-widget[b-dp2nzm2qgc] { min-width: 0; }
.kl-home-actionreq[b-dp2nzm2qgc] { display: grid; grid-template-columns: 1fr; gap: var(--k-space-7); }

/* ---- Generic card ---- */
.kl-home-card[b-dp2nzm2qgc] {
  position: relative; overflow: hidden;
  background: var(--k-surface); border: 1px solid var(--k-border);
  border-radius: var(--k-radius-lg); padding: var(--k-space-7); box-shadow: var(--k-elev-1);
}
.kl-home-card-head[b-dp2nzm2qgc] { display: flex; align-items: center; gap: var(--k-space-4); margin-bottom: var(--k-space-6); }
.kl-home-card-icon[b-dp2nzm2qgc] { font-size: 16px; color: var(--k-text-muted); }
.kl-home-card-icon--critical[b-dp2nzm2qgc] { color: var(--k-critical); }
.kl-home-card-icon--caution[b-dp2nzm2qgc] { color: var(--k-caution); }
.kl-home-card-title[b-dp2nzm2qgc] { margin: 0 auto 0 0; font-family: var(--k-font-display); font-size: 15px; font-weight: 700; color: var(--k-text); }
.kl-home-card-body[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: var(--k-space-5); color: var(--k-text); }
.kl-home-empty[b-dp2nzm2qgc] { margin: 0; color: var(--k-text-muted); font-size: 14px; }
.kl-home-card-head .kl-count[b-dp2nzm2qgc] { margin-inline-start: auto; }

/* ---- Mock-flag chip (hatched, restrained — marks not-yet-wired sample data) ---- */
.kl-mock-chip[b-dp2nzm2qgc] {
  margin-inline-start: auto;
  font-family: var(--k-font-mono); font-size: 10px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; padding: 2px 6px; border-radius: 4px; white-space: nowrap;
  color: var(--k-text-muted); border: 1px dashed var(--k-outline);
  background: repeating-linear-gradient(-45deg,
     color-mix(in oklab, var(--k-outline) 16%, transparent) 0 6px, transparent 6px 12px);
}

/* ---- Quick actions ---- */
/* auto-fit so the grid seats 5 tiles (Log Medical joined when the duplicate top link rail retired). */
.kl-home-quickgrid[b-dp2nzm2qgc] { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--k-space-5); }
@media (max-width: 700px) { .kl-home-quickgrid[b-dp2nzm2qgc] { grid-template-columns: repeat(2,1fr); } }
.kl-home-qa[b-dp2nzm2qgc] {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between;
  gap: var(--k-space-8); min-height: 120px; padding: var(--k-space-7);
  background: var(--k-surface); border: 1px solid var(--k-border); border-radius: var(--k-radius-lg);
  color: var(--k-text); text-decoration: none; box-shadow: var(--k-elev-1);
  transition: transform .15s, border-color .15s, box-shadow .15s;
}
.kl-home-qa[b-dp2nzm2qgc]::after {
  content: "→"; position: absolute; right: var(--k-space-7); bottom: var(--k-space-6);
  font-family: var(--k-font-mono); color: var(--k-text-muted); transition: transform .2s, color .2s;
}
.kl-home-qa:hover[b-dp2nzm2qgc] { border-color: var(--k-accent); transform: translateY(-2px); box-shadow: var(--k-elev-2); }
.kl-home-qa:hover[b-dp2nzm2qgc]::after { transform: translateX(4px); color: var(--k-accent); }
.kl-home-qa .ki[b-dp2nzm2qgc] { font-size: 26px; color: var(--k-accent); }
/* Cap the label short of the absolute → arrow's slot so a long label wraps instead of colliding with it
   (the "New Record," comma-look). */
.kl-home-qa-label[b-dp2nzm2qgc] { font-family: var(--k-font-display); font-weight: 700; font-size: 16px; max-inline-size: calc(100% - 28px); }
/* Featured action — an ACCENT card, NOT a saturated fill. A barely-tinted teal surface +
   a teal hairline + ONE contained teal icon badge: the brand pop lives in the badge, so the
   tile reads as primary without the blinding block. Every channel is token-based, so it holds
   in light + dark (no bright fill in either). */
.kl-home-qa--primary[b-dp2nzm2qgc] {
  color: var(--k-text);
  background: color-mix(in oklab, var(--k-accent) 8%, var(--k-surface));
  border-color: color-mix(in oklab, var(--k-accent) 45%, var(--k-border));
}
.kl-home-qa--primary:hover[b-dp2nzm2qgc] {
  border-color: var(--k-accent);
  background: color-mix(in oklab, var(--k-accent) 12%, var(--k-surface));
  box-shadow: var(--k-elev-2);
}
.kl-home-qa--primary .ki[b-dp2nzm2qgc] {
  color: var(--k-on-accent);
  background: var(--k-accent);
  padding: 8px;
  border-radius: var(--k-radius-md);
  box-shadow: 0 6px 16px -8px color-mix(in oklab, var(--k-accent) 65%, transparent);
}
.kl-home-qa--primary .kl-home-qa-label[b-dp2nzm2qgc] { color: var(--k-accent); }
.kl-home-qa--primary[b-dp2nzm2qgc]::after { color: var(--k-accent); }

/* ---- Needs rework ---- */
[data-widget="needs-rework"][b-dp2nzm2qgc] { border-left: 3px solid var(--k-critical); }
.kl-home-rework-row[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: 4px; }
.kl-home-rework-top[b-dp2nzm2qgc] { display: flex; align-items: center; justify-content: space-between; gap: var(--k-space-5); }
.kl-home-rework-id[b-dp2nzm2qgc] { font-size: 13px; font-weight: 600; color: var(--k-text); }
.kl-home-rework-when[b-dp2nzm2qgc] { font-family: var(--k-font-mono); font-size: 12px; color: var(--k-text-muted); }
.kl-home-rework-issue[b-dp2nzm2qgc] { margin: 0; font-weight: 600; color: var(--k-critical); }
.kl-home-rework-note[b-dp2nzm2qgc] { margin: 2px 0 0; font-size: 13px; font-style: italic; color: var(--k-text-muted); }

/* ---- System clock ---- */
.kl-home-clock[b-dp2nzm2qgc] {
  display: flex; align-items: stretch; gap: var(--k-space-7);
  background: radial-gradient(80% 120% at 100% 0%, color-mix(in oklab, var(--k-accent) 14%, transparent), transparent 60%), var(--k-surface);
}
.kl-home-clock-rail[b-dp2nzm2qgc] { width: 4px; flex-shrink: 0; border-radius: var(--k-radius-full); background: linear-gradient(180deg, var(--k-accent), var(--k-accent-bright)); }
.kl-home-clock-body[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: 4px; flex: 1; }
.kl-home-clock-eyebrow[b-dp2nzm2qgc] { display: inline-flex; align-items: center; gap: var(--k-space-3); font-family: var(--k-font-mono); font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--k-text-muted); }
.kl-home-dot[b-dp2nzm2qgc] {
  width: 8px; height: 8px; border-radius: 50%; background: var(--k-success);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--k-success) 25%, transparent);
  animation: k-home-pulse-b-dp2nzm2qgc 2s ease-in-out infinite;
}
@keyframes k-home-pulse-b-dp2nzm2qgc {
  0%,100% { box-shadow: 0 0 0 3px color-mix(in oklab, var(--k-success) 25%, transparent); }
  50%     { box-shadow: 0 0 0 6px color-mix(in oklab, var(--k-success) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .kl-home-dot[b-dp2nzm2qgc] { animation: none; } }
.kl-home-clock-time[b-dp2nzm2qgc] { font-family: var(--k-font-mono); font-size: 32px; font-weight: 600; letter-spacing: -.02em; line-height: 1.05; color: var(--k-text); }
.kl-home-clock-date[b-dp2nzm2qgc] { font-size: 13px; color: var(--k-text-muted); }
/* The zone caption: quiet, but always present — an unlabelled hour reads as the viewer's own local time. */
.kl-home-clock-zone[b-dp2nzm2qgc] { font-size: 11px; letter-spacing: .08em; color: var(--k-text-muted); }
/* The unset-zone hint's call to action (owner request 2026-07-24). Inline text inside a sentence, so WCAG 2.5.8's
   inline exception applies and it deliberately gets NO 44px box — nothing around it changes size. It only has to
   read as a link: accent colour + a permanent underline, since the surrounding text is already low-contrast and
   colour alone must never be the only cue (WCAG 1.4.1). */
.kl-home-clock-zone-link[b-dp2nzm2qgc] {
  color: var(--k-accent-bright, var(--k-accent));
  text-decoration: underline;
  text-underline-offset: 2px;
}
.kl-home-clock-zone-link:hover[b-dp2nzm2qgc] { color: var(--k-accent); }
.kl-home-clock-zone-link:focus-visible[b-dp2nzm2qgc] {
  outline: 2px solid var(--k-accent-bright, var(--k-accent));
  outline-offset: 2px;
  border-radius: var(--k-radius-sm);
}
.kl-home-clock .kl-mock-chip[b-dp2nzm2qgc] { margin-inline-start: 0; }

/* ---- Weather ---- */
.kl-home-weather[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: var(--k-space-6); }
.kl-home-weather-now[b-dp2nzm2qgc] { display: flex; align-items: center; gap: var(--k-space-5); }
.kl-home-weather-icon[b-dp2nzm2qgc] { font-size: 30px; color: var(--k-accent); }
.kl-home-weather-temp[b-dp2nzm2qgc] { font-family: var(--k-font-display); font-weight: 700; font-size: 28px; color: var(--k-text); margin-right: auto; }
.kl-home-weather-hours[b-dp2nzm2qgc] { display: grid; grid-template-columns: repeat(3,1fr); gap: var(--k-space-4); padding: var(--k-space-5); background: var(--k-surface-2); border: 1px solid var(--k-border); border-radius: var(--k-radius-md); }
.kl-home-weather-hour[b-dp2nzm2qgc] { display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 12px; }
.kl-home-weather-h[b-dp2nzm2qgc] { font-family: var(--k-font-mono); font-size: 10px; letter-spacing: .08em; color: var(--k-text-muted); }
.kl-home-weather-p[b-dp2nzm2qgc] { font-family: var(--k-font-mono); font-size: 11px; color: var(--k-info); }
.kl-home-weather-meta[b-dp2nzm2qgc] { display: flex; gap: var(--k-space-7); font-size: 12px; color: var(--k-text-muted); }
.kl-home-weather-meta span[b-dp2nzm2qgc] { display: inline-flex; align-items: center; gap: 6px; }
.kl-home-weather-meta .ki[b-dp2nzm2qgc] { font-size: 14px; color: var(--k-accent); }

/* ---- My K9 ---- */
.kl-home-k9[b-dp2nzm2qgc] { padding: 0; overflow: hidden; }
.kl-home-k9-banner[b-dp2nzm2qgc] {
  display: flex; align-items: center; gap: var(--k-space-5); padding: var(--k-space-7);
  border-bottom: 1px solid var(--k-border);
  background:
    radial-gradient(80% 200% at 0% 0%, color-mix(in oklab, var(--k-accent) 18%, transparent), transparent 60%),
    linear-gradient(135deg, color-mix(in oklab, var(--k-accent) 14%, var(--k-surface-2)), var(--k-surface-2));
}
.kl-home-k9-avatar[b-dp2nzm2qgc] {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: var(--k-radius-full);
  background: color-mix(in oklab, var(--k-accent) 18%, var(--k-surface));
  color: var(--k-accent); font-size: 22px;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--k-accent) 16%, transparent);
}
.kl-home-k9-id[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: 2px; margin-right: auto; }
.kl-home-k9-name[b-dp2nzm2qgc] { margin: 0; font-size: 18px; font-weight: 700; }
.kl-home-k9-rows[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: var(--k-space-3); padding: var(--k-space-5) var(--k-space-7) var(--k-space-7); }
/* Next Cert / Last Med read as tidy mini-cards with clear left/right padding (were flush, dashed-separated). */
.kl-home-k9-row[b-dp2nzm2qgc] { display: flex; align-items: center; justify-content: space-between; gap: var(--k-space-4); padding: var(--k-space-4) var(--k-space-5); background: var(--k-surface-2); border: 1px solid var(--k-border); border-radius: var(--k-radius-sm); font-size: 13px; }
.kl-home-k9-key[b-dp2nzm2qgc] { color: var(--k-text-muted); }
/* width:100% + border-box (see .kl-btn) so View Profile ends inside the card's right padding, never clipped. */
.kl-home-k9-action[b-dp2nzm2qgc] { margin-top: var(--k-space-2); width: 100%; box-sizing: border-box; }

/* ---- Pass-on ---- */
.kl-home-passon-list[b-dp2nzm2qgc] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--k-space-3); }
.kl-home-passon-row[b-dp2nzm2qgc] {
  background: var(--k-surface-2);
  border: 1px solid var(--k-border); border-left: 3px solid transparent; border-radius: var(--k-radius-md);
  transition: background-color .12s, border-color .12s;
}
.kl-home-passon-row:hover[b-dp2nzm2qgc] { background: var(--k-surface-3); }
.kl-home-passon-row--unread[b-dp2nzm2qgc] { border-left-color: var(--k-info); }
/* The whole row is the link (deep-links its message in the inbox, ?msg=…); the anchor carries the row padding so
   the click target == the visible row, and the hover echoes kl-home-event-row (surface shift + accent subject).
   The descendant selector out-specifies the foundation `.kl-shell-main a:not([class*="-btn"])` teal-anchor rule. */
.kl-home-passon-row .kl-home-passon-link[b-dp2nzm2qgc] { display: block; padding: var(--k-space-5); color: inherit; text-decoration: none; border-radius: inherit; }
.kl-home-passon-row:hover .kl-home-passon-subj[b-dp2nzm2qgc] { color: var(--k-accent); }
.kl-home-passon-top[b-dp2nzm2qgc] { display: flex; align-items: baseline; justify-content: space-between; gap: var(--k-space-4); margin-bottom: 2px; }
.kl-home-passon-subj[b-dp2nzm2qgc] { font-size: 13px; font-weight: 600; color: var(--k-text); transition: color .12s; }
.kl-home-passon-when[b-dp2nzm2qgc] { font-family: var(--k-font-mono); font-size: 11px; color: var(--k-text-muted); }
.kl-home-passon-body[b-dp2nzm2qgc] { display: block; margin: 0; font-size: 12px; line-height: 1.5; color: var(--k-text-muted); }
/* A6 2026-09-13 — measured box 18 / hit 18-20. This is the full-width tail link of the Pass-On card, with no
   horizontal neighbour and nothing but the card's own padding below it, so the box floor is free of any overlay
   risk and costs 30px once. */
.kl-home-passon-all[b-dp2nzm2qgc] { display: inline-flex; align-items: center; gap: 4px; margin-top: var(--k-space-5); min-block-size: var(--k-touch); font-size: 12px; font-weight: 600; color: var(--k-accent); text-decoration: none; }
.kl-home-passon-all:hover[b-dp2nzm2qgc] { text-decoration: underline; }
.kl-home-passon-all[b-dp2nzm2qgc]::after { content: "→"; font-family: var(--k-font-mono); }

/* ---- Events ---- */
.kl-home-events-list[b-dp2nzm2qgc] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.kl-home-event-row a[b-dp2nzm2qgc] { display: flex; align-items: center; justify-content: space-between; gap: var(--k-space-2); padding: var(--k-space-4) var(--k-space-5); border-radius: var(--k-radius-sm); font-size: 13px; color: var(--k-text); text-decoration: none; transition: background-color .12s, color .12s; }
.kl-home-event-row a:hover[b-dp2nzm2qgc] { background: var(--k-surface-2); color: var(--k-accent); }
.kl-home-event-row .k-mono[b-dp2nzm2qgc] { font-size: 12px; color: var(--k-text-muted); }

/* ---- Sync: a COMPACT little status bar (rebuilt). The full `padding` shorthand overrides the generic
   .kl-home-card padding so it stays slim; tight line-heights + a 1px body gap remove the dead vertical
   space (no more big top gap or loose row spacing); align-items:center vertically centres icon/body/chip
   in the now content-height card. margin-block-start:auto still pins it to the column bottom when the
   column has spare height; otherwise it just sits snugly under Events. ---- */
.kl-home-sync[b-dp2nzm2qgc] {
  display: flex;
  align-items: center;
  gap: var(--k-space-4);
  margin-block-start: auto;
  padding: var(--k-space-4) var(--k-space-5);
}
.kl-home-sync-icon[b-dp2nzm2qgc] { font-size: 18px; color: var(--k-success); flex-shrink: 0; }
.kl-home-sync-body[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: 1px; margin-right: auto; line-height: 1.2; }
.kl-home-sync-health[b-dp2nzm2qgc] { font-size: 12px; font-weight: 700; letter-spacing: .04em; line-height: 1.2; color: var(--k-success); }
.kl-home-sync-chk[b-dp2nzm2qgc] { font-size: 10px; line-height: 1.2; color: var(--k-text-muted); }
.kl-home-sync .kl-mock-chip[b-dp2nzm2qgc] { margin-inline-start: 0; flex-shrink: 0; }

/* =============================================================================
   Supervisor oversight
   ========================================================================== */
/* Now lives INSIDE the Operations column (above Drafts) — the pane gap handles separation (no top
   margin) and the padding is trimmed for the narrower column. */
.kl-home-supervisor[b-dp2nzm2qgc] {
  margin-block-start: 0;
  background: var(--k-surface); border: 1px solid var(--k-border);
  border-radius: var(--k-radius-lg); padding: var(--k-space-7); box-shadow: var(--k-elev-1);
}
.kl-home-supervisor > .kl-section-head[b-dp2nzm2qgc] {
  display: flex; align-items: center; gap: var(--k-space-5);
  margin-bottom: var(--k-space-8); padding-bottom: var(--k-space-6); border-bottom: 1px solid var(--k-border);
}
.kl-home-supervisor .kl-section-title[b-dp2nzm2qgc] { margin: 0 auto 0 0; font-size: 11px; font-weight: 700; letter-spacing: .22em; text-transform: uppercase; color: var(--k-text-muted); }

/* auto-fill adapts the panel count to the narrower Operations-column width (container-responsive).
   align-items:stretch is explicit (not just the grid default) so every panel sharing a row fills that
   row's track height — see .kl-home-sup-panel's height:100% for the box-sizing half of the fix. */
.kl-home-sup-grid[b-dp2nzm2qgc] { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); align-items: stretch; gap: var(--k-space-6); list-style: none; margin: 0; padding: 0; }

/* No min-height: a short panel sits at content height (owner: no dead space); the grid row equalizes track
   height to the tallest panel, and each CTA's margin-top:auto keeps it pinned to its card's bottom edge.
   box-sizing:border-box + height:100% (owner ruling 2026-07-23, equal-height oversight tiles): a descendant
   of .kl-shell-main inherits NO box-sizing reset (the sheet's only reset is the shell's own direct children —
   see kanine-design-system.css "box-sizing is LOAD-BEARING" note), so this panel defaults to content-box.
   grid's default align-items:normal/stretch alone was NOT reliably filling every same-row panel to the row's
   track height on this page (measured: shorter panels landed ~8px short of taller row-mates); height:100%
   against a border-box panel resolves against the grid area itself and fills it exactly, with no clipping
   since the content never exceeds its own natural height and the flex column simply gets more free space. */
.kl-home-sup-panel[b-dp2nzm2qgc] {
  display: flex; flex-direction: column; gap: var(--k-space-5);
  background: var(--k-surface-2); border: 1px solid var(--k-border); border-radius: var(--k-radius-lg); padding: var(--k-space-6);
  transition: border-color .12s, transform .12s, box-shadow .12s;
  box-sizing: border-box; height: 100%;
}
.kl-home-sup-panel:hover[b-dp2nzm2qgc] { border-color: var(--k-outline); transform: translateY(-1px); box-shadow: var(--k-elev-2); }
.kl-home-sup-panel--critical[b-dp2nzm2qgc] { border-color: color-mix(in oklab, var(--k-critical) 35%, var(--k-border)); background: color-mix(in oklab, var(--k-critical) 6%, var(--k-surface-2)); }
.kl-home-sup-panel--caution[b-dp2nzm2qgc] { border-color: color-mix(in oklab, var(--k-caution) 35%, var(--k-border)); background: color-mix(in oklab, var(--k-caution) 6%, var(--k-surface-2)); }
/* UI-GUAR-027 (R2-16): in the DARK family a surface must never carry a status hue. Neutralize the
   critical/caution sup-panel FILL to the sanctioned --k-surface-2 (status stays on the colored border +
   the big-number color + the icon). Light/outdoor-light keep the redesign's faint high-contrast tint. */
html.dark .kl-home-sup-panel--critical[b-dp2nzm2qgc],
html.dark .kl-home-sup-panel--caution[b-dp2nzm2qgc] { background: var(--k-surface-2); }
.kl-home-sup-panel .kl-home-card-head[b-dp2nzm2qgc] { margin-bottom: 0; }
.kl-home-sup-panel .kl-home-card-icon[b-dp2nzm2qgc] { font-size: 16px; color: var(--k-text-muted); }
.kl-home-sup-rows[b-dp2nzm2qgc] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; flex: 1; }
.kl-home-sup-rows li[b-dp2nzm2qgc] { display: flex; align-items: center; justify-content: space-between; gap: var(--k-space-4); padding: var(--k-space-3) 0; border-bottom: 1px dashed var(--k-border); font-size: 12px; color: var(--k-text-muted); }
/* A6 2026-09-13 — the row links measured box 18 / hit 18 in a 31px row. AN EXPANDER IS NOT AVAILABLE HERE: the
   rows are stacked 31px apart, so a 48px band centred on one row's link overlaps the band of the row above and
   the row below, and every one of those is itself a link to a different record. That is the exact press-stealing
   the overlay rule forbids. The row must therefore grow, and the anchor must fill it — the same answer the
   /dogs/{id}/edit custom-field row took. The li's block padding moves onto the anchor so the anchor's box IS the
   row's box; `align-items: stretch` is what lets it take the height. The dashed separator stays on the li.
   Measured after: hit 48, rows 31 -> 48, and a press on the row above and the row below still opens THAT row's
   record. Cost: +17px per row on the two supervisor widgets. */
.kl-home-sup-rows li:has(> .kl-home-sup-rownav)[b-dp2nzm2qgc] { align-items: stretch; padding-block: 0; }
.kl-home-sup-rownav[b-dp2nzm2qgc] { padding-block: var(--k-space-3); min-block-size: var(--k-touch); }
.kl-home-sup-rows li:last-child[b-dp2nzm2qgc] { border-bottom: 0; }
.kl-home-sup-rows li .k-mono[b-dp2nzm2qgc] { font-size: 11px; color: var(--k-text); }
.kl-home-sup-big[b-dp2nzm2qgc] { margin: var(--k-space-4) 0 0; flex: 1; font-family: var(--k-font-display); font-weight: 800; font-size: 56px; line-height: 1; letter-spacing: -.04em; color: var(--k-text); }
.kl-home-sup-panel--critical .kl-home-sup-big[b-dp2nzm2qgc] { color: var(--k-critical); }
.kl-home-sup-panel--caution .kl-home-sup-big[b-dp2nzm2qgc] { color: var(--k-caution); }
.kl-home-sup-sub[b-dp2nzm2qgc] { margin: 0; font-size: 12px; color: var(--k-text-muted); }
.kl-home-sup-cta[b-dp2nzm2qgc] { margin-top: auto; width: 100%; }
.kl-home-sup-cta-only[b-dp2nzm2qgc] { min-height: 0; }
.kl-home-sup-cta-only .kl-home-card-head[b-dp2nzm2qgc] { margin-bottom: var(--k-space-5); }


/* =============================================================================
   Final-draft pass additions (2026-07-02) — drill-downs, compact states, weather detail
   ========================================================================== */

/* The foundation [class$="-empty"]/-loading state kit centers with --k-space-12 padding — right for a
   page-level empty state, wrong inside a dashboard card that already pads itself (it ballooned every
   quiet "Loading…"/"No X." line into a tall centered block). Flatten to an inline muted line. */
.kl-home-card .kl-home-empty[b-dp2nzm2qgc] { padding: 0; align-items: flex-start; text-align: start; }

/* K9 mini-rows that navigate (Next Cert → that certification, Last Med → that medical record). */
a.kl-home-k9-row[b-dp2nzm2qgc] { color: inherit; text-decoration: none; transition: border-color .12s, background-color .12s; }
.kl-home-k9-row--nav:hover[b-dp2nzm2qgc] { border-color: var(--k-accent); background: color-mix(in oklab, var(--k-accent) 6%, var(--k-surface-2)); }
.kl-home-k9-row--nav:focus-visible[b-dp2nzm2qgc] { outline: 2px solid var(--k-accent); outline-offset: 2px; }

/* Compact no-default-K9 helper (replaces the foundation-stacked tall variant). */
.kl-home-k9-unset[b-dp2nzm2qgc] { display: flex; flex-direction: column; align-items: center; gap: var(--k-space-4); padding: var(--k-space-6); text-align: center; }
.kl-home-k9-unset .kl-home-empty[b-dp2nzm2qgc] { padding: 0; }
.kl-home-k9-unset-actions[b-dp2nzm2qgc] { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--k-space-3); }

/* Dismissed variant: one quiet row, content height. */
.kl-home-k9-collapsed[b-dp2nzm2qgc] { display: flex; align-items: center; gap: var(--k-space-4); padding: var(--k-space-5) var(--k-space-6); }
.kl-home-k9-collapsed .kl-home-empty[b-dp2nzm2qgc] { padding: 0; }

/* Supervisor rows that navigate to their record. The li keeps the dashed separator; the anchor fills it. */
.kl-home-sup-rownav[b-dp2nzm2qgc] { display: flex; flex: 1; align-items: center; justify-content: space-between; gap: var(--k-space-4); color: inherit; text-decoration: none; min-width: 0; }
.kl-home-sup-rownav:hover[b-dp2nzm2qgc], .kl-home-sup-rownav:hover .k-mono[b-dp2nzm2qgc] { color: var(--k-accent); }
.kl-home-sup-rownav:focus-visible[b-dp2nzm2qgc] { outline: 2px solid var(--k-accent); outline-offset: 2px; border-radius: var(--k-radius-sm); }

/* Dark-family remap for the big status numerals (UI-GUAR-027 restraint: the fixed semantic hues are too
   hot on the dark canvas; use the canonical dark status tints). */
html.dark .kl-home-sup-panel--critical .kl-home-sup-big[b-dp2nzm2qgc] { color: #f6ab9d; }
html.dark .kl-home-sup-panel--caution .kl-home-sup-big[b-dp2nzm2qgc] { color: #f4c884; }

/* Weather tile → detail popup affordance. A chrome-free real <button> wrapping the live tile. */
.kl-home-weather-detail-toggle[b-dp2nzm2qgc] {
  display: block; inline-size: 100%; padding: 0; margin: 0;
  background: none; border: 0; font: inherit; color: inherit; text-align: start;
  cursor: pointer; border-radius: var(--k-radius-md);
}
.kl-home-weather-detail-toggle:hover .kl-home-weather-temp[b-dp2nzm2qgc] { color: var(--k-accent); }
.kl-home-weather-detail-toggle:focus-visible[b-dp2nzm2qgc] { outline: 2px solid var(--k-accent); outline-offset: 4px; }

/* Task B (owner request 2026-07-23): compact icon-only weather refresh, tucked into the live card's top-right
   corner — the SAME corner slot the FREE-tier teaser's .kl-home-weather-sample-badge uses below, so it never
   collides with either (only one of the two states ever renders). Sibling of .kl-home-weather-detail-toggle, not
   nested inside it (a <button> cannot contain a <button>). */
.kl-home-weather-refresh[b-dp2nzm2qgc] {
  position: absolute; top: 8px; right: 10px; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  inline-size: 28px; block-size: 28px; padding: 0; margin: 0;
  background: var(--k-surface); border: 1px solid var(--k-border); border-radius: var(--k-radius-full);
  color: var(--k-text-muted); cursor: pointer; transition: color .15s, border-color .15s;
}
.kl-home-weather-refresh:hover:not(:disabled)[b-dp2nzm2qgc] { color: var(--k-accent); border-color: var(--k-accent); }
.kl-home-weather-refresh:focus-visible[b-dp2nzm2qgc] { outline: 2px solid var(--k-accent); outline-offset: 2px; }
.kl-home-weather-refresh:disabled[b-dp2nzm2qgc] { opacity: .6; cursor: default; }
.kl-home-weather-refresh-icon[b-dp2nzm2qgc] { font-size: 13px; }
.kl-home-weather-refresh-icon--spin[b-dp2nzm2qgc] { animation: kl-home-weather-refresh-spin-b-dp2nzm2qgc .8s linear infinite; }
@keyframes kl-home-weather-refresh-spin-b-dp2nzm2qgc { to { transform: rotate(360deg); } }

/* Weather detail dialog (KlOverlay supplies scrim + centering; kl-dialog supplies the surface). */
.kl-home-weather-dialog[b-dp2nzm2qgc] { max-inline-size: 26rem; inline-size: calc(100% - 2rem); padding: var(--k-space-6); display: flex; flex-direction: column; gap: var(--k-space-5); }
.kl-home-weather-dlg-head[b-dp2nzm2qgc] { display: flex; align-items: center; gap: var(--k-space-4); }
.kl-home-weather-dlg-icon[b-dp2nzm2qgc] { font-size: 34px; color: var(--k-accent); }
.kl-home-weather-dlg-id[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: 2px; margin-inline-end: auto; }
.kl-home-weather-dlg-title[b-dp2nzm2qgc] { margin: 0; font-family: var(--k-font-display); font-size: 1.075rem; }
.kl-home-weather-dlg-place[b-dp2nzm2qgc] { font-size: 12px; color: var(--k-text-muted); }
.kl-home-weather-dlg-temp[b-dp2nzm2qgc] { font-size: 24px; font-weight: 600; }
.kl-home-weather-dlg-grid[b-dp2nzm2qgc] { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--k-space-4); margin: 0; }
.kl-home-weather-dlg-fact dt[b-dp2nzm2qgc] { font-family: var(--k-font-mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--k-text-muted); }
.kl-home-weather-dlg-fact dd[b-dp2nzm2qgc] { margin: 2px 0 0; font-size: 14px; font-weight: 600; color: var(--k-text); }
.kl-home-weather-dlg-forecast[b-dp2nzm2qgc] { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--k-space-4); padding: var(--k-space-4); background: var(--k-surface-2); border: 1px solid var(--k-border); border-radius: var(--k-radius-md); }
.kl-home-weather-dlg-cell[b-dp2nzm2qgc] { display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 12px; }
.kl-home-weather-dlg-cell .ki[b-dp2nzm2qgc] { font-size: 16px; color: var(--k-accent); }
.kl-home-weather-dlg-note[b-dp2nzm2qgc] { margin: 0; font-size: 11px; color: var(--k-text-muted); }

/* ── FREE-tier weather teaser (owner-directed 2026-07-18): a blurred, explicitly-SAMPLE mock behind a lock +
   subscription CTA. The blur + badge + overlay make it unmistakable as a sample — the live tile's
   "never a fabricated reading" doctrine stands untouched. ── */
.kl-home-weather-teaser[b-dp2nzm2qgc] { position: relative; overflow: hidden; }
.kl-home-weather-blur[b-dp2nzm2qgc] { filter: blur(5px); opacity: .5; pointer-events: none; user-select: none; }
.kl-home-weather-sample-badge[b-dp2nzm2qgc] { position: absolute; top: 8px; right: 10px; z-index: 2; font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--k-text-muted); border: 1px solid currentColor; border-radius: 4px; padding: 2px 6px; }
.kl-home-weather-lock[b-dp2nzm2qgc] { position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--k-space-3); text-align: center; padding: var(--k-space-4); }
.kl-home-weather-lock .ki[b-dp2nzm2qgc] { font-size: 22px; color: var(--k-accent); }
.kl-home-weather-lock p[b-dp2nzm2qgc] { margin: 0; font-size: 13px; line-height: 1.45; color: var(--k-text); max-width: 34ch; }

/* ── FREE-tier step-up banner (owner-directed 2026-07-18): the standing dashboard upgrade prompt. ── */
.kl-home-upgrade[b-dp2nzm2qgc] { display: flex; align-items: center; gap: var(--k-space-4); margin: var(--k-space-4) 0; }
.kl-home-upgrade span:nth-child(2)[b-dp2nzm2qgc] { flex: 1; }
.kl-home-upgrade .kl-btn[b-dp2nzm2qgc] { flex-shrink: 0; }

/* ── "Set up your agency" checklist (owner-directed 2026-07-18, vertical rebuild 2026-07-18): the admin's
   guided-setup tile at the top of the Readiness column. A checkpoint rail — three detectable steps on a
   connected marker spine, teal-filled checks as real data confirms each one, an n/3 mono readout + thin
   progress bar up top, review links + skip demoted to quiet rows. Disappears entirely when all three
   detectable steps are done (ShowSetupCard). ── */
.kl-home-setup[b-dp2nzm2qgc] {
  background:
    radial-gradient(90% 140% at 100% 0%, color-mix(in oklab, var(--k-accent) 10%, transparent), transparent 55%),
    var(--k-surface);
  border: 1px solid color-mix(in oklab, var(--k-accent) 35%, var(--k-border));
  border-radius: var(--k-radius-lg); padding: var(--k-space-7); box-shadow: var(--k-elev-1);
  display: flex; flex-direction: column; gap: var(--k-space-5); min-width: 0;
}
.kl-home-setup-head[b-dp2nzm2qgc] { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--k-space-4); }
.kl-home-setup-heading[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kl-home-setup-eyebrow[b-dp2nzm2qgc] {
  font-family: var(--k-font-mono); font-size: 10px; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--k-accent);
}
.kl-home-setup-title[b-dp2nzm2qgc] { margin: 0; font-family: var(--k-font-display); font-size: 17px; font-weight: 700; color: var(--k-text); }
.kl-home-setup-count[b-dp2nzm2qgc] { font-size: 22px; font-weight: 600; line-height: 1; color: var(--k-text); flex-shrink: 0; }
.kl-home-setup-count-of[b-dp2nzm2qgc] { font-size: 13px; color: var(--k-text-muted); }

/* Thin progress bar — fill width comes inline from SetupDoneCount. */
.kl-home-setup-track[b-dp2nzm2qgc] {
  block-size: 4px; border-radius: var(--k-radius-full); overflow: hidden;
  background: color-mix(in oklab, var(--k-accent) 14%, var(--k-surface-2));
}
.kl-home-setup-track-fill[b-dp2nzm2qgc] {
  block-size: 100%; border-radius: inherit;
  background: linear-gradient(90deg, var(--k-accent), var(--k-accent-bright));
  transition: inline-size .4s ease;
}
@media (prefers-reduced-motion: reduce) { .kl-home-setup-track-fill[b-dp2nzm2qgc] { transition: none; } }

/* Checkpoint rail: 28px markers joined by a hairline spine (li::before between markers). */
.kl-home-setup-steps[b-dp2nzm2qgc] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.kl-home-setup-step[b-dp2nzm2qgc] { position: relative; display: flex; align-items: flex-start; gap: var(--k-space-5); padding-block: var(--k-space-4); }
.kl-home-setup-step:not(:last-child)[b-dp2nzm2qgc]::before {
  content: ""; position: absolute; left: 13.5px; top: calc(var(--k-space-4) + 28px); bottom: calc(-1 * var(--k-space-4) + 4px);
  inline-size: 1px; background: var(--k-border);
}
.kl-home-setup-marker[b-dp2nzm2qgc] {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  inline-size: 28px; block-size: 28px; border-radius: var(--k-radius-full);
  border: 1px solid var(--k-outline); background: var(--k-surface-2); color: var(--k-text-muted);
  transition: background-color .2s, border-color .2s, color .2s;
}
.kl-home-setup-marker .ki[b-dp2nzm2qgc] { font-size: 13px; }
.kl-home-setup-step-body[b-dp2nzm2qgc] { display: flex; flex-direction: column; gap: 1px; min-width: 0; padding-block-start: 3px; }
.kl-home-setup-step-link[b-dp2nzm2qgc] { font-size: 14px; font-weight: 600; color: var(--k-text); text-decoration: none; }
/* ---- A6 — THE GUIDED-SETUP STEP LINKS (measured 2026-09-13) --------------------------------------------------
   Seven links, box 21 / continuous hit span 20 at 1400x900. This is the first page every user sees and, for a new
   agency, the only one that matters until the checklist is done, so a step a finger misses is a step an agency
   does not complete.

   AN EXPANDER, NOT A BOX FLOOR, AND THE MEASUREMENT IS WHY. The link is the TITLE line of a two-line step: its own
   `-note` sits directly beneath it inside `.kl-home-setup-step-body`. Flooring the link's box would push that note
   down 27px on every step and add ~190px to the card — on the page whose phone layout was already cut down by an
   owner ruling for exactly that reason (see the phone disclosure banner below).

   THE BAND, COMPUTED FROM THE RAIL'S OWN GEOMETRY AND THEN SAMPLED. `li.kl-home-setup-step` is 59px; the body
   starts 8px in and the link's centre sits 21.5px below the li's top. A centred 48px band therefore runs from
   2.5px ABOVE the li's top to 45.5px below it. Two consequences, both checked:
     · consecutive bands are 11px APART (one ends at +45.5, the next begins at +56.5 of the same 59px pitch), so no
       step can take the press meant for the step under it. That is the failure this whole task exists to avoid.
     · the 2.5px of overhang lands in the PREVIOUS step's bottom padding, 24px clear of that step's own link.
   Nothing in the band is a control at either width: above is the previous step's note, below is this step's note.
   `inset-inline:0` keeps the band inside the link's own inline extent, so it never reaches the checkpoint marker
   in the column beside it. Measured after: hit 48, each step still opens ITS OWN destination from both edges.

   AT 393x852 THE CHECKLIST IS COLLAPSED behind `home-agency-setup-toggle` (a 48px control) by the owner's phone
   ruling, so these seven links do not render there at all until it is expanded; expanded, they measure the same. */
.kl-home-setup-step-link[b-dp2nzm2qgc] { position: relative; }
.kl-home-setup-step-link[b-dp2nzm2qgc]::after {
  content: ""; position: absolute; inset-inline: 0; inset-block-start: 50%;
  block-size: var(--k-touch); transform: translateY(-50%);
}
.kl-home-setup-step-link:hover[b-dp2nzm2qgc] { color: var(--k-accent); text-decoration: underline; }
.kl-home-setup-step-link:focus-visible[b-dp2nzm2qgc] { outline: 2px solid var(--k-accent); outline-offset: 2px; border-radius: var(--k-radius-sm); }
.kl-home-setup-step-note[b-dp2nzm2qgc] { font-size: 12px; color: var(--k-text-muted); }
/* Owner request 2026-09-28: the "Download the app" step also links to the three app downloads (/apps). The link
   carries kl-home-setup-step-link for the expander (cluster H). It is the last line of the step, so its box takes
   the full touch height. The centred band then stays inside the box and cannot reach the next step. */
.kl-home-setup-step-getapps[b-dp2nzm2qgc] {
  display: inline-flex; align-items: center; align-self: flex-start; min-block-size: var(--k-touch);
  font-size: 13px; font-weight: 600; color: var(--k-accent);
}
.kl-home-setup-step-getapps:focus-visible[b-dp2nzm2qgc] { outline: 2px solid var(--k-accent); outline-offset: 2px; border-radius: var(--k-radius-sm); }
/* KANINE Passport (package I): the optional "Who trained your dogs?" step opens a panel, so its title is a button that
   reads like the other step links. */
button.kl-home-setup-step-link[b-dp2nzm2qgc] { background: none; border: 0; padding: 0; font-family: inherit; text-align: start; cursor: pointer; }

/* Done state: the solid circle-check glyph IS the marker (a full-bleed teal badge — no circle-in-circle),
   quiet label, teal "Done" note — the step stays a link. */
.kl-home-setup-step[data-done="true"] .kl-home-setup-marker[b-dp2nzm2qgc] {
  background: transparent; border-color: transparent; color: var(--k-accent);
}
.kl-home-setup-step[data-done="true"] .kl-home-setup-marker .ki[b-dp2nzm2qgc] { font-size: 28px; line-height: 1; }
.kl-home-setup-step[data-done="true"] .kl-home-setup-step-link[b-dp2nzm2qgc] { color: var(--k-text-muted); font-weight: 500; }
.kl-home-setup-step[data-done="true"] .kl-home-setup-step-note[b-dp2nzm2qgc] { color: var(--k-accent); font-weight: 600; }
.kl-home-setup-step[data-done="true"][b-dp2nzm2qgc]::before { background: color-mix(in oklab, var(--k-accent) 45%, var(--k-border)); }

/* ── Phone disclosure banner for the setup checklist (owner ruling 2026-07-24) ────────────────────────────────
   At 393px the full card measured 545px and pushed four of six Operations tiles below the fold while the page
   said "Pick a task to get started". At ≤640px — this repo's field breakpoint, the same one B3's overflow rule
   uses — the card collapses to one tappable row; above it NOTHING changes (the banner is display:none, and a
   display:none flex child consumes no gap, so the desktop card is byte-identical to before).

   ⚠ NAMED `-disclosure`, NOT `-banner`, ON PURPOSE (owner follow-up 2026-07-24: "could be vertically centred
   better, and it could be shorter vertically"). The shared design system carries
       .kl-shell-main [class$="-banner"], [class$="-conflict"], [class$="-failure"] {
           display:flex; align-items:flex-start; … margin-block-end:var(--k-space-4); }
   (kanine-design-system.css:762-768) — the standalone NOTICE/ALERT family. That selector matches on the class
   STRING ENDING, so the original name `kl-home-setup-banner` was swept into it and silently inherited
   `margin-block-end` (8px under Home's scoped token scale) plus `align-items:flex-start`. The margin sat BELOW the
   control inside the card, which is precisely why the row read as riding high — measured 11px above the control
   and 19px below — and why the card was 8px taller than its content needed. Renaming takes the element OUT of that
   family rather than fighting it with a compensating margin, and drops a pile of other accidental inheritance
   (padding, border, background, border-radius, font-size, line-height) this rule was overriding by luck.
   Same trap as T7 (`[class$="-field"]`); the shared sheet has 117 of these suffix selectors. */
.kl-home-setup-disclosure[b-dp2nzm2qgc] { display: none; }

@media (max-width: 640px) {
  /* Collapsed, this card holds ONE row, so it no longer needs the block padding that was sized for a multi-row
     card — the inline padding stays put so the row still lines up with the expanded card's content. Symmetric by
     construction, which is what actually centres the row; there is only one in-flow child, so the card's flex
     `gap` never applies and no height is hardcoded anywhere. */
  .kl-home-setup[b-dp2nzm2qgc] { padding-block: var(--k-space-3); padding-inline: var(--k-space-5); }

  .kl-home-setup-disclosure[b-dp2nzm2qgc] {
    display: flex; align-items: center; gap: var(--k-space-4);
    inline-size: 100%; min-block-size: var(--k-touch); /* A6 — 48px floor, never shrunk to save space */
    margin-block: 0; /* belt-and-braces: no shared suffix rule may reintroduce the stray margin */
    /* Block padding is deliberately kept: min-block-size sets the FLOOR, so a longer localised title or a
       two-digit count grows the control instead of clipping. */
    padding: var(--k-space-3) 0;
    background: none; border: 0; font: inherit; color: inherit; text-align: start; cursor: pointer;
  }
  .kl-home-setup-disclosure-icon[b-dp2nzm2qgc] { color: var(--k-accent); font-size: 16px; flex-shrink: 0; }
  .kl-home-setup-disclosure-label[b-dp2nzm2qgc] {
    flex: 1 1 auto; min-inline-size: 0;
    font-family: var(--k-font-display); font-size: 15px; font-weight: 700; color: var(--k-text);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* The count stays readable while collapsed — that is the whole point of the banner. */
  .kl-home-setup-disclosure-count[b-dp2nzm2qgc] { flex-shrink: 0; font-size: 16px; font-weight: 600; line-height: 1; color: var(--k-text); }
  .kl-home-setup-disclosure-chevron[b-dp2nzm2qgc] {
    flex-shrink: 0; color: var(--k-text-muted); font-size: 13px;
    transition: transform .2s ease;
  }
  .kl-home-setup-disclosure[aria-expanded="true"] .kl-home-setup-disclosure-chevron[b-dp2nzm2qgc] { transform: rotate(90deg); }
  .kl-home-setup-disclosure:focus-visible[b-dp2nzm2qgc] { outline: 2px solid var(--k-accent); outline-offset: 2px; border-radius: var(--k-radius-sm); }

  /* The banner replaces the card header at phone width — the title and count would otherwise appear twice. */
  .kl-home-setup > .kl-home-setup-head[b-dp2nzm2qgc] { display: none; }

  /* Collapsed: the panel is genuinely hidden, which is the correct disclosure semantic for aria-expanded="false"
     (content promised hidden must not stay reachable by keyboard or screen reader). Expanding reveals it in place,
     directly under the banner, so nothing above it moves. */
  .kl-home-setup[data-expanded="false"] > .kl-home-setup-track[b-dp2nzm2qgc],
  .kl-home-setup[data-expanded="false"] > .kl-home-setup-steps[b-dp2nzm2qgc],
  .kl-home-setup[data-expanded="false"] > .kl-home-setup-foot[b-dp2nzm2qgc] { display: none; }
}

@media (prefers-reduced-motion: reduce) { .kl-home-setup-disclosure-chevron[b-dp2nzm2qgc] { transition: none; } }

/* ── Dev-support decision dialog (owner-directed 2026-07-18): the fast, explicit phone-home choice. ── */
.kl-home-devsupport-dialog[b-dp2nzm2qgc] { max-inline-size: 30rem; inline-size: calc(100% - 2rem); padding: var(--k-space-7); display: flex; flex-direction: column; gap: var(--k-space-4); }
.kl-home-devsupport-title[b-dp2nzm2qgc] { margin: 0; font-family: var(--k-font-display); font-size: 1.15rem; color: var(--k-text); }
.kl-home-devsupport-p[b-dp2nzm2qgc] { margin: 0; font-size: 14px; line-height: 1.55; color: var(--k-text); }
.kl-home-devsupport-warn[b-dp2nzm2qgc] {
  margin: 0; padding: var(--k-space-4) var(--k-space-5); font-size: 13px; line-height: 1.55;
  color: var(--k-text); background: color-mix(in oklab, var(--k-caution) 10%, var(--k-surface-2));
  border: 1px solid color-mix(in oklab, var(--k-caution) 40%, var(--k-border)); border-radius: var(--k-radius-md);
}
.kl-home-devsupport-note[b-dp2nzm2qgc] { margin: 0; font-size: 12px; color: var(--k-text-muted); }
.kl-home-devsupport-dialog .kl-dialog-actions[b-dp2nzm2qgc] { display: flex; justify-content: flex-end; gap: var(--k-space-3); }

/* Skip: a deliberately quiet text action — never competes with the steps. The settings-guide link shares the
   footer row (left) — the durable hub the checklist graduates into. */
.kl-home-setup-foot[b-dp2nzm2qgc] { display: flex; justify-content: space-between; align-items: baseline; gap: var(--k-space-4); }
/* A6 2026-09-13 — the two footer links measured box 18 / hit 18 (`home-agency-setup-guide`) and box 22 / hit 22
   (`home-agency-setup-skip`). The foot is a 22px flex row and it is the LAST thing in the section, so a centred
   48px band runs 13px above it — into the last step's note, which is text — and 13px below it, into the section's
   own padding. Neither holds a control at either width, and `inset-inline:0` keeps each band inside its own link
   so the two never meet across the `space-between` gap. A box floor was rejected here only because it would add
   26px to a card an owner ruling already asked to be shorter; nothing about it would have been unsafe. */
.kl-home-setup-foot > a[b-dp2nzm2qgc],
.kl-home-setup-foot > button[b-dp2nzm2qgc] { position: relative; }
.kl-home-setup-foot > a[b-dp2nzm2qgc]::after,
.kl-home-setup-foot > button[b-dp2nzm2qgc]::after {
  content: ""; position: absolute; inset-inline: 0; inset-block-start: 50%;
  block-size: var(--k-touch); transform: translateY(-50%);
}
.kl-home-setup-guide[b-dp2nzm2qgc] {
  font-size: 12px; font-weight: 600; color: var(--k-accent); text-decoration: none;
}
.kl-home-setup-guide[b-dp2nzm2qgc]::after { content: " →"; font-family: var(--k-font-mono); }
.kl-home-setup-guide:hover[b-dp2nzm2qgc] { text-decoration: underline; }
.kl-home-setup-guide:focus-visible[b-dp2nzm2qgc] { outline: 2px solid var(--k-accent); outline-offset: 2px; border-radius: var(--k-radius-sm); }
.kl-home-setup-skip[b-dp2nzm2qgc] {
  background: none; border: 0; padding: 2px 0; cursor: pointer;
  font: inherit; font-size: 12px; color: var(--k-text-muted); text-decoration: underline dotted;
}
.kl-home-setup-skip:hover[b-dp2nzm2qgc] { color: var(--k-text); }
.kl-home-setup-skip:focus-visible[b-dp2nzm2qgc] { outline: 2px solid var(--k-accent); outline-offset: 2px; border-radius: var(--k-radius-sm); }

/* ==========================================================================
   R11 / UI-GUAR-011 — LOAD-TIME SPACE RESERVATIONS (measured live 2026-09-17)
   ==========================================================================
   The dashboard loads PROGRESSIVELY by owner ruling (UI-GUAR-032, 2026-06-28): no read runs on the prerender
   path, and each widget fills under its own "Loading…" the instant its own read lands. That ruling stands. What
   it cost was measured by the R11 motion tooth on the live host at 1440x900: the Readiness column was driven
   down 570px by the checklist tile, then 239px by My K9, then 317px by Pass-On, then 151px by Upcoming Events,
   for a cumulative layout shift of 0.1603 (supervisor) and 0.1733 (handler) against the 0.05 bar.

   These rules reserve, while each read is in flight, the height that widget occupies once it has landed. They
   touch the LOADING state only — every settled card keeps the exact geometry the owner approved. Each value is
   the measured settled height of that card in the two-column layout, so they are declared only where that
   layout applies (the grid is single-column below 1100px, where the same numbers would over-reserve).

   .kl-home-card sets no box-sizing of its own, so the reservations set it: the numbers below are the card's
   OUTER height, which is what was measured. */
@media (min-width: 1101px) {
  /* My K9 status — the populated card (banner + next cert + last med + profile action). */
  .kl-home-card:has([data-testid="my-k9-loading"])[b-dp2nzm2qgc] { box-sizing: border-box; min-block-size: 262px; }

  /* Pass-On Log — the card renders at most three rows plus the "Open Pass-On inbox" link. */
  .kl-home-card:has([data-testid="passon-loading"])[b-dp2nzm2qgc] { box-sizing: border-box; min-block-size: 404px; }

  /* Upcoming Events — the card renders at most three occurrence rows. */
  .kl-home-card:has([data-testid="upcoming-events-loading"])[b-dp2nzm2qgc] { box-sizing: border-box; min-block-size: 238px; }
}

/* The checklist tile's reserved footprint (see the placeholder's comment in Home.razor). It is a grid item in
   the same cell the real tile takes, so the Readiness aside auto-places into the row below it exactly as it does
   once the card arrives. Below 1100px the page is one column and the checklist LEADS it, so no space is held
   there: a reservation at the top of a stacked page would move the whole page rather than one column. */
.kl-home-dash > .kl-home-setup-reserve[b-dp2nzm2qgc] { grid-column: 2; align-self: start; block-size: 546px; }
@media (max-width: 1100px) { .kl-home-dash > .kl-home-setup-reserve[b-dp2nzm2qgc] { display: none; } }
/* _content/Kanine.Web/Components/Pages/Lookups.razor.rz.scp.css */
/* =============================================================================
   Lookups (lookups.html) — page-scoped R11 refinement (UI-GUAR-011).
   The PLAT-007 / PLAT-024 controlled-vocabulary console. Consumes the foundation
   vocabulary (kl-dialog, kf-* fields, kl-btn, the State kit) and adds ONLY the
   page-specific structure the shared system does not give: the two-pane taxonomy
   rail + workspace, the values table rendered as a calm data surface with on-brand
   status pills, and the centered merge / add overlays. All colour resolves through
   --k-* tokens so the three modes (light / dark / outdoor) flip correctly and the
   R11 token/canvas gate holds — no raw hex, no gradient, no off-token fill.
   ========================================================================== */

/* ---- Two-pane shell: a fixed-width taxonomy rail beside the fluid workspace. -- */
.kl-lookups[b-q97smm9doy] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-6);
}

/* UI-GUAR-036 (R2-25): on a phone the 16rem (256px) NON-shrinkable rail beside the workspace forced the page to
   ~580px (the live sweep measured documentElement scrollWidth 580 > 320). Stack the two panes vertically and let the
   rail span the row so there is zero horizontal page overflow at every phone width. */
@media (max-width: 640px) {
    /* align-items:stretch (overriding the desktop flex-start) so BOTH panes span the column at 100% — otherwise the
       workspace shrink-wraps its content (~722px header/table) and re-introduces page overflow. min-inline-size:0
       lets the workspace's own scroll-containers (the .kl-tablewrap'd value table) clamp instead of pushing the page. */
    .kl-lookups[b-q97smm9doy] { flex-direction: column; align-items: stretch; }
    /* box-sizing:border-box so the rail's own padding does NOT add to its 100% width (the ~10px the live sweep's
       self-diagnosis pinned on @lookups-rail extending past the viewport); min-inline-size:0 lets it shrink fully. */
    .kl-lookups-rail[b-q97smm9doy] { flex: 0 0 auto; inline-size: 100%; max-inline-size: 100%; min-inline-size: 0; box-sizing: border-box; }
    .kl-lookups-workspace[b-q97smm9doy] { inline-size: 100%; max-inline-size: 100%; min-inline-size: 0; box-sizing: border-box; }

    /* Owner request 2026-07-24 ("the navigation list from column 1 is still a wall of stuff I have to scroll past
       to see the cards"): the ~40-button rail is REPLACED by the one-row picker at phone width. The rail is
       display:none rather than visually-hidden on purpose — this is a swap, not a duplication, so the same
       navigation must not be announced twice to a screen reader. Every rail data-testid stays exactly where it
       was, on the same element, for the bUnit suites that click them (bUnit applies no media queries, so those
       tests are unaffected). */
    /* The rail→picker SWAP itself lives at the END of this file, AFTER the picker's base rules — a media query adds
       no specificity, so an "on" rule here would be overridden by the base `display:none` declared later. */
}

/* ---- Taxonomy rail: the vocabulary directory (All Master Data + per-type). ---- */
.kl-lookups-rail[b-q97smm9doy] {
    flex: 0 0 16rem;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
    padding: var(--k-space-3);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}

/* Rail captions: quiet, tracked-caps section markers that give the directory hierarchy
   (root + a vocabularies group) without competing with the selectable list items. */
.kl-lookups-rail-caption[b-q97smm9doy] {
    margin: 0 0 var(--k-space-1);
    padding-inline: var(--k-space-3);
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}
.kl-lookups-rail-group[b-q97smm9doy] {
    margin: var(--k-space-3) 0 var(--k-space-1);
    padding-inline: var(--k-space-3);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

/* Rail items read as a calm left-rail NAV LIST — readable UI-font labels with a clear
   resting / hover / selected hierarchy, NOT code-like mono. The "All Master Data" lead
   sits a touch heavier (the directory root); the per-type filters are the list body. */
.kl-lookups-rail-all[b-q97smm9doy],
.kl-lookups-rail-type[b-q97smm9doy] {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    inline-size: 100%;
    /* UI-GUAR-036 (R2-25): the taxonomy-rail buttons are ≥44 CSS-px touch targets (was 40; sweep flagged 256×40). */
    min-block-size: var(--k-touch);
    padding-block: 0;
    padding-inline: var(--k-space-3);
    text-align: start;
    font-family: var(--k-font-ui, system-ui, sans-serif);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.25;
    letter-spacing: .005em;
    color: var(--k-text);
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--k-radius-md);
    cursor: pointer;
    transition: background-color var(--k-dur-1) var(--k-ease), color var(--k-dur-1) var(--k-ease);
}
/* The directory root reads as the section lead. */
.kl-lookups-rail-all[b-q97smm9doy] {
    margin-block-end: var(--k-space-1);
    font-weight: 600;
}
.kl-lookups-rail-all:hover[b-q97smm9doy],
.kl-lookups-rail-type:hover[b-q97smm9doy] {
    background: var(--k-surface-2);
    color: var(--k-text);
}
/* The active rail item carries the navy/teal identity: a left accent bar + a tinted
   fill + a heavier label (mirroring the prototype's selected "Base Type" row). The
   accent bar is a pseudo-element so it never shifts the label or the row metrics.
   --k-accent flips per mode, so the selected state holds in light / dark / outdoor. */
.kl-lookups-rail-all[aria-pressed="true"][b-q97smm9doy],
.kl-lookups-rail-type[aria-pressed="true"][b-q97smm9doy] {
    color: var(--k-accent);
    font-weight: 700;
    background: color-mix(in srgb, var(--k-accent) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-accent) 28%, var(--k-surface));
}
.kl-lookups-rail-all[aria-pressed="true"][b-q97smm9doy]::before,
.kl-lookups-rail-type[aria-pressed="true"][b-q97smm9doy]::before {
    content: "";
    position: absolute;
    inset-block: 7px;
    inset-inline-start: 0;
    inline-size: 3px;
    border-radius: var(--k-radius-full);
    background: var(--k-accent);
}

/* ---- Workspace: header + suggest + values table. ----------------------------- */
.kl-lookups-workspace[b-q97smm9doy] {
    flex: 1 1 0;
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
}

.kl-lookups-header[b-q97smm9doy] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-3);
    /* Untappable-header fix (found 2026-07-24): the mobile shell top bar is sticky at z-index 70, so anything that
       scroll-anchors to the very top of the viewport lands UNDERNEATH it — a real Playwright click on
       "Mark as reviewed" was refused with `<button data-testid="shell#topbar.k-back"> … intercepts pointer events`,
       i.e. these controls are genuinely untappable at some scroll positions. scroll-margin keeps the whole action
       row clear of the bar whenever anything scrolls it into view. Page-scoped by instruction; the general answer is
       a shell-level `scroll-padding-block-start` on the mobile layout, which would protect EVERY page — reported as
       a recommendation, not applied, because the shell files are under concurrent edit. */
    scroll-margin-block-start: var(--k-space-12);
}
/* The scope title is a page HEADING (the active vocabulary), so it wears the brand
   display face — not a code-like mono token. It reads as the workspace's anchor. */
.kl-lookups-scope[b-q97smm9doy] {
    margin: 0;
    margin-inline-end: auto;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--k-text);
}
/* Review Queue is a real toggle — show its pressed (active-triage) state on-brand. */
.kl-lookups-triage[aria-pressed="true"][b-q97smm9doy] {
    color: var(--k-accent);
    background: color-mix(in srgb, var(--k-accent) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-accent) 30%, var(--k-surface));
}
.kl-lookups-triage[b-q97smm9doy],
.kl-lookups-add[b-q97smm9doy],
.kl-lookups-export[b-q97smm9doy] {
    min-block-size: var(--k-touch);
    padding: 0 var(--k-space-4);
    font-size: 14px;
    color: var(--k-text);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    cursor: pointer;
    transition: background-color var(--k-dur-1) var(--k-ease), border-color var(--k-dur-1) var(--k-ease);
}
.kl-lookups-triage:hover[b-q97smm9doy],
.kl-lookups-add:not(:disabled):hover[b-q97smm9doy] {
    background: var(--k-surface-2);
    border-color: var(--k-outline);
}
/* Add Value is the workspace's primary create — give it the teal lead when enabled. */
.kl-lookups-add:not(:disabled)[b-q97smm9doy] {
    color: var(--k-accent);
    border-color: color-mix(in srgb, var(--k-accent) 40%, var(--k-surface));
    font-weight: 600;
}
.kl-lookups-add:disabled[b-q97smm9doy],
.kl-lookups-export:disabled[b-q97smm9doy] {
    cursor: not-allowed;
    color: var(--k-text-muted);
    opacity: .55;
}

/* (The "Review your lookups" confirmation styled HERE until 2026-09-12 — .kl-lookups-review-confirm for the
   "Mark as reviewed" button and .kl-lookups-reviewed for its confirmed status pill. Owner ruling: "I've decided
   that I dont like the lookups reviewed button at all ... the onboarding page should settle for at least 1
   navigation to the lookups page removing the button". Both controls are gone, so both rules go with them —
   a page rule for markup that no longer exists is dead CSS that looks live.) */

/* ---- Suggest box (PLAT-022 typeahead). --------------------------------------- */
.kl-lookups-suggest[b-q97smm9doy] {
    position: relative;
    /* UI-GUAR-036 (R2-25): cap at the viewport on a phone (22rem=352px exceeded 320 and left a ~10px page overflow). */
    max-inline-size: min(22rem, 100%);
}
.kl-lookups-suggest-input[b-q97smm9doy] {
    inline-size: 100%;
    min-block-size: var(--k-touch); /* UI-GUAR-036: ≥44 touch target */
    padding: 0 var(--k-space-3);
    color: var(--k-text);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
}
.kl-lookups-suggest-input:focus-visible[b-q97smm9doy] {
    outline: 2px solid var(--k-accent);
    outline-offset: 1px;
}
.kl-lookups-suggest-list[b-q97smm9doy] {
    list-style: none;
    margin: var(--k-space-1) 0 0;
    padding: var(--k-space-1);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    box-shadow: var(--k-elev-2);
}
.kl-lookups-suggest-item[b-q97smm9doy] {
    display: flex;
    align-items: baseline;
    gap: var(--k-space-2);
    min-block-size: var(--k-touch); /* UI-GUAR-036: ≥44 touch target */
    padding: 0 var(--k-space-2);
    border-radius: var(--k-radius-sm);
}
.kl-lookups-suggest-item:hover[b-q97smm9doy] {
    background: var(--k-surface-2);
}
/* 2026-07-02: a suggestion is PICKABLE (it commits its type scope) — cursor + focus ring match the affordance. */
.kl-lookups-suggest-item[b-q97smm9doy] { cursor: pointer; }
.kl-lookups-suggest-item:focus-visible[b-q97smm9doy] {
    outline: 2px solid var(--k-accent);
    outline-offset: 2px;
}
.kl-lookups-suggest-code[b-q97smm9doy] {
    color: var(--k-accent);
    font-family: var(--k-font-mono, ui-monospace, monospace);
    font-size: 12px;
}
.kl-lookups-suggest-label[b-q97smm9doy] {
    color: var(--k-text);
    font-size: 14px;
}
.kl-lookups-suggest-empty[b-q97smm9doy] {
    margin: var(--k-space-2) 0 0;
    color: var(--k-text-muted);
    font-size: 13px;
}

/* ---- Values table: a calm, scannable data surface with a quiet accent top edge so
   the workspace reads as the page anchor (presence) without shouting. ---------------- */
.kl-lookups-table[b-q97smm9doy] {
    inline-size: 100%;
    border-collapse: collapse;
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-block-start: 2px solid color-mix(in srgb, var(--k-accent) 38%, var(--k-border));
    border-radius: var(--k-radius-lg);
    overflow: hidden;
    box-shadow: var(--k-elev-1);
}
/* Column headers (2026-07-02 — the values table rendered four-to-five UNLABELED columns):
   the .kl-data-table thead idiom — uppercase 11px muted, a quiet bottom rule. */
.kl-lookups-th[b-q97smm9doy] {
    padding: var(--k-space-3) var(--k-space-4);
    text-align: start;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--k-text-muted);
    border-block-end: 1px solid var(--k-border);
}
.kl-lookups-th--actions[b-q97smm9doy] { text-align: end; }
.kl-lookups-row[b-q97smm9doy] {
    border-block-start: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
    transition: background-color var(--k-dur-1) var(--k-ease);
}
.kl-lookups-row:first-child[b-q97smm9doy] {
    border-block-start: 0;
}
.kl-lookups-row:hover[b-q97smm9doy] {
    background: var(--k-surface-2);
}
.kl-lookups-table td[b-q97smm9doy] {
    padding: var(--k-space-3) var(--k-space-4);
    font-size: 14px;
    color: var(--k-text);
    vertical-align: middle;
}
.kl-lookups-cell-code[b-q97smm9doy] {
    color: var(--k-accent);
    font-family: var(--k-font-mono, ui-monospace, monospace);
    inline-size: 9rem;
    /* ROOT CAUSE of the desktop horizontal scroll (owner: "I cannot see the whole row / the edit button depending
       on screen size"). MEASURED at 1400px, the five columns summed to the table's 946px as:
           status 93.3 | CODE 452 | label 191.7 | order 72.7 | actions 136.4
       — the Code column alone was 48% of the table, because one seeded value's code is a single 50-character
       token with no break opportunity (ENGAGED_IN_OR_SHOWED_INTENT_TO_AGGRESSIVELY_RESIST). A cell's min-content
       width is its longest unbreakable run, and a table can never render narrower than the sum of its columns'
       min-contents, so ONE row was setting the floor for the whole table and pushing the actions column off screen.

       The declared inline-size values were never the lever and shaving them would have achieved nothing: the table
       algorithm had ALREADY squeezed status to 93.3px against its own 8rem declaration. Only the min-content floor
       mattered.

       `overflow-wrap: anywhere` (NOT break-word) is the fix, because only `anywhere` reduces the min-content
       contribution — `break-word` wraps visually but leaves the intrinsic floor intact, so the table would not
       have shrunk at all. READABILITY IS NOT TRADED: every character still renders, the code is never truncated
       or ellipsised, it simply wraps onto a second line in the rare long case. Desktop/tablet only — the phone
       card already gets this from the shared card system. */
    overflow-wrap: anywhere;
}
.kl-lookups-cell-order[b-q97smm9doy] {
    color: var(--k-text-muted);
    inline-size: 5rem;
    font-variant-numeric: tabular-nums;
}
.kl-lookups-cell-actions[b-q97smm9doy] {
    text-align: end;
    white-space: nowrap;
}

/* ── PHONE: the values table reflows to CARDS via the SHARED `.kl-table-cards` system ─────────────────────────
   Adopted, not re-implemented (A1: shared styling lives once). The design system already ships an opt-in
   responsive-card treatment (kanine-design-system.css §"table cards") that six pages use — Certifications, Dogs,
   Expenses, MasterNames, Medical, People. Lookups was simply never converted. The opt-in lives in the MARKUP
   (`kl-table-cards` on the <table>, `data-label` / `kl-tcard-title` / `kl-tcard-actions` on the cells), so there is
   deliberately NO page-scoped card CSS here.

   WHY THIS HAD TO COME FIRST: a <table> cannot render narrower than its min-content width, and this one's floor was
   956px (fixed 8rem status + 9rem code + 5rem order + a nowrap actions column of >=48px buttons). At 393px that
   escaped .kl-tablewrap and forced documentElement.scrollWidth to 956; a real mobile browser answers that by
   EXPANDING THE LAYOUT VIEWPORT to 956, so window.innerWidth reported 956, not 393, and every `max-width: 640px`
   rule on this page was being evaluated against the wrong viewport. Capping the row count would NOT have fixed it:
   50 rows have the same min-content width as 1,248.

   A hand-rolled version of this block was written here first and silently did nothing: §5n's table-structural guard
   (kanine-design-system.css:1043-1048) re-asserts `display:table-row`/`table-cell` with `!important` on every table
   inside .kl-shell-main, so page-scoped display rules cannot beat it. The shared system carries the matching
   `!important` overrides by design. If this ever needs extending, extend the SHARED system, never re-add a copy
   here. */

/* ── Row actions PINNED to the trailing edge (owner report 2026-07-24: "on desktop and tablet I cannot see the
   whole row — like I can't see the edit button depending on size of screen"). ───────────────────────────────────
   MEASURED CAUSE: the values table's min-content width is 956px (fixed 8rem status + 9rem code + 5rem order, plus a
   `white-space:nowrap` actions column carrying up to four ≥48px buttons on a PROPOSED row). The workspace's
   .kl-tablewrap is only 634-870px at the widths that matter, so the actions column lands OUTSIDE the viewport —
   measured at 1024 / 1180 / 1400 / 1440 the Edit button's rect sat at x≈1190-1495 with document.elementFromPoint at
   its centre returning nothing at all (it reached the button ONLY at 1280). It was technically scrollable inside
   .kl-tablewrap, but nothing signalled that — the owner is right that the control is effectively unreachable.
   Sticky pins the actions cell to the scroll container's trailing edge so the row's controls are ALWAYS on screen
   whatever the horizontal scroll offset, with no page-level horizontal scrolling (the project's hard constraint) and
   without shrinking a single target (A6 — the buttons keep their var(--k-touch) floor untouched).
   ≥641px only: below that the row becomes a card and there is no horizontal axis to pin to. */
@media (min-width: 641px) {
    /* REQUIRED for the sticky cells below: Chromium ignores `position:sticky` on a <td>/<th> inside a
       `border-collapse:collapse` table. border-spacing:0 keeps the rendered geometry identical to the collapsed
       table (the row dividers are per-row border-block-start declarations, not collapsed cell borders). */
    .kl-lookups-table[b-q97smm9doy] {
        border-collapse: separate;
        border-spacing: 0;
        /* ALSO required: an ancestor with `overflow:hidden` becomes the sticky element's scroll container, so the
           table's own overflow clip silently neutralised the pin. The rounded corners it existed to clip are already
           clipped by .kl-tablewrap (shared sheet: border-radius + overflow-x:auto), so nothing is lost. */
        overflow: visible;
    }
    .kl-lookups-th--actions[b-q97smm9doy],
    .kl-lookups-cell-actions[b-q97smm9doy] {
        position: sticky;
        inset-inline-end: 0;
        z-index: 1;
        /* An opaque backdrop is REQUIRED: without it the scrolled-under label text shows through the pinned cell.
           Both states are declared so the pinned cell tracks the row's hover exactly like the rest of the row. */
        background: var(--k-surface);
    }
    .kl-lookups-row:hover .kl-lookups-cell-actions[b-q97smm9doy] {
        background: var(--k-surface-2);
    }
    /* A hairline so the pinned column reads as pinned rather than as text overlapping mid-scroll. */
    .kl-lookups-th--actions[b-q97smm9doy]::before,
    .kl-lookups-cell-actions[b-q97smm9doy]::before {
        content: "";
        position: absolute;
        inset-block: 0;
        inset-inline-start: 0;
        inline-size: 1px;
        background: var(--k-border);
    }
}

/* Status pill: a small mode-aware lifecycle badge (active / proposed / merged) — a
   tinted, bordered chip (mirroring the prototype) rather than bare coloured text, so
   the lifecycle reads at a glance. Every channel resolves through the status token so
   the chip flips cleanly across the three modes. */
.kl-lookups-cell-status[b-q97smm9doy] {
    inline-size: 8rem;
}
/* UI-GUAR-026 FOLLOW-UP (2026-09-08) — at <=640px this cell is also the shared §8b-m `.kl-tcard-badge`, which
   pins it with `flex: 0 0 auto` (no shrink) so it never gives width back to the title. The 8rem here was sized
   for the DESKTOP table's Status column and was still being honoured as this cell's flex-basis inside the
   phone CARD, permanently reserving ~128px next to the pinned kebab's own reserve before the title got a single
   pixel. Reset to content width for the card only; the shared rule still centres and orders it, so the pill
   itself is untouched at every width. */
@media (max-width: 640px) {
    .kl-lookups-cell-status[b-q97smm9doy] {
        inline-size: auto;
    }
}
.kl-lookups-status-pill[b-q97smm9doy] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-1);
    padding-block: 3px;
    padding-inline: var(--k-space-2);
    border: 1px solid transparent;
    border-radius: var(--k-radius-full);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    line-height: 1.4;
    white-space: nowrap;
}
.kl-lookups-row[data-status="active"] .kl-lookups-status-pill[b-q97smm9doy] {
    color: var(--k-success-fg);
    background: color-mix(in srgb, var(--k-success) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-success) 32%, var(--k-surface));
}
.kl-lookups-row[data-status="proposed"] .kl-lookups-status-pill[b-q97smm9doy] {
    color: var(--k-caution-fg);
    background: color-mix(in srgb, var(--k-caution) 14%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-caution) 36%, var(--k-surface));
}
/* `retired` and `rejected` are the two SOFT-DELETED states (deleted_at set). They join the `merged` treatment
   because all three are terminal — the value is present for curation and history, and no picker will offer it
   again. They must NOT inherit the `active` success tint: a retired row keeps status='active' in the database,
   which is exactly how it came to be badged green in the first place. */
.kl-lookups-row[data-status="merged"] .kl-lookups-status-pill[b-q97smm9doy],
.kl-lookups-row[data-status="retired"] .kl-lookups-status-pill[b-q97smm9doy],
.kl-lookups-row[data-status="rejected"] .kl-lookups-status-pill[b-q97smm9doy] {
    color: var(--k-text-muted);
    background: color-mix(in srgb, var(--k-text-muted) 10%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-text-muted) 28%, var(--k-surface));
}
/* UI-GUAR-027 (R2-16, ruling §H.1 #16) — DARK-MODE BADGE RESTRAINT. In the light/outdoor field the dark-on-tint
   above is high-contrast on white; in the DARK family that bright --k-success TEXT (#1E9E6A) on the desaturated
   dark surface-mix is too low-contrast (the owner's "Active badge too bright / hard to read"). Re-map to LIGHT text
   on a more-saturated (still ≤~0.35 HSL-sat) surface-mix fill — the SAME restrained pattern the foundation uses for
   `html.dark .kl-chip--success` (kanine-design-system.css ~640). A Blazor scoped sheet reaches an `html.dark` ANCESTOR
   by writing the ancestor BARE (`html.dark .scoped .scoped`): the rewriter scopes the trailing compounds with the
   page `[b-hash]` and leaves `html.dark` un-scoped, which is exactly what's wanted (proven by ReportBuilder.razor.css
   ~196 / TenantSettingsRetention.razor.css ~82). NOTE — do NOT use `:global(html.dark)` here: Blazor emits the literal
   `:global(...)` token into the served bundle UNCHANGED, and a browser cannot parse `:global()` (it is a CSS-Modules
   construct, not a web standard), so the WHOLE rule is dropped and the dark remap silently never applies (the live
   DarkSurfaceAndBadgeAuditTests canvas-readback badge tooth caught this: the pill rendered the bright pre-fix
   #1E9E6A at 4.22:1). The token-only base above was necessary but not sufficient because --k-success itself does not
   re-point per mode. The pill stays a compact leaf; only the row hooks the selector (the design-system row-tint is
   chip-leaf-scoped so the `<tr>` never paints). */
html.dark .kl-lookups-row[data-status="active"] .kl-lookups-status-pill[b-q97smm9doy] {
    color: #9ce6c1;
    background: color-mix(in srgb, var(--k-success) 30%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-success) 55%, var(--k-surface));
}
html.dark .kl-lookups-row[data-status="proposed"] .kl-lookups-status-pill[b-q97smm9doy] {
    color: #f4c884;
    background: color-mix(in srgb, var(--k-caution) 32%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-caution) 55%, var(--k-surface));
}
html.dark .kl-lookups-row[data-status="merged"] .kl-lookups-status-pill[b-q97smm9doy],
html.dark .kl-lookups-row[data-status="retired"] .kl-lookups-status-pill[b-q97smm9doy],
html.dark .kl-lookups-row[data-status="rejected"] .kl-lookups-status-pill[b-q97smm9doy] {
    color: var(--k-text-muted);
    background: color-mix(in srgb, var(--k-text-muted) 22%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-text-muted) 45%, var(--k-surface));
}
/* A merged row is a terminal logical-redirect, and a retired / rejected row is soft-deleted — dim all three so
   they read as superseded rather than as current master data. */
.kl-lookups-row[data-status="merged"] td[b-q97smm9doy],
.kl-lookups-row[data-status="retired"] td[b-q97smm9doy],
.kl-lookups-row[data-status="rejected"] td[b-q97smm9doy] {
    /* DIM BY INK, NOT BY OPACITY. `opacity: .6` on the row multiplied into every child: the status pill read 3.59:1
       and the scope chip 3.37:1 in dark. The muted token is 4.5:1 or better in every mode. */
    color: var(--k-text-muted);
}

/* THE PER-ROW ACTION BUTTON SKINS ARE GONE — owner ruling 2026-09-09, "collapse the buttons into the more
   actrions button". `.kl-lookups-approve` / `-merge` / `-reject` / `-fix` / `-edit` styled five inline buttons that
   were duplicates of items this row's overflow menu already carried, and Lookups.razor no longer renders any of
   them. A rule that can no longer match anything is deleted rather than left as a comment: an exception that stops
   describing something is a permanent hole, not documentation. The menu items carry the shared `.kl-rowmenu-item`
   skin, which is where a row action's appearance belongs anyway. */

/* ---- Merge overlay + Add dialog: centered, top-layer-feeling modals. ---------- */
/* UI-GUAR-033: overlay/scrim retired — <KlOverlay> now supplies the fixed scrim + centering. The .kl-lookups-overlay-body below keeps the card styling. */
.kl-lookups-overlay-body[b-q97smm9doy] {
    inline-size: calc(100% - 2rem);
    max-inline-size: 34rem;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    padding: var(--k-space-6);
    background: var(--k-surface);
    color: var(--k-text);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-3);
}
.kl-lookups-overlay-b[b-q97smm9doy],
.kl-lookups-overlay-a[b-q97smm9doy] {
    margin: 0;
    font-size: 14px;
}
.kl-lookups-overlay-b span[data-testid$="-code"][b-q97smm9doy],
.kl-lookups-overlay-a span[data-testid$="-code"][b-q97smm9doy] {
    color: var(--k-accent);
    font-family: var(--k-font-mono, ui-monospace, monospace);
}
.kl-lookups-overlay-execute[b-q97smm9doy] {
    margin-block-start: var(--k-space-2);
}

/* The Add dialog uses the foundation .kl-dialog box styling (surface/radius/shadow). */
/* UI-GUAR-033: overlay positioning retired — <KlOverlay> now supplies the fixed scrim + centering; the panel keeps only its card/box styling. */
/* A13 (2026-09-12): the line that tells the reader this dialog is the fix for the row they clicked. It is a direct
   child of .kl-dialog, so the foundation's `.kl-dialog > * { padding-inline: var(--k-space-6) }` already aligns it
   with the title above and the fields below; only the vertical rhythm and the tone belong here. Caution-toned
   rather than error-toned: an empty category is a gap to fill, not a failure. */
.kl-lookups-add-orphan[b-q97smm9doy] {
    margin: var(--k-space-2) 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--k-text-muted);
}
.kl-lookups-add-form[b-q97smm9doy] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    padding: var(--k-space-4) var(--k-space-6) var(--k-space-6);
}
/* (The dismissal switch was laid out HERE until 2026-09-12 — a second hand-rolled copy of the row
   CustomFields.razor.css also declared. Both are replaced by the shared `label.kf-field--switch` block in
   kanine-design-system.css §5b-sw, which carries the §A6 var(--k-touch) floor. The two ATTACHMENT switches on this
   page carried no rule at all and rendered a 224x13 stretched box; the shared block fixes them with the same
   promotion. Gap moves from --k-space-2 to the shared --k-space-3 so all four switches on this page match.) */

/* (The column-visibility menu was styled HERE until 2026-09-12 — .kl-lookups-columns-wrap, the
   aria-expanded trigger tint, .kl-lookups-columns-menu and the .kl-lookups-columns-item checkbox glyph. Owner
   ruling: "Id also like to remove the columns button i dont think its a need." The control, its menu, its scrim
   and its Order item are deleted, and the inventory contract lookups.html#button.action[4] is RETIRED in
   ProposedUI/docs/retired-contracts.json. The measurement the old comment carried — that this hand-rolled popup
   rendered 96px off the inline-start edge at 430px, which does not grow scrollWidth in LTR and so never showed up
   in any horizontal-overflow sweep — dies with the control it described. The page's ONE remaining menu is the
   shared <CommandBar>, whose panel is anchored by kanine-design-system.css section W4, not by this sheet.) */

/* ---- Edit (rename) + Reject dialogs: centered modals over the curation surface. - */
/* UI-GUAR-033: overlay positioning retired — <KlOverlay> now supplies the fixed scrim + centering; the panels keep only their card/box styling (foundation .kl-dialog). */
.kl-lookups-edit-form[b-q97smm9doy],
.kl-lookups-reject-form[b-q97smm9doy] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    padding: var(--k-space-4) var(--k-space-6) var(--k-space-6);
}
.kl-dialog-body[b-q97smm9doy] {
    margin: 0;
    color: var(--k-text-muted);
    font-size: 14px;
    line-height: 1.5;
}
.kl-lookups-reject-reason[b-q97smm9doy] {
    min-block-size: 4.5rem;
    resize: vertical;
    font-family: inherit;
    line-height: 1.5;
}
/* The danger-led Reject confirm uses the foundation .kl-btn--danger; nothing to add. */

/* ---- Crafted calm motion: the curation dialogs rise in gently (no bounce/gimmick),
   honouring prefers-reduced-motion (the foundation also disables transitions there). */
@keyframes kl-lookups-rise-b-q97smm9doy {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.kl-motion-rise[b-q97smm9doy] {
    animation: kl-lookups-rise-b-q97smm9doy var(--k-dur-2, 180ms) var(--k-ease, ease) both;
}
@media (prefers-reduced-motion: reduce) {
    .kl-motion-rise[b-q97smm9doy] {
        animation: none;
    }
}

/* ---- Empty / placeholder state: a composed, titled card (icon + headline + context),
   NOT a sparse one-liner. The surface matches the values table so the workspace keeps
   the same calm presence whether populated or empty; every channel is token-driven so
   it flips correctly across light / dark / outdoor. ----------------------------------- */
.kl-lookups-empty[b-q97smm9doy] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--k-space-2);
    min-block-size: 16rem;
    padding: var(--k-space-12) var(--k-space-6);
    text-align: center;
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}
.kl-lookups-empty-icon[b-q97smm9doy] {
    margin-block-end: var(--k-space-2);
    color: color-mix(in srgb, var(--k-accent) 55%, var(--k-text-muted));
}
.kl-lookups-empty-title[b-q97smm9doy] {
    margin: 0;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 17px;
    font-weight: 700;
    color: var(--k-text);
}
.kl-lookups-empty-message[b-q97smm9doy] {
    margin: 0;
    max-inline-size: 42ch;
    color: var(--k-text-muted);
    font-size: 14px;
    line-height: 1.55;
}

/* UI-GUAR-024 / R2-13 — the taxonomy-integrity alert. A restrained caution banner (NOT a loud
   full-saturation block): caution text on a desaturated surface-mix fill that reads in all 3 modes
   (the --k-caution + --k-surface mix re-points per mode like every other channel here — no html.dark
   selector). Sits above the workspace header so an admin sees the actionable orphan list first. */
.kl-lookups-integrity[b-q97smm9doy] {
    margin: 0 0 var(--k-space-4);
    padding: var(--k-space-3) var(--k-space-4);
    border: 1px solid color-mix(in srgb, var(--k-caution) 42%, var(--k-surface));
    /* --k-radius-md (8px) — the former --k-radius never existed; its 10px fallback was the live value. */
    border-radius: var(--k-radius-md);
    background: color-mix(in srgb, var(--k-caution) 12%, var(--k-surface));
    color: var(--k-text);
}
.kl-lookups-integrity-title[b-q97smm9doy] {
    margin: 0 0 8px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.5;
    color: var(--k-text);
}
/* The lead line: WHERE the action is. Rendered only when at least one row carries a control (see the .razor). */
.kl-lookups-integrity-lead[b-q97smm9doy] {
    margin: 0 0 var(--k-space-2);
    font-size: 13px;
    line-height: 1.5;
    color: var(--k-text-muted);
}
/* ── THE ROW LIST. MEASURED 2026-09-12, AND THE CAUSE OF "they appear to, but it's not right". ─────────────────
   This rule used to say `display: flex; flex-wrap: wrap` and nothing about direction, intending a WRAPPING ROW OF
   CHIPS. It never rendered as one. The shared RCL carries a family rule

       .kl-shell-main :where([class^="kl-"], [class*=" kl-"])[class$="-list"] { display: flex; flex-direction: column; … }

   and `kl-lookups-integrity-list` ends in `-list`, so it is captured. Both selectors weigh (0,2,0), so source order
   decided and the shared `flex-direction: column` won. CDP's own matched-rule list is where that was read, not
   inferred. The result on the live host at 1400: a COLUMN of four 708px-wide pills, each holding a button only
   121–184px wide — 74% to 83% of every visible quick link did nothing when clicked — plus one row (OTHER) that came
   out 61px tall against 44px for its neighbours, because `align-items: baseline` in a column-WRAP container has no
   sane answer. That is the whole of the appearance complaint.

   THE ANSWER IS NOT A SPECIFICITY FIGHT. A full-width action row is the better shape here anyway: it is one thumb
   target per problem on a phone, it holds a long category name without wrapping into a chip, and the affordance can
   sit at the row's end where a reader looks for it. So the direction the shared rule imposes is now DECLARED here
   rather than inherited by accident, and the row is built to be a row. Nothing reaches the RCL. */
.kl-lookups-integrity-list[b-q97smm9doy] {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
}
/* The row shell owns the frame; the control inside owns every pixel of it (below). */
.kl-lookups-integrity-item[b-q97smm9doy] {
    display: block;
    padding: 0;
    border: 1px solid color-mix(in srgb, var(--k-caution) 34%, var(--k-surface-2, var(--k-surface)));
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2, var(--k-surface));
    font-size: 13px;
}
/* The READ-ONLY row — a reader who cannot author the child vocabulary gets the diagnosis and no control (A13 /
   CanFixOrphan). It has no button to supply the inline padding, so it supplies its own. The block padding stays at
   zero and the height comes from --k-touch alone, which is what makes the read-only alert exactly as tall as the
   author's: measured 58px against 50px before this line, an 8px-per-row difference for the same four problems. */
.kl-lookups-integrity-item:not(:has(> .kl-lookups-integrity-fix))[b-q97smm9doy] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    min-block-size: var(--k-touch);
    padding: 0 var(--k-space-3);
}
/* D54 item 7 — the read-only duplicate row names the survivor in words, because without a control the reader has
   no other way to see which of the two Kanine would keep. Muted like the lead line: it is the row's explanation,
   not its subject. */
.kl-lookups-integrity-keeps[b-q97smm9doy] {
    margin-inline-start: auto;
    color: var(--k-text-muted);
}
/* THE QUICK FIX — owner ask 2026-09-09, reshaped 2026-09-12. The listed problem IS the control, so the row becomes
   a button rather than growing a second element beside it.
   `inline-size: 100%` is the fix for the dead area: what the reader sees framed is exactly what accepts the click.
   A6: --k-touch in the block axis. That is a deliberate spend of vertical space on a control, and it is bounded —
   the alert exists only while the problem does, and it disappears the moment the count reaches zero. */
.kl-lookups-integrity-fix[b-q97smm9doy] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    inline-size: 100%;
    min-block-size: var(--k-touch);
    margin: 0;
    padding: var(--k-space-1) var(--k-space-3);
    border: 0;
    border-radius: inherit;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: start;
    cursor: pointer;
    transition: background-color var(--k-dur-1) var(--k-ease);
}
.kl-lookups-integrity-fix:hover[b-q97smm9doy] {
    background: color-mix(in srgb, var(--k-caution) 22%, var(--k-surface));
}
.kl-lookups-integrity-fix:focus-visible[b-q97smm9doy] {
    outline: 2px solid var(--k-accent);
    outline-offset: 2px;
}
/* The affordance, parked at the row's end. `margin-inline-start: auto` is what pushes it there and what makes the
   gap between the name and the action read as one row rather than two stacked labels. It shrinks before the name
   does (`flex: 0 1 auto` with the name holding `min-inline-size: 0`), so a long category name never pushes the page
   sideways at 320px — it wraps inside its own row instead. */
.kl-lookups-integrity-fix-cta[b-q97smm9doy] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: 0 1 auto;
    margin-inline-start: auto;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--k-accent);
}
.kl-lookups-integrity-fix-icon[b-q97smm9doy] {
    flex: 0 0 auto;
    font-size: 16px;
}
.kl-lookups-integrity-name[b-q97smm9doy] {
    font-weight: 600;
    color: var(--k-text);
    min-inline-size: 0;
    overflow-wrap: anywhere;
}
.kl-lookups-integrity-code[b-q97smm9doy] {
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--k-text-muted);
}

/* ---- RECORD-TAXONOMY scope inputs (the scoped-type add) + the per-row scope chips. ---- */
.kl-lookups-add-scope[b-q97smm9doy] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
    margin: 0;
    padding: var(--k-space-3);
    border: 1px solid var(--k-border);
    /* --k-radius-md — the former --k-radius-2 never existed; the 8px fallback was the live value. */
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2, var(--k-surface));
}
.kl-lookups-add-scope > .kf-label[b-q97smm9doy] {
    margin-block-end: var(--k-space-1);
}
/* §A6 (measured live 2026-09-12 at 320/375/393/430/768/1400): this row is a <label> that activates its checkbox,
   so the label is the hit target, and it measured 20.9px to 37.8px tall — the seven "Can be used as" flags of a
   personnel type were all under the floor at every width. `min-block-size` raises the band the finger lands on and
   `align-items: center` leaves the box and the words where they already sat.

   IT STAYS PAGE-SCOPED, and that is not drift. This is a checkbox LIST inside one fieldset, not a standalone
   `.kf-field` switch: it must not take the form kit's --k-space-4 field margin on all seven rows. The shared switch
   row is `label.kf-field--switch` in kanine-design-system.css §5b-sw and this page uses that one for its three
   standalone switches. */
.kl-lookups-add-scope-kind[b-q97smm9doy] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    /* border-box, so the floor INCLUDES the 2px block padding and the row lands on exactly var(--k-touch).
       Nothing in this sheet's ancestry sets box-sizing on a descendant, so a content-box row would have read 52px. */
    box-sizing: border-box;
    min-block-size: var(--k-touch);
    padding-block: 2px;
    cursor: pointer;
}
.kl-lookups-add-scope-kind input[type="checkbox"][b-q97smm9doy] {
    inline-size: 16px;
    min-inline-size: 16px;
    block-size: 16px;
    margin: 0;
    accent-color: var(--k-teal-700);
    cursor: pointer;
}
.kl-lookups-add-scope-kind-code[b-q97smm9doy] {
    margin-inline-start: auto;
    font-size: 12px;
    color: var(--k-text-muted);
}
.kl-lookups-add-scope-empty[b-q97smm9doy] {
    margin: 0;
    font-size: 13px;
    color: var(--k-text-muted);
}
/* UI-GUAR-026 FOLLOW-UP (2026-09-08) — the wrapper the value's DISPLAY NAME now renders in (Lookups.razor),
   so it is an ELEMENT and not a bare text node. At >640px this is decoration-free (inline, exactly the bare
   text node it replaces). At <=640px the shared §8b-m rule `.kl-table-cards .kl-tcard-title > *` already gives
   any element child of the title cell `overflow:hidden; text-overflow:ellipsis; white-space:nowrap` — which a
   bare text node never qualified for — so wrapping the name in a real element is what lets that existing,
   shared, already-tested rule reach it at all. Nothing below re-declares that treatment; only `flex-basis`
   needs stating here, to make the name claim the whole first line of the (now wrapping) title cell rather than
   share it with `.kl-lookups-row-meta`. */
@media (max-width: 640px) {
    .kl-lookups-table .kl-lookups-cell-label.kl-tcard-title[b-q97smm9doy] {
        flex-wrap: wrap;
        row-gap: var(--k-space-1);
    }
    .kl-lookups-row-name[b-q97smm9doy] {
        flex-basis: 100%;
    }
}

/* UI-GUAR-026 FOLLOW-UP (2026-09-08) — groups the recordKinds scope chips and the personnel-holder note
   (Lookups.razor) into ONE unit, so at <=640px they drop to a line of their own under the name (title.razor's
   wrap above) instead of squeezing it letter by letter — measured 225-321px card heights before this, against
   an 8-11 line-box name at the worst reproduction. This is NOT the row's state: the Status pill two columns
   over is the one `kl-tcard-badge`, and this group does not touch that class, `kl-tcard-actions`, the pinned
   corner or either derived token. At >640px this wrapper carries no rule at all — it renders inline exactly
   where its two children rendered as bare siblings before, so the desktop table is unchanged. */
@media (max-width: 640px) {
    .kl-lookups-table .kl-lookups-cell-label.kl-tcard-title > .kl-lookups-row-meta[b-q97smm9doy] {
        flex-basis: 100%;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--k-space-2);
        overflow: visible;
        text-overflow: clip;
        white-space: normal;
    }
}
.kl-lookups-row-scope[b-q97smm9doy] {
    display: inline-flex;
    flex-wrap: wrap;
    gap: var(--k-space-1);
    margin-inline-start: var(--k-space-2);
    vertical-align: middle;
}
.kl-lookups-row-scope-chip[b-q97smm9doy] {
    display: inline-flex;
    align-items: center;
    padding: 1px 6px;
    border: 1px solid var(--k-border);
    border-radius: 999px;
    background: var(--k-surface-2, var(--k-surface));
    font-size: 11px;
    color: var(--k-text-muted);
    /* UI-GUAR-026 FOLLOW-UP (2026-09-08) — a chip is a single machine token (DEPLOYMENT, TRAINING); it must wrap
       as a whole unit inside its wrapping parent (.kl-lookups-row-scope, flex-wrap:wrap) rather than fragment
       inside itself. Without this the parent's ambient `overflow-wrap: anywhere` (inherited from the shared
       `.kl-table-cards tbody td` rule) reaches the pill's own text and breaks it mid-word the moment the
       available line is narrower than one chip (measured: "DEPLOYMENT" -> "DEPLOY" / "MENT"). flex-shrink:0
       keeps the pill from being squeezed smaller than its own content first, which is what makes wrapping WHOLE
       chips to the next line the flex algorithm's only remaining option. */
    white-space: nowrap;
    flex-shrink: 0;
}

/* OWNER RULING 2026-08-09 — the personnel-type IN-USE count, rendered inline on the value's own title line so it
   costs NO extra row at any width (B1/A10). Deliberately quiet: it is context for a curation decision, not a state
   badge, so it takes the muted text channel rather than the status pill's colour semantics. It flips for free with
   the --k-* tokens. */
.kl-lookups-row-holders[b-q97smm9doy] {
    display: inline-flex;
    align-items: center;
    margin-inline-start: var(--k-space-2);
    font-size: 11px;
    color: var(--k-text-muted);
    vertical-align: middle;
}

/* OWNER RULING 2026-08-09 — the deactivate-in-use warning inside the reject confirm. Deliberately CAUTION, not the
   shared .kl-error critical box: the decision is permitted (we warn, we do not refuse), and a red "error" panel above
   an enabled Save reads as "blocked" and teaches the admin to distrust the colour. Tinted through --k-caution over
   the FLIPPING --k-surface token so it stays legible in the dark/outdoor modes. */
.kl-lookups-reject-inuse[b-q97smm9doy] {
    margin: 0 0 var(--k-space-3);
    padding: var(--k-space-3);
    border: 1px solid color-mix(in srgb, var(--k-caution) 45%, var(--k-surface));
    border-radius: var(--k-radius-md);
    background: color-mix(in srgb, var(--k-caution) 12%, var(--k-surface));
    font-size: 13px;
    line-height: 1.45;
}

/* Dark / outdoor flip: surface/border/text/accent channels above resolve through the --k-* tokens the foundation
   re-points per mode, so they flip for free. The ONE exception is the status pill TEXT colour, which references the
   fixed semantic --k-success/--k-caution hues (these do NOT re-point per mode) and so needs the explicit
   `html.dark … .kl-lookups-status-pill` remap added above (UI-GUAR-027) to stay restrained + legible in the dark
   field. Write the `html.dark` ancestor BARE (NOT `:global(html.dark)` — Blazor emits `:global()` verbatim into the
   bundle and the browser drops the rule as un-parseable; the rewriter scopes the trailing compounds and leaves a bare
   `html.dark` un-scoped, the working pattern). */

/* Bounded render window footer (owner ruling 2026-07-24): the honest "showing N of M" line plus the explicit
   reveal. Reuses .kl-lookups-export for the button so it inherits that family's var(--k-touch) floor (A6). */
.kl-lookups-window[b-q97smm9doy] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
    margin-block-start: var(--k-space-3);
}
.kl-lookups-window-count[b-q97smm9doy] {
    margin: 0;
    font-size: 13px;
    color: var(--k-text-muted);
}

/* ---- Phone taxonomy picker (owner request 2026-07-24) --------------------------------------------------------
   Hidden by default so DESKTOP AND TABLET ARE UNTOUCHED — the left rail remains the navigation there. It is only
   turned on inside the max-width:640px block above, where it replaces the rail one-for-one. A display:none element
   consumes no flex gap, so the desktop two-pane layout is byte-identical to before. */
.kl-lookups-railpicker[b-q97smm9doy] { display: none; }
.kl-lookups-railpicker-label[b-q97smm9doy] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}
.kl-lookups-railpicker-select[b-q97smm9doy] {
    inline-size: 100%;
    max-inline-size: 100%;
    min-inline-size: 0;
    box-sizing: border-box;
    /* A6: the picker is the page's primary navigation on a phone — it keeps the full touch floor. */
    min-block-size: var(--k-touch);
}

/* The rail → picker SWAP. Deliberately the LAST rule in this file: `@media` contributes no specificity, so this
   must come after `.kl-lookups-railpicker { display: none }` above or the base rule wins and the picker never
   appears (it did exactly that on the first attempt — the element was in the DOM but never visible).
   display:none on the rail rather than visually-hidden: this is a SWAP, not a duplication, so the same navigation
   must not be announced twice. */
@media (max-width: 640px) {
    .kl-lookups-rail[b-q97smm9doy] { display: none; }
    .kl-lookups-railpicker[b-q97smm9doy] {
        display: flex;
        flex-direction: column;
        gap: var(--k-space-2);
        inline-size: 100%;
        max-inline-size: 100%;
        min-inline-size: 0;
        box-sizing: border-box;
    }
}

/* ── PHONE: the Order field, after the buttons collapsed ──────────────────────────────────────────────────────
   WHAT WAS HERE. Owner request 2026-07-24: "there is some free vertical space to reclaim on the lookups card if you
   just moved the order label to the same row as the edit button and more actions button". That was answered by
   re-pointing the shared band's `flex-basis: 100%` to `flex: 1 1 auto` so the Order cell could share the action
   row's leading edge.

   WHY IT IS GONE. Owner ruling 2026-09-09: "collapse the buttons into the more actrions button". There is no action
   ROW any more. The slot holds one control, so §A10 clause 4 corners it, and the full-width band row it used to
   occupy is reclaimed outright — which is more than the 2026-07-24 request asked for, and satisfies it by leaving
   nothing to share rather than by overriding it. Every declaration that made Order a passenger on that row goes
   with it: the stretch, the 48px line box, and the footer margin/padding/border that drew the band's divider.

   WHAT ORDER IS, AND WHY IT STAYS AN ORDINARY CARD FIELD. It is a value, not a control, so it cannot collapse into
   the menu. §A10 clause 7 offers `.kl-tcard-foot` — a field moved to the card's LAST line — and Order does not need
   it: it is already the last cell in the table's column order, so the foot line would move nothing and its
   `flex-basis: 100%` would forbid it sharing a line with Code — and they DO share one: measured at 393px, Code
   sits 144px wide at the card's leading edge and Order 80px at its trailing edge, on the same line. Forcing the
   foot line splits that line and costs +20px per card, on every card, for no gain. Clause 7's `.kl-tcard-empty` half is likewise not taken: `SortOrder` is a
   non-nullable int, so the field is never blank while its column is on, and the clause is explicit that the
   empty-hiding is opt-in per field and never generic.

   The ONE delta kept is the inline eyebrow. The shared system renders every data cell's label as a block caption
   above the value; a one-word label over a one-digit number spends a whole line box on 50 cards to say what fits
   beside it. It is still LABELLED — Order is a value admins read and sort by, so it never becomes a bare number. */
@media (max-width: 640px) {
    .kl-shell-main .kl-lookups-table .kl-lookups-cell-order[data-label][b-q97smm9doy]::before {
        display: inline;
        margin-inline-end: var(--k-space-2);
    }
}
/* _content/Kanine.Web/Components/Pages/MyReports.razor.rz.scp.css */
/* Phase G WP-G3 — the reporter's "My reports" view (ruling R2). Reporter-grade chrome: card list (no dense
   data table), plain-language stage chips keyed to FeedbackReporterStage keys, an attention rail for the
   confirm-fix / needs-input items, and the detail drawer with the confirmation block front and center.
   Scoped CSS gives this page its own b-scope (regenerate kanine-scope-map.json on composition change). */

.kl-myreports-lede[b-bfksqbxa30] {
    margin: 0 0 1.25rem;
    color: var(--k-text-muted);
    max-width: 60ch;
}

/* --- attention rail ---------------------------------------------------------------------------------- */

.kl-myreports-attention[b-bfksqbxa30] {
    margin-bottom: 1.5rem;
}

.kl-myreports-attention h2[b-bfksqbxa30] {
    font-size: 0.95rem;
    margin: 0 0 0.5rem;
}

.kl-myreports-attention-card[b-bfksqbxa30] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    text-align: left;
    padding: 0.75rem 1rem;
    margin-bottom: 0.5rem;
    border: 1px solid var(--k-accent, #2f6feb);
    border-left-width: 4px;
    border-radius: 8px;
    /* UI-GUAR-027: a card is a SURFACE, so it mixes over the surface token, never over transparent. The old
       7%-over-transparent tint took whatever sat behind it and matched no sanctioned token in dark (measured
       rgb(17,35,44) in dark, rgb(9,25,31) in dark+outdoor). 8% and 12% over --k-surface are the design system's
       accent hover washes, so the card keeps its tint and resolves to a sanctioned surface in every mode. */
    background: color-mix(in srgb, var(--k-accent, #2f6feb) 8%, var(--k-surface));
    cursor: pointer;
    font: inherit;
    color: var(--k-text);
}

.kl-myreports-attention-card:hover[b-bfksqbxa30] {
    background: color-mix(in srgb, var(--k-accent, #2f6feb) 12%, var(--k-surface));
}

.kl-myreports-attention-text[b-bfksqbxa30] {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kl-myreports-attention-cta[b-bfksqbxa30] {
    font-weight: 600;
    color: var(--k-accent, #2f6feb);
    white-space: nowrap;
}

/* --- card list --------------------------------------------------------------------------------------- */

.kl-myreports-list[b-bfksqbxa30] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.6rem;
}

.kl-myreports-card[b-bfksqbxa30] {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.85rem 1rem;
    border: 1px solid var(--k-border);
    border-radius: 8px;
    background: var(--k-surface, transparent);
    cursor: pointer;
    font: inherit;
    color: var(--k-text);
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

.kl-myreports-card:hover[b-bfksqbxa30] {
    border-color: var(--k-accent, #2f6feb);
    box-shadow: 0 1px 6px rgb(0 0 0 / 8%);
}

/* §A10: the card's title line. `display`/`align-items`/`gap` are the shared `.kl-cardline` primitive's now
   (kanine-design-system.css §8b-n) — what stays here is only this card's own spacing below the line.
   `justify-content: space-between` is GONE on purpose: it pushed the two items to opposite ends, which read fine
   for a chip + a timestamp and is wrong the moment a growing title is the first item — the title's own flex-grow
   is what fills the gap now, and leaving both in place would double-space the row. */
.kl-myreports-card-top[b-bfksqbxa30] {
    margin-bottom: 0.35rem;
}

.kl-myreports-when[b-bfksqbxa30] {
    font-size: 0.8rem;
    color: var(--k-text-muted);
    white-space: nowrap;
}

/* The two-line clamp is deliberate and SURVIVES becoming the title: §8b-n does not ellipsize an off-table title
   precisely so a clamp like this keeps working. The trailing margin went with the row it used to separate. */
.kl-myreports-snippet[b-bfksqbxa30] {
    margin: 0;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.kl-myreports-card-meta[b-bfksqbxa30] {
    display: flex;
    gap: 0.35rem;
    flex-wrap: wrap;
}

/* --- stage chips (keys from FeedbackReporterStage — never raw statuses) -------------------------------- */

.kl-myreports-stage[b-bfksqbxa30] {
    font-weight: 600;
}

.kl-myreports-stage--received[b-bfksqbxa30] {
    background: color-mix(in srgb, var(--k-text-muted) 15%, transparent);
}

.kl-myreports-stage--in-review[b-bfksqbxa30] {
    background: color-mix(in srgb, #8250df 16%, transparent);
    color: #8250df;
}

.kl-myreports-stage--needs-input[b-bfksqbxa30],
.kl-myreports-stage--confirm-fix[b-bfksqbxa30] {
    background: color-mix(in srgb, var(--k-accent, #2f6feb) 16%, transparent);
    color: var(--k-accent, #2f6feb);
}

.kl-myreports-stage--fix-in-progress[b-bfksqbxa30] {
    background: color-mix(in srgb, #bf8700 18%, transparent);
    color: #9a6700;
}

.kl-myreports-stage--closed[b-bfksqbxa30] {
    background: color-mix(in srgb, #1a7f37 16%, transparent);
    color: #1a7f37;
}

html.dark .kl-myreports-stage--fix-in-progress[b-bfksqbxa30] {
    color: #d4a72c;
}

html.dark .kl-myreports-stage--closed[b-bfksqbxa30] {
    color: #3fb950;
}

html.dark .kl-myreports-stage--in-review[b-bfksqbxa30] {
    color: #a371f7;
}

.kl-myreports-sev-high[b-bfksqbxa30] {
    background: color-mix(in srgb, #cf222e 15%, transparent);
    color: #cf222e;
}

/* UI-GUAR-027: in dark the base chip remap repaints this fill as --k-surface-3, and #f85149 on it measured 3.69:1
   (3.39:1 in dark+outdoor), under the 4.5 floor. This is the design system's own dark critical-chip remap
   (html.dark .kl-chip--critical): light text on a 30% critical-over-surface fill, about 6.7:1. */
html.dark .kl-myreports-sev-high[b-bfksqbxa30] {
    color: #f6ab9d;
    background: color-mix(in srgb, var(--k-critical) 30%, var(--k-surface));
}

.kl-myreports-note-chip[b-bfksqbxa30] {
    background: color-mix(in srgb, var(--k-accent, #2f6feb) 14%, transparent);
    color: var(--k-accent, #2f6feb);
}

/* --- detail drawer ------------------------------------------------------------------------------------ */

.kl-myreports-detail[b-bfksqbxa30] {
    max-inline-size: none;   /* defeat the .kl-dialog 30rem clamp */
    width: min(560px, 92vw);
    /* NO block cap here. `max-height: 100vh` used to sit on this line, and the overlay reserves
       `var(--k-space-4)` top AND bottom, so 100vh asks for 2 * --k-space-4 MORE than the panel is
       given, at every viewport. It is deleted rather than corrected: .kl-dialog §5i declares the
       one right budget, `calc(100dvh - 2 * var(--k-space-4))`. `max-height` and `max-block-size`
       are the SAME cascaded property in horizontal-tb, so a page declaration REPLACES the shared
       cap rather than combining with it — a page that restates the budget can only drift from it. */
    overflow-y: auto;
    padding: 1.25rem;
}

.kl-myreports-detail-head[b-bfksqbxa30] {
    margin-bottom: 1rem;
}

.kl-myreports-stage-desc[b-bfksqbxa30] {
    margin: 0.4rem 0 0;
    color: var(--k-text-muted);
}

.kl-myreports-detail h3[b-bfksqbxa30] {
    font-size: 0.95rem;
    margin: 0 0 0.4rem;
}

.kl-myreports-detail section[b-bfksqbxa30] {
    margin-bottom: 1.15rem;
}

.kl-myreports-confirm-block[b-bfksqbxa30] {
    padding: 0.9rem 1rem;
    border: 1px solid var(--k-accent, #2f6feb);
    border-radius: 8px;
    background: color-mix(in srgb, var(--k-accent, #2f6feb) 7%, transparent);
}

.kl-myreports-confirm-block p[b-bfksqbxa30] {
    margin: 0 0 0.6rem;
    color: var(--k-text-muted);
}

.kl-myreports-confirm-actions[b-bfksqbxa30] {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.kl-myreports-reject-label[b-bfksqbxa30] {
    display: block;
    font-weight: 600;
    margin-bottom: 0.3rem;
}

.kl-myreports-required[b-bfksqbxa30] {
    font-weight: 400;
    color: var(--k-text-muted);
    font-size: 0.85rem;
}

.kl-myreports-reject-note[b-bfksqbxa30] {
    width: 100%;
    margin-bottom: 0.6rem;
    resize: vertical;
}

.kl-myreports-verdict[b-bfksqbxa30] {
    margin-bottom: 1rem;
}

.kl-myreports-teamnote[b-bfksqbxa30] {
    padding: 0.75rem 1rem;
    border-left: 3px solid var(--k-accent, #2f6feb);
    border-radius: 4px;
    background: color-mix(in srgb, var(--k-accent, #2f6feb) 6%, transparent);
}

.kl-myreports-teamnote p[b-bfksqbxa30] {
    margin: 0;
    white-space: pre-wrap;
}

.kl-myreports-comment[b-bfksqbxa30] {
    white-space: pre-wrap;
}

.kl-myreports-fieldlabel[b-bfksqbxa30] {
    font-weight: 600;
    margin-right: 0.35rem;
}

.kl-myreports-steps[b-bfksqbxa30] {
    margin: 0.4rem 0 0;
    padding-left: 1.4rem;
}

.kl-myreports-thumbwrap[b-bfksqbxa30] {
    display: inline-block;
    border: 1px solid var(--k-border);
    border-radius: 8px;
    padding: 0.35rem;
    background: none;
    cursor: zoom-in;
    text-align: center;
}

.kl-myreports-thumbwrap:hover[b-bfksqbxa30] {
    border-color: var(--k-accent, #2f6feb);
}

.kl-myreports-thumb[b-bfksqbxa30] {
    display: block;
    max-width: 220px;
    max-height: 150px;
    border-radius: 5px;
}

.kl-myreports-thumb-hint[b-bfksqbxa30] {
    display: block;
    font-size: 0.75rem;
    color: var(--k-text-muted);
    padding-top: 0.25rem;
}

.kl-myreports-timeline ul[b-bfksqbxa30] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.4rem;
    font-size: 0.9rem;
}

/* --- full-screen screenshot --------------------------------------------------------------------------- */

/* This surface is a modal PANEL (role=dialog, aria-modal, inside <KlOverlay>) but it is NOT a
   .kl-dialog, so it inherits no shared cap and has to state the budget itself. `94vh` overran the
   space the overlay leaves on any viewport shorter than 533px: measured 2026-09-13 at 780x360 it
   rendered 338.39px into 328px of space. The image carries the same budget so it fills the panel
   exactly instead of forcing the panel's own scroll. */
.kl-myreports-shot-full[b-bfksqbxa30] {
    max-width: 96vw;
    max-block-size: calc(100vh - 2 * var(--k-space-4));
    max-block-size: calc(100dvh - 2 * var(--k-space-4));
    overflow: auto;
}

.kl-myreports-shot-full img[b-bfksqbxa30] {
    display: block;
    max-width: 100%;
    max-block-size: calc(100vh - 2 * var(--k-space-4));
    max-block-size: calc(100dvh - 2 * var(--k-space-4));
    border-radius: 6px;
}

/* Full-screen detail (owner-directed 2026-07-09) — defeats the design-system 30rem .kl-dialog clamp. */
.kl-myreports-detail-full[b-bfksqbxa30] {
    max-inline-size: none;
    inline-size: min(880px, 96vw);
    /* The block cap is INHERITED from .kl-dialog (§5i): `calc(100dvh - 2 * var(--k-space-4))`.
       This rule declared `max-block-size: 92vh` from 2026-07-09, FIFTEEN DAYS BEFORE the shared cap
       existed (219a2253, 2026-07-24) — so it never was an opt-out from the shared cap, it was a
       per-page guess at the same intent, and it was wrong in BOTH directions. Measured 2026-09-13:
       40px SHORTER than allowed at 1400x900, and 3.19px TALLER than allowed at 780x360, because
       `N vh` exceeds `100vh - 2 * --k-space-4` on any viewport under `2 * --k-space-4 / (1 - N)`. */
    display: flex;
    flex-direction: column;
    padding: 0;
}

.kl-myreports-detail-head-full[b-bfksqbxa30] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.9rem 1.2rem;
    border-bottom: 1px solid var(--k-border, #e2e6ec);
    flex: 0 0 auto;
}

.kl-myreports-detail-head-main[b-bfksqbxa30] { min-inline-size: 0; }

.kl-myreports-detail-head-actions[b-bfksqbxa30] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 0 auto;
    flex-wrap: wrap;
}

.kl-myreports-rescind-confirm-wrap[b-bfksqbxa30] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
}

.kl-myreports-detail-body[b-bfksqbxa30] {
    padding: 1rem 1.2rem 1.4rem;
    overflow-y: auto;
    flex: 1 1 auto;
}

/* Reporter reply round-trip — the NEEDS_INFO answer composer + sent state + history. */
.kl-myreports-reply[b-bfksqbxa30],
.kl-myreports-reply-sent[b-bfksqbxa30] {
    margin: 0.75rem 0 1rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--k-border, #d8dee6);
    border-radius: 8px;
    background: var(--k-surface-2, #f7f9fc);
}

.kl-myreports-reply h3[b-bfksqbxa30],
.kl-myreports-reply-sent h3[b-bfksqbxa30] {
    margin: 0 0 0.35rem;
    font-size: 1rem;
}

.kl-myreports-reply-lede[b-bfksqbxa30] {
    margin: 0 0 0.6rem;
    color: var(--k-text-muted);
    font-size: 0.85rem;
}

.kl-myreports-reply-text[b-bfksqbxa30] {
    inline-size: 100%;
    box-sizing: border-box;
    resize: vertical;
    min-block-size: 5.5rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--k-border, #cfd6df);
    border-radius: 6px;
    font: inherit;
}

.kl-myreports-reply-atts[b-bfksqbxa30] {
    list-style: none;
    margin: 0.6rem 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.kl-myreports-reply-att[b-bfksqbxa30] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--k-border, #cfd6df);
    border-radius: 6px;
    background: var(--k-surface, #fff);
    font-size: 0.8rem;
}

.kl-myreports-reply-thumb[b-bfksqbxa30] {
    inline-size: 2.5rem;
    block-size: 2.5rem;
    object-fit: cover;
    border-radius: 4px;
}

.kl-myreports-reply-att-remove[b-bfksqbxa30] {
    border: none;
    background: transparent;
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1;
    color: var(--k-text-muted);
}

.kl-myreports-reply-actions[b-bfksqbxa30] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.7rem;
    align-items: center;
}

/* ::deep IS LOAD-BEARING — see the same note in CertificationCreate.razor.css. This
   styles the <input> rendered by <InputFile>, a CHILD COMPONENT, which never carries
   this component's scope attribute; without ::deep the compiled selector
   `.kl-myreports-reply-fileinput[b-xxxxxxxxxx]` matches nothing and the raw native
   "Choose Files / no files selected" control sits visible next to the styled "Attach
   file" label. Found by Req_UIGUAR_ScopedCssChildComponentLeakTests, which was written
   for the certificate-scan instance the owner caught on camera and immediately turned
   up this second one — nobody had reported it, because the failure is silent. */
.kl-myreports-reply-attach[b-bfksqbxa30]  .kl-myreports-reply-fileinput {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    opacity: 0;
    overflow: hidden;
}

.kl-myreports-reply-attach[b-bfksqbxa30] {
    position: relative;
    overflow: hidden;
    cursor: pointer;
}

.kl-myreports-reply-history[b-bfksqbxa30] {
    margin: 0.75rem 0;
}

.kl-myreports-reply-past[b-bfksqbxa30] {
    padding: 0.5rem 0.7rem;
    border-inline-start: 3px solid var(--k-accent, #3b6ea5);
    background: var(--k-surface-2, #f7f9fc);
    border-radius: 0 6px 6px 0;
    margin-bottom: 0.5rem;
}

.kl-myreports-reply-past p[b-bfksqbxa30] {
    margin: 0.2rem 0 0;
}
/* _content/Kanine.Web/Components/Pages/OperatorBetaActivity.razor.rz.scp.css */
/* BETA-ACT — the people drill-down has eight columns, so it defeats the 30rem .kl-dialog clamp (the FeedbackTriage
   full-detail pattern). The block cap stays the shared one of .kl-dialog, and the panel scrolls inside it. */
.kl-beta-activity-drill[b-wyjcyu1vlw] {
    max-inline-size: none;
    width: min(1100px, 96vw);
    overflow-y: auto;
}

/* The order control does not need the width of the page. */
.kl-beta-activity-sort[b-wyjcyu1vlw] {
    max-inline-size: 20rem;
}
/* _content/Kanine.Web/Components/Pages/OrgUnits.razor.rz.scp.css */
/* =============================================================================
   OrgUnits (org-units.html) — page-scoped R11 refinement (UI-GUAR-011).
   The DATA-013 org-unit registry / tree editor. The shared design system gives
   the page shell (kl-page / kl-section-head), the fields (kf-*), the buttons
   (kl-btn) and the dialog box (kl-dialog); this stylesheet adds ONLY the
   page-specific structure the system does not: the titled header, a composed
   empty-state card, the two-pane (hierarchy rail + detail workspace) split, the
   ARIA tree rendered as a calm, scannable surface with a navy/teal selected
   accent, the detail form rhythm, and the centered create / move overlays.

   Every colour resolves through --k-* tokens so the three modes (light / dark /
   outdoor) flip correctly and the R11 token/canvas gate holds — no raw hex
   (except the modal scrim, matching the signed-off Lookups precedent), no
   gradient, no off-token fill. NOTE (corrected 2026-07-02): scoped CSS CAN
   reach the dark ancestor — write a BARE `html.dark .my-class` rule (it is
   `:global(html.dark)` that ships verbatim and dies; Lookups.razor.css:340 is
   the proven in-repo pattern). This file simply needs no remap because every
   channel is token-driven.
   ========================================================================== */

/* ---- Titled header: the page anchor (title + one-line context) beside the
   primary create action, mirroring the signed-off evidence-vault pagehead. ----- */
.kl-ou-pagehead[b-9kceg8e18j] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--k-space-4);
    margin-block-end: var(--k-space-6);
}
.kl-ou-pagehead-text[b-9kceg8e18j] {
    min-inline-size: 0;
}
.kl-ou-pagetitle[b-9kceg8e18j] {
    margin: 0 0 var(--k-space-1);
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--k-text);
}
.kl-ou-pagesub[b-9kceg8e18j] {
    margin: 0;
    max-inline-size: 64ch;
    color: var(--k-text-muted);
    line-height: 1.5;
}
/* Keep the create action from being squeezed when the title wraps. */
.kl-ou-page .kl-head-actions[b-9kceg8e18j] {
    flex: 0 0 auto;
}

/* ---- Composed empty state: a token card with an inline org-hierarchy glyph in a
   tinted disc, a headline and one line of guidance — optically centred, the same
   calm presence as the populated surface (NOT a sparse line on a void). ---------- */
.kl-ou-empty[b-9kceg8e18j] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--k-space-3);
    min-block-size: 18rem;
    justify-content: center;
    padding: var(--k-space-16) var(--k-space-6);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}
.kl-ou-empty-disc[b-9kceg8e18j] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 72px;
    block-size: 72px;
    margin-block-end: var(--k-space-1);
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    color: var(--k-accent);
}
.kl-ou-empty-svg[b-9kceg8e18j] {
    display: block;
}
.kl-ou-empty-title[b-9kceg8e18j] {
    margin: 0;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--k-text);
}
.kl-ou-empty-msg[b-9kceg8e18j] {
    margin: 0;
    max-inline-size: 48ch;
    color: var(--k-text-muted);
    line-height: 1.55;
}

/* ---- Two-pane split: a fixed-width hierarchy rail beside the fluid detail
   workspace (collapses to a stack on narrow viewports). --------------------------- */
.kl-split[b-9kceg8e18j] {
    display: flex;
    align-items: stretch;
    gap: var(--k-space-6);
}
@media (max-width: 900px) {
    .kl-split[b-9kceg8e18j] {
        flex-direction: column;
    }
}

.kl-tree-pane[b-9kceg8e18j] {
    flex: 0 0 20rem;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    padding: var(--k-space-4);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}
@media (max-width: 900px) {
    .kl-tree-pane[b-9kceg8e18j] {
        flex-basis: auto;
    }
}

.kl-detail-pane[b-9kceg8e18j] {
    flex: 1 1 0;
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    padding: var(--k-space-6);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-block-start: 2px solid color-mix(in srgb, var(--k-accent) 38%, var(--k-border));
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}

/* A quiet, tracked-caps section title for each pane head. */
.kl-section-title[b-9kceg8e18j] {
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--k-text);
}

/* ---- ARIA tree: a calm, scannable list of selectable nodes. ------------------- */
.kl-tree[b-9kceg8e18j] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow-y: auto;
}
.kl-tree-node[b-9kceg8e18j] {
    display: flex;
    flex-direction: column;
}

/* A node row — branch (expand/collapse) or leaf (select). Generous touch target,
   resting / hover / selected hierarchy. The whole row is the affordance. */
.kl-tree-row[b-9kceg8e18j] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    min-block-size: var(--k-touch);
    padding-inline: var(--k-space-2);
    border: 1px solid transparent;
    border-radius: var(--k-radius-md);
    cursor: pointer;
    transition: background-color var(--k-dur-1) var(--k-ease), border-color var(--k-dur-1) var(--k-ease);
}
.kl-tree-row:hover[b-9kceg8e18j] {
    background: var(--k-surface-2);
}
.kl-tree-row:focus-visible[b-9kceg8e18j] {
    outline: 2px solid var(--k-accent);
    outline-offset: 1px;
}

/* The selected node carries the navy/teal identity: a left accent bar + a tinted
   fill (mirroring the Lookups selected-rail pattern). --k-accent flips per mode. */
.kl-tree-node--selected > .kl-tree-row[b-9kceg8e18j] {
    position: relative;
    color: var(--k-accent);
    background: color-mix(in srgb, var(--k-accent) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-accent) 28%, var(--k-surface));
}
.kl-tree-node--selected > .kl-tree-row[b-9kceg8e18j]::before {
    content: "";
    position: absolute;
    inset-block: 9px;
    inset-inline-start: 0;
    inline-size: 3px;
    border-radius: var(--k-radius-full);
    background: var(--k-accent);
}

.kl-tree-twisty[b-9kceg8e18j] {
    flex: 0 0 1.25rem;
    text-align: center;
    color: var(--k-text-muted);
    font-size: 0.85rem;
    user-select: none;
}
.kl-tree-name[b-9kceg8e18j] {
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.95rem;
    color: var(--k-text);
}
.kl-tree-node--selected > .kl-tree-row .kl-tree-name[b-9kceg8e18j] {
    font-weight: 600;
    color: var(--k-accent);
}
/* The short code badge: a quiet mono chip, set apart from the name. */
.kl-tree-badge[b-9kceg8e18j] {
    flex: 0 0 auto;
    padding-block: 2px;
    padding-inline: var(--k-space-2);
    font-family: var(--k-font-mono, ui-monospace, monospace);
    font-size: 10px;
    letter-spacing: 0.02em;
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border-radius: var(--k-radius-sm);
}
.kl-tree-node--selected > .kl-tree-row .kl-tree-badge[b-9kceg8e18j] {
    color: var(--k-accent);
    background: color-mix(in srgb, var(--k-accent) 16%, var(--k-surface));
}

/* Children indent + a hairline guide rail (the hierarchy cue). */
.kl-tree-children[b-9kceg8e18j] {
    margin-inline-start: var(--k-space-3);
    padding-inline-start: var(--k-space-3);
    border-inline-start: 1px solid color-mix(in srgb, var(--k-border) 70%, transparent);
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* ---- Detail workspace: the section head, the field grid + actions. ------------ */
.kl-detail-pane .kl-section-head[b-9kceg8e18j] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
}

.kl-form-grid[b-9kceg8e18j] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--k-space-4) var(--k-space-6);
}
@media (max-width: 640px) {
    .kl-form-grid[b-9kceg8e18j] {
        grid-template-columns: minmax(0, 1fr);
    }
}
.kf-field[b-9kceg8e18j] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
}

/* The read-only Parent Unit value: reads as a filled, non-editable field (it is
   changed via the structural Move op, not inline) — distinct from the inputs. */
.kf-readonly[b-9kceg8e18j] {
    display: flex;
    align-items: center;
    min-block-size: var(--k-touch);
    padding-inline: var(--k-space-3);
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
}

.kl-form-actions[b-9kceg8e18j] {
    display: flex;
    justify-content: flex-end;
    gap: var(--k-space-3);
    margin-block-start: var(--k-space-2);
}

/* Inline detail status / error lines under the actions. */
.kl-detail-pane .kl-error[b-9kceg8e18j],
.kl-detail-pane .kl-muted[b-9kceg8e18j] {
    margin: 0;
    font-size: 0.85rem;
}

/* R11 composed detail-pane empty state (no unit selected) — a centered disc + inline panel glyph + heading +
   guidance, matching the page-level kl-ou-empty caliber, so the right pane never reads as a bare void (skeptic
   R11 bar #5). Fills the pane height and centers, light/dark/outdoor via tokens. */
.kl-detail-empty[b-9kceg8e18j] {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: var(--k-space-3);
    min-block-size: 16rem;
    padding: var(--k-space-8, 2rem) var(--k-space-6);
}
.kl-detail-empty-disc[b-9kceg8e18j] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 64px;
    block-size: 64px;
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    color: var(--k-accent);
}
.kl-detail-empty-title[b-9kceg8e18j] {
    margin: 0;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--k-text);
}
.kl-detail-empty-msg[b-9kceg8e18j] {
    margin: 0;
    max-inline-size: 44ch;
    color: var(--k-text-muted);
    line-height: 1.55;
}

/* ---- Create / Move modal PANELS: the centered card look only. ----------------
   UI-GUAR-033: overlay/scrim retired — <KlOverlay> now supplies the fixed scrim +
   centering. These are <div role="dialog"> panels wrapped by <KlOverlay>, so the
   panel must NOT position itself — it is a plain card the overlay centers. The
   former scrim-free `position:fixed; inset:0` self-overlay (which double-painted
   the modal outside the scrim) is gone; the foundation .kl-dialog (no ::backdrop)
   supplies the base card and this scoped block keeps the local card rhythm. ------ */
.kl-dialog[b-9kceg8e18j] {
    inline-size: calc(100% - 2rem);
    max-inline-size: 32rem;
    block-size: fit-content;
    max-block-size: calc(100% - 2rem);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    padding: var(--k-space-6);
    background: var(--k-surface);
    color: var(--k-text);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-3);
    /* Calm rise-in (no bounce); disabled under reduced-motion below. */
    animation: kl-ou-rise-b-9kceg8e18j var(--k-dur-2, 200ms) var(--k-ease, ease) both;
}
/* Neutralize the foundation's <dialog>-oriented child padding (.kl-dialog > *):
   this container already owns its padding + gap, so the per-child inline padding
   would double up. The fields/notes/actions inside lay out on the flex column. */
.kl-dialog > *[b-9kceg8e18j] {
    padding: 0;
}
.kl-dialog-title[b-9kceg8e18j] {
    margin: 0;
    font-family: var(--k-font-display, system-ui, sans-serif);
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--k-text);
}
.kl-dialog-note[b-9kceg8e18j] {
    margin: 0;
    color: var(--k-text-muted);
    font-size: 0.9rem;
    line-height: 1.55;
}
.kl-dialog-actions[b-9kceg8e18j] {
    display: flex;
    justify-content: flex-end;
    gap: var(--k-space-3);
    margin-block-start: var(--k-space-2);
}

@keyframes kl-ou-rise-b-9kceg8e18j {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .kl-dialog[b-9kceg8e18j] {
        animation: none;
    }
}
/* _content/Kanine.Web/Components/Pages/OwnerFeedbackBoard.razor.rz.scp.css */
/* Phase-D WP8 — the operator feedback Kanban. Bare html.dark for dark overrides (the dead-rule trap:
   :global(html.dark) ships verbatim and the browser drops it). */

.kl-fb-board[b-w3fptvnzy6] {
    display: flex;
    gap: 0.75rem;
    align-items: stretch;   /* columns share a common height so the lanes read as one board, not ragged cards */
    overflow-x: auto;
    padding-bottom: 0.75rem;
    /* The lanes scroll sideways, so the board carries the shared §8b-s scroll cue. It takes the MASK
       variant, not the shadow one: the lanes are opaque --k-surface-2 slabs and paint over any background
       the container draws (measured: cue delta 0 with the shadows, before the swap).
       End padding >= the 28px fade depth, so at full scroll the fade sits over empty space and never dims
       the last lane. */
    padding-inline-end: 32px;
}

.kl-fb-column[b-w3fptvnzy6] {
    /* Grow to share the full page width (the page is now full-bleed, not capped at 1120px), but keep a sane
       floor so the lanes horizontally scroll instead of crushing when the viewport is genuinely narrow, and a
       ceiling so a handful of columns don't sprawl absurdly wide on an ultra-wide monitor. */
    flex: 1 1 240px;
    min-inline-size: 232px;
    max-inline-size: 360px;
    display: flex;
    flex-direction: column;
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: 8px;
    padding: 0.5rem;
}

.kl-fb-column-body[b-w3fptvnzy6] {
    /* Fill the stretched column height so short lanes don't leave the column looking half-empty. */
    flex: 1 1 auto;
}

.kl-fb-column-head[b-w3fptvnzy6] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.5rem;
}

.kl-fb-column-title[b-w3fptvnzy6] {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.04em;
}

/* Per-stage tints: the six lanes read left→right as a pipeline — inbox (info) → work (accent) →
   decision (caution emphasis) → landed (success family). Subtle top borders only, never loud fills. */
.kl-fb-column--new[b-w3fptvnzy6] { border-top: 3px solid color-mix(in srgb, var(--k-info) 55%, var(--k-border)); }
.kl-fb-column--triaged[b-w3fptvnzy6] { border-top: 3px solid color-mix(in srgb, var(--k-accent) 55%, var(--k-border)); }
.kl-fb-column--claude_proposed[b-w3fptvnzy6] { border-top: 3px solid var(--k-caution); }
.kl-fb-column--approved[b-w3fptvnzy6] { border-top: 3px solid color-mix(in srgb, var(--k-success) 45%, var(--k-border)); }
.kl-fb-column--merged[b-w3fptvnzy6] { border-top: 3px solid color-mix(in srgb, var(--k-success) 70%, var(--k-border)); }
.kl-fb-column--resolved[b-w3fptvnzy6] { border-top: 3px solid var(--k-success); }

/* Awaiting-your-decision emphasis: the CLAUDE_PROPOSED lane carries a quiet caution wash + its own header note. */
.kl-fb-column--decision[b-w3fptvnzy6] {
    background: color-mix(in srgb, var(--k-caution) 6%, var(--k-surface-2));
}

.kl-fb-column-note[b-w3fptvnzy6] {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    color: var(--k-caution);
    white-space: nowrap;
}

.kl-fb-card[b-w3fptvnzy6] {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: 6px;
    padding: 0.5rem;
    margin-bottom: 0.5rem;
    cursor: pointer;
    position: relative;
    font-size: 0.82rem;
}

/* A proposal awaiting the owner's ruling gets a subtle glow so the morning scan lands on it first. */
.kl-fb-card--proposed[b-w3fptvnzy6] {
    border-color: color-mix(in srgb, var(--k-caution) 60%, var(--k-border));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--k-caution) 35%, transparent),
                0 2px 10px -4px color-mix(in srgb, var(--k-caution) 45%, transparent);
}

/* Age heat on the intake lanes (NEW/TRIAGED): >72h amber, >168h red — pure class-driven left borders. */
.kl-fb-card--stale[b-w3fptvnzy6] {
    border-inline-start: 3px solid var(--k-caution);
}

.kl-fb-card--overdue[b-w3fptvnzy6] {
    border-inline-start: 3px solid var(--k-critical);
}

.kl-fb-card-snippet[b-w3fptvnzy6] {
    margin: 0.15rem 0;
    color: var(--k-text-muted);
    font-size: 0.78rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
}

.kl-fb-similar[b-w3fptvnzy6] {
    cursor: pointer;
    font: inherit;
    font-size: 0.72rem;
    border: 1px solid color-mix(in srgb, var(--k-info) 45%, var(--k-border));
    color: var(--k-info);
    background: color-mix(in srgb, var(--k-info) 8%, var(--k-surface));
}

.kl-fb-similar:hover[b-w3fptvnzy6] {
    background: color-mix(in srgb, var(--k-info) 16%, var(--k-surface));
}

/* NOTE: `.kl-fb-card-line` is used for SEVERAL lines of the card; only the first one also wears `.kl-cardline`
   (§A10's title line). The shared primitive supplies display/align-items/gap there and this rule's own values
   still serve the others, so nothing is duplicated — the shared selector is more specific and wins where it
   applies. `justify-content: space-between` is retained for the non-title lines it was written for; on the title
   line the shared rule's growing title makes it inert rather than wrong. */
.kl-fb-card-line[b-w3fptvnzy6] {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    justify-content: space-between;
    margin: 0.15rem 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The route is a single unbroken token, so it CLIPS rather than wrapping — the one place an off-table title
   behaves like a table one, and for the same reason (there is no word boundary to wrap at). */
.kl-fb-card-line.kl-cardline > .kl-tcard-title[b-w3fptvnzy6] {
    overflow: hidden;
    text-overflow: ellipsis;
}

.kl-fb-card-badges[b-w3fptvnzy6] {
    display: flex;
    gap: 0.25rem;
    flex-wrap: wrap;
}

.kl-fb-thumb[b-w3fptvnzy6] {
    width: 100%;
    border-radius: 4px;
    border: 1px solid var(--k-border);
}

.kl-fb-thumb--blocked[b-w3fptvnzy6] {
    padding: 0.5rem;
    font-size: 0.75rem;
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border: 1px dashed var(--k-border);
    border-radius: 4px;
}

.kl-fb-card-purge[b-w3fptvnzy6] {
    font-size: 0.75rem;
    color: var(--k-text-muted);
    margin-top: 0.25rem;
}

.kl-fb-card-actions[b-w3fptvnzy6] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.35rem;
}

/* The delete affordance: a quiet ghost button until armed, then a red confirm so the destructive click is
   unmistakable. `--k-critical` is the shared danger token (same one -delete buttons use elsewhere). */
.kl-fb-delete-btn[b-w3fptvnzy6] {
    margin-inline-start: auto;   /* push Delete to the trailing edge, away from the Move/Ask cluster */
    color: var(--k-critical);
}

.kl-fb-delete-confirm-wrap[b-w3fptvnzy6] {
    display: inline-flex;
    gap: 0.35rem;
    margin-inline-start: auto;
    align-items: center;
}

.kl-fb-delete-yes[b-w3fptvnzy6] {
    background: var(--k-critical);
    border-color: var(--k-critical);
    color: #fff;
}

.kl-fb-move-menu[b-w3fptvnzy6] {
    position: absolute;
    z-index: 30;
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: 6px;
    box-shadow: 0 6px 18px rgb(10 26 43 / 0.18);
    display: flex;
    flex-direction: column;
    min-width: 160px;
}

.kl-fb-move-item[b-w3fptvnzy6] {
    text-align: start;
    padding: 0.4rem 0.6rem;
    background: none;
    border: 0;
    cursor: pointer;
}

.kl-fb-move-item:hover[b-w3fptvnzy6] {
    background: var(--k-surface-2);
}

/* The digest strip — one calm row: big numbers, quiet labels, no dashboard kitsch. */
.kl-fb-digest[b-w3fptvnzy6] {
    display: flex;
    /* P5 (2026-07-24) — second contributor to the layout-viewport expansion: four nowrap items plus
       three 2rem gaps gave this strip a 384px min-content inside a 361px box. Wrapping costs one row
       on a phone and nothing at all above ~384px of room; the row gap is deliberately tighter than
       the column gap so the wrapped state stays compact (B1). */
    flex-wrap: wrap;
    gap: 0.5rem 2rem;
    align-items: baseline;
    padding: 0.6rem 0.9rem;
    margin-bottom: 0.75rem;
    border: 1px solid var(--k-border);
    border-radius: 8px;
    background: var(--k-surface-2);
}

.kl-fb-digest-item[b-w3fptvnzy6] {
    display: flex;
    align-items: baseline;
    gap: 0.45rem;
}

.kl-fb-digest-num[b-w3fptvnzy6] {
    font-size: 1.45rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.kl-fb-digest-label[b-w3fptvnzy6] {
    font-size: 0.75rem;
    color: var(--k-text-muted);
    letter-spacing: 0.02em;
}

.kl-fb-digest-item--decide .kl-fb-digest-num[b-w3fptvnzy6] {
    color: var(--k-caution);
    font-size: 1.7rem;
}

.kl-fb-digest-item--decide .kl-fb-digest-label[b-w3fptvnzy6] {
    color: var(--k-caution);
    font-weight: 600;
}

/* The dispatch-mode comfort strip — calm and legible, never buried. The state copy is the reassurance:
   Manual (the default) reads muted-safe; Auto earns a quiet caution tint so the owner always knows the
   system may act on its own. */
.kl-fb-dispatch[b-w3fptvnzy6] {
    display: flex;
    gap: 0.9rem;
    align-items: baseline;
    flex-wrap: wrap;
    padding: 0.55rem 0.9rem;
    margin-bottom: 0.75rem;
    border: 1px solid var(--k-border);
    border-radius: 8px;
    background: var(--k-surface-2);
}

.kl-fb-dispatch-toggle[b-w3fptvnzy6] {
    display: inline-flex;
    gap: 0.4rem;
    align-items: center;
    font-weight: 600;
    font-size: 0.85rem;
    cursor: pointer;
    white-space: nowrap;
}

.kl-fb-dispatch-state[b-w3fptvnzy6] {
    font-size: 0.8rem;
    color: var(--k-text-muted);
}

.kl-fb-dispatch-state--auto[b-w3fptvnzy6] {
    color: var(--k-caution);
    font-weight: 600;
}

.kl-fb-dispatch-help[b-w3fptvnzy6] {
    flex-basis: 100%;
    margin: 0;
    font-size: 0.73rem;
    color: var(--k-text-muted);
}

html.dark .kl-fb-dispatch[b-w3fptvnzy6] {
    background: #16222c;
    border-color: #2c3a45;
}

/* P5 (2026-07-24) — this row used to force the LAYOUT VIEWPORT open. It was a nowrap flex whose
   min-content was 615px (the 320px search floor + 3 severity chips + "Show closed" + two 1rem gaps)
   inside a 361px box, so on a 393px phone the browser widened the layout viewport to 631px — and
   every `max-width: 640px` rule on the page was then evaluated against that lie, silently never
   matching. `flex-wrap` + a shrinkable search floor is the fix; the desktop row is unchanged
   (the 20rem basis is the old 320px, and above ~615px of room nothing wraps). */
.kl-fb-toolbar[b-w3fptvnzy6] {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
    margin-bottom: 0.75rem;
}

.kl-fb-sevchips[b-w3fptvnzy6] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.kl-fb-search[b-w3fptvnzy6] {
    /* Basis = the old 320px, so the desktop row measures exactly as before; `min-inline-size: 0`
       lifts the flex-item automatic minimum so it can shrink on a phone instead of pushing the
       viewport open. NOT a touch-target change (A6): the input's block size is untouched. */
    flex: 0 1 20rem;
    min-inline-size: 0;
}

.kl-fb-parked[b-w3fptvnzy6] {
    margin-top: 1rem;
}

.kl-fb-parked-group[b-w3fptvnzy6] {
    margin-bottom: 0.5rem;
}

/* `.kl-fb-detail-panel` was REMOVED 2026-09-13 (D56-R residual 3). It styled the side detail panel the
   2026-07-08 owner ruling replaced with the full-screen `.kl-fb-detail-full` view below. No markup has
   carried the class since: the whole repo holds one authored occurrence, which was this rule.

   It is recorded here rather than deleted silently because its `max-height: 100vh` was 32px past the
   space the overlay leaves, and a reader who finds that value in the history should be able to tell a
   dead rule from a live overrun. */

.kl-fb-detail-dl[b-w3fptvnzy6] {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.2rem 0.75rem;
    font-size: 0.9rem;
}

.kl-fb-tabs[b-w3fptvnzy6] {
    display: flex;
    gap: 0.4rem;
    margin: 0.6rem 0;
}

.kl-fb-dom[b-w3fptvnzy6],
.kl-fb-bundle[b-w3fptvnzy6],
.kl-fb-diff[b-w3fptvnzy6] {
    max-height: 320px;
    overflow: auto;
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: 6px;
    padding: 0.5rem;
    font-size: 0.75rem;
    white-space: pre-wrap;
    word-break: break-word;
}

.kl-fb-detail-shot[b-w3fptvnzy6] {
    max-width: 100%;
    border: 1px solid var(--k-border);
    border-radius: 6px;
}

/* Hide the native "Choose file / no file chosen" control. It is rendered by the <InputFile> COMPONENT, so a
   plain scoped rule never reaches it (CSS isolation doesn't stamp the scope onto a child component's output) —
   ::deep crosses that boundary. Clicking the styled label still opens the picker (a <label> wrapping the
   input triggers it even while the input is display:none). */
.kl-fb-import-label[b-w3fptvnzy6]  .kl-fb-import-input {
    display: none;
}

/* The .kfb import control reads as a proper dashed "drop a file here" affordance rather than a bare ghost
   button — an upload glyph, a monospace extension pill, and a calm hover-lift so it invites the (rare) air-gap
   import without competing with the board's primary card work. Content is centered both ways in the box. */
.kl-fb-import-label[b-w3fptvnzy6] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 9.5rem;
    min-height: 2.4rem;
    gap: 0.45rem;
    padding: 0.4rem 0.85rem;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--k-text-muted, #64748b);
    background: var(--k-surface-2, #f8fafc);
    border: 1px dashed var(--k-border, #cbd5e1);
    border-radius: 8px;
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease, background .15s ease, transform .1s ease;
}

.kl-fb-import-label:hover[b-w3fptvnzy6] {
    color: var(--k-accent, #0d9488);
    border-color: var(--k-accent, #0d9488);
    background: var(--k-surface, #fff);
    transform: translateY(-1px);
}

.kl-fb-import-label:focus-within[b-w3fptvnzy6] {
    outline: 2px solid var(--k-accent, #0d9488);
    outline-offset: 2px;
}

.kl-fb-import-label .ki[b-w3fptvnzy6] {
    font-size: 1rem;
    line-height: 1;
}

.kl-fb-import-ext[b-w3fptvnzy6] {
    font-family: var(--k-font-mono, ui-monospace, monospace);
    font-size: 0.8rem;
    padding: 0.05rem 0.3rem;
    border-radius: 4px;
    background: var(--k-surface-3, #eef2f6);
    color: var(--k-text, #334155);
}

html.dark .kl-fb-import-label[b-w3fptvnzy6] {
    color: #94a3b8;
    background: rgba(148, 163, 184, 0.08);
    border-color: #3a4a5e;
}

html.dark .kl-fb-import-label:hover[b-w3fptvnzy6] {
    color: var(--k-accent, #2dd4bf);
    border-color: var(--k-accent, #2dd4bf);
    background: rgba(148, 163, 184, 0.04);
}

html.dark .kl-fb-import-ext[b-w3fptvnzy6] {
    background: rgba(148, 163, 184, 0.16);
    color: #cbd5e1;
}

.kl-fb-reject[b-w3fptvnzy6],
.kl-fb-verify[b-w3fptvnzy6],
.kl-fb-park[b-w3fptvnzy6] {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.4rem;
}

html.dark .kl-fb-column[b-w3fptvnzy6] {
    background: #16222c;
    border-color: #2c3a45;
}

html.dark .kl-fb-column--decision[b-w3fptvnzy6] {
    background: color-mix(in srgb, var(--k-caution) 10%, #16222c);
}

html.dark .kl-fb-digest[b-w3fptvnzy6] {
    background: #16222c;
    border-color: #2c3a45;
}

html.dark .kl-fb-similar[b-w3fptvnzy6] {
    background: color-mix(in srgb, var(--k-info) 14%, #101a22);
}

html.dark .kl-fb-card[b-w3fptvnzy6],
html.dark .kl-fb-move-menu[b-w3fptvnzy6] {
    background: #101a22;
    border-color: #2c3a45;
}

html.dark .kl-fb-dom[b-w3fptvnzy6],
html.dark .kl-fb-bundle[b-w3fptvnzy6],
html.dark .kl-fb-diff[b-w3fptvnzy6],
html.dark .kl-fb-thumb--blocked[b-w3fptvnzy6] {
    background: #16222c;
    border-color: #2c3a45;
}

/* Phase G R5 — the reporter-rejection treatment: the red UNRESOLVED badge + the "what's still wrong" quote on
   HUMAN_REVIEW cards, and a red column accent so an escalated ticket cannot hide at the board's right edge. */
.kl-fb-chip--unresolved[b-w3fptvnzy6] {
    background: color-mix(in srgb, #cf222e 16%, transparent);
    color: #cf222e;
    font-weight: 700;
    letter-spacing: 0.03em;
}

html.dark .kl-fb-chip--unresolved[b-w3fptvnzy6] {
    color: #f85149;
}

/* Runner observability strip (013_runner_heartbeat.sql): a quiet row of who's online + what they're on. */
.kl-fb-runners[b-w3fptvnzy6] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.25rem 0 0.75rem;
    font-size: 0.82rem;
    color: var(--k-text-muted);
}

.kl-fb-runners-label[b-w3fptvnzy6] {
    font-weight: 600;
}

.kl-fb-runner-chip[b-w3fptvnzy6] {
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--k-text-muted) 12%, transparent);
    white-space: nowrap;
}

.kl-fb-runner-chip--working[b-w3fptvnzy6] {
    background: color-mix(in srgb, #1a7f37 16%, transparent);
    color: #1a7f37;
    font-weight: 600;
}

html.dark .kl-fb-runner-chip--working[b-w3fptvnzy6] {
    color: #3fb950;
}

/* Reconciler needs-attention flag (012_reconcile.sql): an amber, deliberately prominent chip — an ambiguous
   card/task drift the reconciler declined to auto-move, awaiting the operator's (or the board-doctor's) call. */
.kl-fb-chip--attention[b-w3fptvnzy6] {
    background: color-mix(in srgb, #bf8700 20%, transparent);
    color: #9a6700;
    font-weight: 700;
    letter-spacing: 0.02em;
}

html.dark .kl-fb-chip--attention[b-w3fptvnzy6] {
    color: #e3b341;
}

.kl-fb-card-rejection[b-w3fptvnzy6] {
    margin-top: 0.35rem;
    padding: 0.35rem 0.5rem;
    border-left: 3px solid #cf222e;
    border-radius: 4px;
    background: color-mix(in srgb, #cf222e 7%, transparent);
    font-style: italic;
    font-size: 0.85rem;
}

.kl-fb-column--human_review .kl-fb-column-head[b-w3fptvnzy6] {
    border-bottom: 2px solid #cf222e;
}

/* Phase G — the PENDING_CONFIRMATION column reads as a calm waiting state (customer gate, no operator action). */
.kl-fb-column--pending_confirmation .kl-fb-column-title[b-w3fptvnzy6] {
    color: var(--k-text-muted);
}

/* Phase G WP-G5 — the addendum countersign queue (the one operator ceremony, R9). */
.kl-fb-countersign[b-w3fptvnzy6] {
    margin-top: 1.25rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--k-border);
    border-left: 4px solid #bf8700;
    border-radius: 8px;
}

.kl-fb-countersign h2[b-w3fptvnzy6] {
    font-size: 1rem;
    margin: 0 0 0.6rem;
}

.kl-fb-countersign-card[b-w3fptvnzy6] {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.5rem 0;
    border-top: 1px solid var(--k-border);
}

.kl-fb-countersign-meta[b-w3fptvnzy6] {
    font-size: 0.85rem;
    color: var(--k-text-muted);
}

.kl-fb-countersign-actions[b-w3fptvnzy6] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-size: 0.85rem;
}

/* Phase G WP-G7 — the "Shipped with data" release list. */
.kl-fb-cjis[b-w3fptvnzy6] {
    margin-top: 1.25rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--k-border);
    border-left: 4px solid #8250df;
    border-radius: 8px;
}

.kl-fb-cjis h2[b-w3fptvnzy6] {
    font-size: 1rem;
    margin: 0 0 0.6rem;
}

.kl-fb-cjis-card[b-w3fptvnzy6] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.45rem 0;
    border-top: 1px solid var(--k-border);
}

/* Full-screen ticket view (owner-directed 2026-07-08 — replaces the end drawer). */
.kl-fb-detail-full[b-w3fptvnzy6] {
    /* The design-system .kl-dialog clamps panels to 30rem (max-inline-size) — a full-screen ticket view must
       defeat BOTH axes explicitly or it renders as a centered card. */
    max-inline-size: none;
    inline-size: min(1600px, 97vw);
    width: min(1600px, 97vw);
    /* A FILL, not a cap: this panel is the same height empty as it is saturated, because the owner
       asked for a ticket view that takes the whole viewport. So the fix is NOT to delete the
       declaration and inherit .kl-dialog's cap — that would let an empty ticket collapse to its
       header. It is to fill the same budget .kl-dialog caps to.
       `height: 95vh` came in on 2026-07-08, SIXTEEN DAYS BEFORE the shared cap existed (219a2253,
       2026-07-24), so it was never an opt-out from it. 95vh exceeds `100vh - 2 * var(--k-space-4)`
       on every viewport under 640px tall, which is every phone in landscape: measured 2026-09-13
       this panel rendered 342px into 328px of space at 780x360 WITH NO CONTENT AT ALL.
       The vh line is the fallback for engines without dvh, exactly as §5i writes it. The cap comes
       from .kl-dialog and is not restated here — one budget, one place. */
    block-size: calc(100vh - 2 * var(--k-space-4));
    block-size: calc(100dvh - 2 * var(--k-space-4));
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}

.kl-fb-detail-full-head[b-w3fptvnzy6] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--k-border);
    flex: 0 0 auto;
}

.kl-fb-detail-full-title[b-w3fptvnzy6] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    min-width: 0;
}

.kl-fb-detail-full-meta[b-w3fptvnzy6] {
    font-size: 0.8rem;
    color: var(--k-text-muted);
    white-space: nowrap;
}

.kl-fb-detail-close[b-w3fptvnzy6] {
    white-space: nowrap;
}

.kl-fb-detail-full-body[b-w3fptvnzy6] {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1rem 1.25rem 1.5rem;
}

/* Reporter reply round-trip — the card-face "reporter replied" badge. */
.kl-fb-chip--reply[b-w3fptvnzy6] {
    background: #e4eefb;
    color: var(--k-accent, #26538c);
    font-weight: 600;
}

/* Rescind — the withdrawn-report badge (muted amber, distinct from the red UNRESOLVED). */
.kl-fb-chip--rescinded[b-w3fptvnzy6] {
    background: #f4e4c1;
    color: #8a5a00;
    font-weight: 700;
    letter-spacing: 0.02em;
}

/* Star — the per-person gold outline + the small star chip. */
.kl-fb-card--starred[b-w3fptvnzy6] {
    outline: 2px solid #e3b341;
    outline-offset: -1px;
    box-shadow: 0 0 0 1px #e3b341 inset;
}

.kl-fb-chip--starred[b-w3fptvnzy6] {
    background: #fbf1d3;
    color: #8a6d1f;
    font-weight: 700;
}

/* Drag note-prompt modal (owner-directed 2026-07-12) — a note-required drag collects its reason here. */
.kl-fb-dropnote[b-w3fptvnzy6] {
    max-inline-size: 30rem;
    padding: 1.1rem 1.25rem;
}

.kl-fb-dropnote-text[b-w3fptvnzy6] {
    inline-size: 100%;
    box-sizing: border-box;
    resize: vertical;
    font: inherit;
    padding: 0.5rem 0.65rem;
    border: 1px solid var(--k-border, #cfd6df);
    border-radius: 6px;
    margin: 0.5rem 0 0.75rem;
}

.kl-fb-dropnote-actions[b-w3fptvnzy6] {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

/* Re-queue escape hatch on a Discovery card's Claude tab. */
.kl-fb-claude-requeue[b-w3fptvnzy6] {
    margin-top: 0.9rem;
    padding-top: 0.75rem;
    border-top: 1px dashed var(--k-border, #d8dee6);
}

/* Move-confirm consequence text (owner-directed 2026-07-12) — benign help vs a real-consequence warning. */
.kl-fb-moveconfirm-consequence[b-w3fptvnzy6] {
    margin: 0.4rem 0 0.6rem;
    padding: 0.5rem 0.65rem;
    border-radius: 6px;
    font-size: 0.88rem;
    background: var(--k-surface-2, #f4f6f9);
    color: var(--k-text, #2a2f36);
    border-inline-start: 3px solid var(--k-border, #cfd6df);
}

.kl-fb-moveconfirm-consequence.is-consequential[b-w3fptvnzy6] {
    background: #fdf3e6;
    color: #7a4a12;
    border-inline-start-color: #d98a2b;
}

@media (prefers-color-scheme: dark) {
    .kl-fb-moveconfirm-consequence.is-consequential[b-w3fptvnzy6] { background: #3a2a14; color: #f0c98a; border-inline-start-color: #d98a2b; }
}
/* _content/Kanine.Web/Components/Pages/RecordReview.razor.rz.scp.css */
/* =============================================================================
   RecordReview (record-view.html) — HOST-CHROME scoped CSS. The read-only document
   body's styling (identity header + status medallion, summary grid, story-index,
   narrative/weather, drill-in, attachments, Involved collections) moved WITH the
   shared component into Kanine.Presentation/Lifecycle/RecordDetailBody.razor.css so
   both heads render it identically. What stays here is the web HOST's chrome only:
   the page eyebrow + the ONE compiled command bar (the shared lifecycle action bar
   composed with the host Edit / Print-Export). Tokens only (--k-*); no off-token
   colour and no generic gradient (those red the central R11 objective teeth).
   ========================================================================== */

/* The page label reads as a quiet eyebrow so the envelope header CARD becomes the
   document cover (the record is the document; this is just the section label).

   It is ALSO the reserved home of the lifecycle refusal message (owner ruling
   2026-07-27 — see the .kl-actionbar-message block below): the row is laid out as a
   flex line with a min-block-size big enough to hold a one-line banner, so the
   message paints BESIDE "RECORD REVIEW" instead of inside the command card. The
   space is reserved permanently and is simply empty until a refusal happens, which
   is what makes it impossible for the message to move anything when it appears. */
.kl-rv-eyebrow[b-z6do6blcp0] {
    font-family: var(--k-font-ui);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--k-text-muted);
    display: flex;
    align-items: center;
    /* 3rem clears a one-line kl-failure (12+12 padding + 21 line-box + 2 border = 47px). */
    min-block-size: 3rem;
    margin: 0 0 var(--k-space-2);
}

/* ── ONE COMPILED ACTION CLUSTER (owner direction 2026-06-26) ───────────────────────────────────────────────────
   The single cohesive command bar at the top of the screen: the SHARED lifecycle action bar (status badge +
   Complete/Approve/Reject/Reopen + soft-delete, inside RecordReviewSurface) composed with the host-level Edit +
   Print/Export — all on ONE elevated band so status + actions read as a command header above the read-only body.
   Composition is layout + scoped ::deep only (the shared component is NOT restructured; its data-status /
   data-action / kl-badge hooks are untouched). Tokens only (--k-*). */
.kl-rv-commandbar[b-z6do6blcp0] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-3);
    /* The containing block for the out-of-flow refusal slots (owner ruling 2026-07-27): the message is anchored to
       the CARD, not to the action bar inside it, so it can be lifted clear of the card onto the header row. */
    position: relative;
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-3) var(--k-space-6);
    margin-block-end: var(--k-space-4);
}

/* The shared surface contributes the visible status badge + the lifecycle buttons (+ soft-delete) — lay its
   kl-record body out INLINE so it reads as part of the command bar (it is otherwise a bare block). The single
   visible status badge (span.kl-badge[data-status]) the e2e suite asserts is the one this surface renders. */
.kl-rv-commandbar[b-z6do6blcp0]  .kl-record {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2) var(--k-space-3);
    flex: 1 1 auto;
    min-inline-size: 0;
    margin: 0;
}

/* The lifecycle action bar inside the surface: an inline button group within the command bar — drop the
   stand-alone "-actionbar" base treatment (full-width space-between + bottom rule + block padding/margin). */
.kl-rv-commandbar[b-z6do6blcp0]  .kl-actionbar {
    border-block-end: none;
    padding: 0;
    margin: 0;
    gap: var(--k-space-2);
    justify-content: flex-start;
}

/* The reason capture drops to its OWN full-width row inside the command bar (so a reason input is never squeezed
   beside the buttons). The failure banner used to be listed here too — it is no longer in flow at all; see below. */
.kl-rv-commandbar[b-z6do6blcp0]  .kl-reason {
    flex-basis: 100%;
}

/* ── THE REFUSAL MESSAGE, ON THE HEADER ROW (owner ruling 2026-07-27) ───────────────────────────────────────────
   "A valid re-entered step-up credential is required to sign this action." used to render inline inside the
   lifecycle action bar, in flow. It grew the bar's intrinsic width and added a line, so the command row re-wrapped
   and Delete + "Edit record" dropped to a second row — controls moving under the cursor at the moment of refusal.
   The banner now paints on the "RECORD REVIEW" header row above this card, exactly as the ruling suggested.

   HOW THE ROW IS GUARANTEED NOT TO REFLOW — two independent halves, both required:
     1. STRUCTURE (shared): the slot is rendered UNCONDITIONALLY by LifecycleActionBar / RecordDeleteAction, so the
        bar's child list is byte-identical with and without a message. There is no @if to change the DOM.
     2. LAYOUT (here + §5g-1): the slot is absolutely positioned, so it is not a flex item of anything — it cannot
        add a line, cannot widen a shrink-to-fit item, cannot consume a gap. The guarantee is unconditional; it does
        not depend on the message being short enough for a reservation.
   The header row's min-block-size (.kl-rv-eyebrow above) is only about not OVERLAPPING the eyebrow — it is not
   what keeps the buttons still.

   The `position: static` reset is load-bearing: the shared sheet makes .kl-record the default containing block, so
   without this the message would anchor to the surface INSIDE the card and paint over the card's own top edge.
   Scoped ::deep compiles to `.kl-rv-commandbar[b-…] .kl-record` (0,3,0), which outranks the sheet's (0,2,0). */
.kl-rv-commandbar[b-z6do6blcp0]  .kl-record {
    position: static;
}

/* The LIFECYCLE refusal — the one in the sign-and-seal film — takes the header row per the ruling. Its bottom edge
   sits just above the card, so the banner grows UPWARD into the reserved strip: a message that wraps eats header
   whitespace rather than pushing the card down. Right-aligned so it never collides with the "RECORD REVIEW" label. */
.kl-rv-commandbar[b-z6do6blcp0]  .kl-actionbar-message {
    inset-block-end: calc(100% + var(--k-space-2));
    inset-inline: auto 0;
}

/* The soft-DELETE refusal goes directly BELOW the card rather than sharing the header strip. Two absolutely
   positioned boxes cannot stack themselves, and these two are independent states — a refused Complete and a refused
   Delete can both be showing (neither clears the other) — so parking both in one strip would let one alert cover
   the other, which is exactly the "do not weaken the message" failure. Below the card the two can never collide,
   and it puts the message immediately under the Delete control that produced it. */
.kl-rv-commandbar[b-z6do6blcp0]  .kl-deleteaction-message {
    inset-block: calc(100% + var(--k-space-2)) auto;
    inset-inline: 0;
    inline-size: auto;
}

@media (max-width: 640px) {
    /* Phone: the card is too narrow for the lifecycle message to sit BESIDE the eyebrow, so it takes the full width
       above the card and the reservation is given back. At this width a refusal wraps to ~2 lines and therefore
       overlays the eyebrow label rather than reserving room for it — a transient alert briefly covering a static
       section label is a better trade than 4-plus rem of permanent dead space above every record on a phone. It is
       still out of flow, so the command row is exactly as immovable here as it is at desktop. */
    .kl-rv-eyebrow[b-z6do6blcp0] {
        min-block-size: 0;
        margin-block-end: var(--k-space-4);
    }

    .kl-rv-commandbar[b-z6do6blcp0]  .kl-actionbar-message {
        inset-inline: 0;
        inline-size: auto;
        max-inline-size: none;
    }

    .kl-rv-commandbar[b-z6do6blcp0]  .kl-deleteaction-message {
        max-inline-size: none;
    }
}

/* The record-type meta echo ("DEPLOYMENT") the shared surface renders is REDUNDANT here — the identity header
   already shows the human record-type label (the kl-chip "Deployment"). Hide the raw-code echo (the data-field
   hook stays in the DOM for the REL-012 parity assertions, which render the component in isolation; this is
   presentation-only on this page, not a structural change to the shared component). */
.kl-rv-commandbar[b-z6do6blcp0]  .kl-record-meta {
    display: none;
}

/* The host-level cluster (Edit / read-only note + Print) sits at the FAR end of the command bar. */
.kl-rv-commandbar-host[b-z6do6blcp0] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
    margin-inline-start: auto;
}

/* Dark: keep the command bar's elevation/border legible on the dark canvas (the foundation flips the tokens). */
html.dark .kl-rv-commandbar[b-z6do6blcp0] {
    box-shadow: var(--k-elev-1);
    border-color: var(--k-border);
}

.kl-rv-edit[b-z6do6blcp0] {
    /* primary colour + sizing come from the foundation kl-btn--primary; this only keeps the glyph/text aligned */
    display: inline-flex;
    align-items: center;
}

.kl-rv-readonly-note[b-z6do6blcp0] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    margin: 0;
    font-size: 14px;
    color: var(--k-text-muted);
}

/* The Print / Export control (a kl-btn--secondary) reads as part of the host command cluster — an inline button
   beside the Edit / read-only note within the one command bar, so it carries no stand-alone block margin. */
.kl-print-export[b-z6do6blcp0] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
}

/* REC-030 "Save as template": the same inline command-cluster button as Print / Export (glyph and text aligned). */
.kl-rv-savetemplate[b-z6do6blcp0] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
}

/* REC-030: the note after a successful "Save as template". It uses the read-only note's type scale and adds the
   link to the Templates screen. It wraps at phone width, so the link never forces a horizontal scroll. */
.kl-rv-template-saved[b-z6do6blcp0] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
    margin: 0;
    font-size: 14px;
    color: var(--k-text-muted);
}

/* ── NARROW-WIDTH "More actions" OVERFLOW (owner request, live review 2026-07-23) ───────────────────────────────
   Edit record / Print-Export / Build court packet collapse into ONE disclosure at <=640px (the design system's
   phone breakpoint — see kanine-design-system.css / the *.razor.css "mobile sweep" rules) so the command card
   stays a SINGLE row tall on a phone; Complete/Delete (the shared RecordReviewSurface) are never touched — they
   stay directly visible at every width. A plain <div> pair (RecordReview.razor's _moreOpen Blazor state — NOT the
   shell account menu's native <details>: a real Chromium <details>/summary uses an internal ::details-content box
   for its collapse/expand animation that a plain `display:contents` override on the panel could NOT fully
   neutralize — the flex container collapsed to a 0x0 box even though its (correctly `display:inline-flex`)
   grandchildren measured a real size, so the buttons were computed-visible but never actually laid out. A plain
   div has no such native collapse machinery, so display:contents dissolves it cleanly.) AT DESKTOP (the default,
   no media query below) the trigger is hidden and the panel DISSOLVES via display:contents regardless of
   _moreOpen, so the SAME Edit/Print-Export/packet buttons render as plain flex items of .kl-rv-commandbar-host —
   byte-identical to the pre-existing desktop layout. The trigger + dropdown chrome only actually paints <=640px,
   where the panel defaults to display:none and only shows (as an absolutely-positioned dropdown) while .is-open
   (the _moreOpen-driven class) is present. */
.kl-rv-more[b-z6do6blcp0] {
    display: contents;
}

.kl-rv-more-trigger[b-z6do6blcp0] {
    display: none;
}

.kl-rv-more-panel[b-z6do6blcp0] {
    display: contents;
}

@media (max-width: 640px) {
    .kl-rv-more[b-z6do6blcp0] {
        display: inline-block;
        position: relative;
    }

    /* ICON-ONLY at narrow widths (the RowContextMenu kebab precedent — .kl-rowmenu-kebab): a full "More actions"
       text label alongside Complete/Delete does not fit a phone-width row, which just re-creates the two-row
       problem one level down. The accessible name survives via aria-label/title (visible text is not required for
       a real <button>'s name); the visible glyph is the SAME ki-ms-more-vert kebab RowContextMenu already uses. */
    .kl-rv-more-trigger[b-z6do6blcp0] {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-block-size: var(--k-touch, 44px);
        min-inline-size: var(--k-touch, 44px);
        padding: 0;
        gap: 0;
    }

    .kl-rv-more-trigger .kl-rv-more-label[b-z6do6blcp0] {
        /* visually hidden, not display:none: keeps the string in the accessibility tree/DOM text content as a
           second, redundant name source alongside aria-label, rather than deleting it outright. */
        position: absolute;
        inline-size: 1px;
        block-size: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    .kl-rv-more-panel[b-z6do6blcp0] {
        display: none;
        position: absolute;
        inset-block-start: calc(100% + var(--k-space-1));
        inset-inline-end: 0;
        z-index: 50;
        flex-direction: column;
        gap: var(--k-space-2);
        min-inline-size: 12rem;
        max-inline-size: min(20rem, calc(100vw - var(--k-space-4)));
        background: var(--k-surface);
        color: var(--k-ink-900, #10233d);
        border: 1px solid var(--k-border);
        border-radius: var(--k-radius-md);
        box-shadow: 0 8px 24px rgb(0 0 0 / .18);
        padding: var(--k-space-2);
    }

    .kl-rv-more-panel.is-open[b-z6do6blcp0] {
        display: flex;
    }

    /* Inside the open panel the relocated buttons stack full-width as menu rows rather than an inline cluster. */
    .kl-rv-more-panel.is-open .kl-btn[b-z6do6blcp0] {
        inline-size: 100%;
        justify-content: flex-start;
    }
}

/* Dark: the panel's own surface/border/shadow tokens already flip with the foundation; nothing extra needed here
   beyond the same elevation the account-menu panel keeps legible on the dark canvas. */
html.dark .kl-rv-more-panel.is-open[b-z6do6blcp0] {
    box-shadow: var(--k-elev-2, 0 8px 24px rgb(0 0 0 / .4));
}

/* ── RECORD HISTORY (owner ruling 2026-09-14, "i cant sign a page off with empty history") ──────────────────
   The record's own app.record_lifecycle_audit trail, mounted as the shared EntityHistoryPanel below the
   document body.

   WHY THIS BLOCK EXISTS AT ALL. The section was added with FOUR classes and no rule anywhere reached one of
   them: `kl-rv-history`, `-head`, `-title` and `-lede` were all bare. That is conformance by ABSENCE — the
   exact shape `unstyled-class-scan.mjs` was written to find. An unstyled `<section>` is a plain block, so it
   passes the wrap and overflow sweeps by having no rule to violate, and it renders as unframed text hanging
   off the bottom of a page whose every other block is a card. Measured on the live host 2026-09-14.

   The treatment is COPIED, not invented: it is the same surface/border/radius/elevation/padding the document
   body's own cards use (`.kl-rv-narrative`), and the same head rule (`.kl-rv-linked-head`). Those live in
   RecordDetailBody's SCOPED sheet, which cannot reach this component — a scoped rule styles its own component
   and nobody else (the `kl-badge` trap). So the values are restated here rather than shared by accident.

   NAMING. `-head` and not `-header`, `-lede` and not `-note`: `[class$="-header"]` and `[class$="-note"]` are
   live unscoped foundation families keyed on where the whole class ATTRIBUTE ends, and a class that ends in a
   family word silently joins that family's padding, surface and border. Fifteen defects in this campaign came
   from that trap, and the house fix is always to rename off the family word — never `!important`. */
.kl-rv-history[b-z6do6blcp0] {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-6);
    margin-block-end: var(--k-space-4);
}

.kl-rv-history-head[b-z6do6blcp0] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--k-space-3);
    margin-block-end: var(--k-space-4);
    padding-block-end: var(--k-space-3);
    border-block-end: 1px solid var(--k-border);
}

.kl-rv-history-title[b-z6do6blcp0] {
    font-family: var(--k-font-display);
    font-size: 16px;
    font-weight: 700;
    line-height: 1.3;
    margin: 0;
    color: var(--k-text);
}

/* The standing sentence about WHAT this ledger records and that it is append-only. It sits above the table
   rather than under it: a reader who finds one row needs to know the trail is complete before they read it. */
.kl-rv-history-lede[b-z6do6blcp0] {
    margin: 0 0 var(--k-space-4);
    color: var(--k-text-muted, #5b6169);
    font-size: 14px;
    line-height: 1.55;
}

/* ── OWNER RULING 2026-09-16 (D75 #9) — the printed record is the SHEET document, never the review workspace ───────
   Print preview hides the workspace on screen and unparks the sheets (RecordReview.razor, .kl-rv-print). On paper the
   page heading and the workspace are hidden whenever the sheets exist. A heading left above the first sheet would push
   that sheet past the foot of the paper and add a page the screen never showed. */
.kl-rv-screen[data-print-preview="open"][b-z6do6blcp0] {
    display: none;
}

.kl-rv-printbar[b-z6do6blcp0] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin-block-end: var(--k-space-4);
}

@media print {
    .kl-rv-eyebrow[data-print-twin="true"][b-z6do6blcp0],
    .kl-rv-screen[data-print-twin="true"][b-z6do6blcp0] {
        display: none;
    }

    .kl-rv-print[b-z6do6blcp0] {
        margin: 0;
        padding: 0;
    }
}
/* _content/Kanine.Web/Components/Pages/ReliabilityDashboard.razor.rz.scp.css */
/* =============================================================================
   ReliabilityDashboard — R11 page-scoped refinement (UI-GUAR-011, restrained-premium)
   -----------------------------------------------------------------------------
   The ONE reliability surface (2026-07-19 merge of AgencyDashboard into this
   page): a scope/filter bar + "More filters" off-canvas drawer, and a body that
   switches on grain — the unit-wide rollup tiles + sortable per-K9 table at "All
   units", the subject hero + that unit's tiles at single-K9. The metric-tile card
   skin itself now lives ONCE in MetricTileGrid.razor.css (it was duplicated here
   and in AgencyDashboard.razor.css); this sheet keeps only what the page frame
   needs. Consumes the foundation vocabulary (kl-page measure, kl-section-head/
   -count/-title, kf-field/-label/-select/-input, kl-btn, kl-chip variants). No
   off-token colour, no gradient, no body-bg change — light/dark/outdoor ride the
   foundation's flipping --k-* channels.
   ========================================================================== */

.kl-sr-only[b-218m7accqd] {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* The committed-scope test-observability hooks stay in the DOM (tests read their data-* via
   GetAttribute) but must never occupy layout — as empty flex children of .kl-page they would
   otherwise inject phantom row-gaps into the section rhythm. display:none removes them from flow
   without affecting attribute reads. */
.kl-rel-committed[b-218m7accqd] { display: none; }

/* Eyebrow next to the page H1 (the RPT-009 provenance line; its text follows the current grain). */
.kl-rel-eyebrow[b-218m7accqd] {
    font-size: 13px;
    font-weight: 600;
    color: var(--k-text-muted);
    letter-spacing: .01em;
    align-self: center;
}

/* ---- Filter bar = THE QUERY CARD'S HEADER LINE ------------------------------
   `.kl-rel-bar` IS GONE, and its card chrome with it. It declared background, border, radius, elevation and
   padding by hand; every one of those now comes from kanine-design-system.css §9
   (`.kl-shell-main .kl-qcard > .kl-searchbar`), which also paints the 2px brand eyebrow across the top of the
   MERGED card and squares off the bottom corners while the panel is open. Re-declaring any of it here would be
   the drift Req_QueryCardPlacementTests.QueryCardCss_LivesOnlyInTheSharedSheet exists to stop, and the shared
   selector is (0,3,0) so a page-scoped copy would lose anyway.

   WHAT IS LEFT IS THE ONE THING THE SHARED RULE CANNOT KNOW: the shared header is a WRAPPING FLEX ROW, and this
   page puts two full-width bands on it — the control line, and the applied-chip row under it. Each claims the
   whole line so the row wraps between them instead of trying to seat them side by side. */
.kl-rel-headline > .kl-rel-barline[b-218m7accqd],
.kl-rel-headline > .kl-rel-chips[b-218m7accqd] {
    flex: 1 1 100%;
    min-inline-size: 0;
}
/* THE HEADER LINE - renamed OUT of the `-row` family, and that is a fix, not a tidy.

   It was `.kl-rel-bar-row`. Its class ATTRIBUTE ends in `-row`, so kanine-design-system.css §5l
   (`:where([class^="kl-"],[class*=" kl-"])[class$="-row"]`, the LIST-ROW family) matched it at (0,2,0) and gave it
   `padding: var(--k-space-3) var(--k-space-4)`, `background: var(--k-surface)`, `border: 1px solid var(--k-border)`
   and `border-radius: var(--k-radius-md)`. The page's own rule below is also (0,2,0) and later in source, so it won
   `display` / `align-items` / `gap` and silently lost the other four - the family's box treatment stayed.

   The result, measured live at 1400 before the rename: the query card's header line was painted as a SECOND card
   INSIDE the filter card - `padding 12px 16px`, `border 1px solid rgb(194,204,217)`, `border-radius 8px`,
   `background rgb(255,255,255)` - costing 26px of block space and 32px of inline space at EVERY width, on the one
   region of this page a reviewer had just asked to make smaller. The row measured 95px tall around a tallest child
   of 69.

   This is the THIRD trap-T7 capture found on this page in one pass (the others: `kl-rel-field--toggle` into the
   §5m switch family, which malformed the approved-only control; and `kl-mtile-id` into the §1049 `-id` family,
   which was benign). It was pre-existing and nobody had reported it, because a card border inside a card border
   reads as deliberate. `-barline` matches no family in the shared sheet's suffix census. */
.kl-rel-barline[b-218m7accqd] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--k-space-3);
}
.kl-rel-field[b-218m7accqd] {
    margin-block-end: 0;
    min-inline-size: 10rem;
    flex: 1 1 10rem;
}
/* The GRAIN control earns more width than a peer filter — it carries "call-name — handler" labels
   and it is the one control that changes what the page IS. */
.kl-rel-field--scope[b-218m7accqd] {
    flex: 0 1 18rem;
    min-inline-size: 12rem;
}
.kl-rel-k9[b-218m7accqd] { max-inline-size: 22rem; }
.kl-rel-field--date[b-218m7accqd] {
    flex: 0 1 9rem;
    min-inline-size: 9rem;
}
/* The modifier `kl-rel-field--toggle` IS GONE, together with the wrapper that carried it.

   THE DEFECT IT CAUSED, recorded so nobody reintroduces the name. The markup was
   `<div class="kf-field kl-rel-field kl-rel-field--toggle">` holding a "Scope" label and the
   approved-only pill. The class ATTRIBUTE ends in `-toggle`, so kanine-design-system.css §5m
   (`.kl-shell-main :where([class^="kl-"],[class*=" kl-"])[class$="-toggle"]`, the switch-TRACK family)
   matched the WRAPPER at (0,2,0) and gave it `min-block-size: var(--k-touch)`, `padding: 0 var(--k-space-3)`,
   `background: var(--k-surface-2)`, `border: 1px solid var(--k-border)` and `border-radius: var(--k-radius-full)`.
   §5b's `-field` family (also (0,2,0), earlier in source) still supplied `flex-direction: column`, because §5m
   declares no direction. So the wrapper rendered as a 240x77 rounded pill, laid out as a COLUMN, with the word
   "Scope" sitting hard against its own top border and a second, real pill underneath it.

   Measured live before the fix, at 1400 and at 393 alike: background rgb(238,242,247),
   border 1px solid rgb(194,204,217), border-radius 9999px, min-block-size 48px, padding 0/12px, 240x77.

   That is trap T7, and T7's own rule is that the fix is to LEAVE the family - never to re-declare properties
   back against it, which sheds nothing and leaves the next author fighting a selector they cannot see. Here the
   wrapper had no job left once the redundant "Scope" label went, so it was deleted rather than renamed. The
   control itself (`.kl-rel-completed`, below) was always correct and is unchanged. */

/* ---- The header line's own layout. THREE items now, not eight (§A9): the primary, the scope flag, and the
   one disclosure. The primary is bounded rather than greedy - `flex: 0 1 18rem` keeps a 1024px card from
   handing the whole line to one select - and the disclosure is pushed to the trailing edge so the line reads
   left-to-right as [what am I looking at] [how is it scoped] ... [everything else]. ---- */
.kl-rel-more[b-218m7accqd] {
    margin-inline-start: auto;
    position: relative;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
}
/* B8, and the shared `.kl-qcard-toggle--active` rule said the same thing first: a COLLAPSED card must never hide
   that the page on screen is narrowed. The count badge already says how many, and the accent edge says "in here".
   Named `--active` rather than borrowing `kl-qcard-toggle--active`, because that literal class name is what
   Req_QueryCardPlacementTests.NoPageHandRollsTheDisclosureButton forbids outside QueryCardToggle.razor. */
.kl-rel-more--active[b-218m7accqd] {
    border-color: var(--k-accent);
    color: var(--k-accent);
}
.kl-rel-more--active .ki-filter[b-218m7accqd] { color: var(--k-accent); }
/* The disclosure state, drawn where every other query card in the product draws it. `aria-hidden` because
   `aria-expanded` on the button already carries the same fact to assistive tech, and saying it twice is noise. */
.kl-rel-more-chevron[b-218m7accqd] {
    font-size: 16px;
    line-height: 1;
    color: var(--k-text-muted);
}
.kl-rel-badge[b-218m7accqd] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: 20px;
    block-size: 20px;
    padding: 0 6px;
    border-radius: var(--k-radius-full);
    background: var(--k-teal-500);
    color: var(--k-ink-900, #08121d);
    font-size: 11px;
    font-weight: 700;
}

/* ---- Approved-only switch (the foundation role="switch" track + a real teal fill when checked) -- */
.kl-rel-completed[b-218m7accqd] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    min-block-size: var(--k-touch);
    padding: 0 var(--k-space-3);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-full);
    font-size: 14px;
    color: var(--k-text);
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease), border-color var(--k-dur-1) var(--k-ease);
}
.kl-rel-completed:hover[b-218m7accqd] { background: var(--k-surface-3); }
/* the actual checkbox is a small accent box; teal accent-color keeps it on-brand in all modes */
.kl-rel-completed-input[b-218m7accqd] {
    inline-size: 18px;
    block-size: 18px;
    min-block-size: 0;
    margin: 0;
    accent-color: var(--k-teal-500);
    cursor: pointer;
}
.kl-rel-completed-text[b-218m7accqd] { font-weight: 600; }
/* checked → the whole pill lights teal-tinted with a teal edge, driven by the native checkbox. */
.kl-rel-completed:has(.kl-rel-completed-input:checked)[b-218m7accqd] {
    background: color-mix(in srgb, var(--k-teal-500) 18%, var(--k-surface));
    border-color: var(--k-teal-700);
}

/* Active-scope chips row + clear-all */
.kl-rel-chips[b-218m7accqd] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
    padding-block-start: var(--k-space-2);
    border-block-start: 1px solid var(--k-border);
}
.kl-rel-chips-label[b-218m7accqd] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}
/* ---- Applied-scope chips. Each is a real <button> (focusable, Enter/Space for free) that removes its own
   dimension. A6: the whole chip is the hit target and it holds the --k-touch floor, so nothing here buys the
   §A9 collapse out of a touch target.

   NAMING: `kl-rel-applied`, `-key`, `-val`, `-drop`. Deliberately NOT `-chip`, `-pill`, `-badge`, `-status`,
   `-row`, `-x` or `-label`, every one of which is a live attribute-suffix family in the shared sheet - the
   same mechanism (T7) that malformed the scope toggle this pass removed. Checked against the sheet's full
   suffix census before the names were chosen. ---- */
.kl-rel-applied[b-218m7accqd] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    min-block-size: var(--k-touch);
    padding: 0 var(--k-space-3);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    color: var(--k-text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    max-inline-size: 100%;
}
.kl-rel-applied:hover[b-218m7accqd] { background: var(--k-surface-3); border-color: var(--k-outline); }
.kl-rel-applied:focus-visible[b-218m7accqd] { outline: 2px solid var(--k-accent); outline-offset: 2px; }
.kl-rel-applied-key[b-218m7accqd] {
    color: var(--k-text-muted);
    font-weight: 600;
    white-space: nowrap;
}
/* The VALUE is the only part that can be long (an org-unit name, a dog's call-name and handler), so it is the
   only part allowed to truncate - the dimension name and the remove affordance must never be the thing that
   disappears when an agency uses long names. */
.kl-rel-applied-val[b-218m7accqd] {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-inline-size: 0;
}
.kl-rel-applied-drop[b-218m7accqd] {
    font-size: 12px;
    color: var(--k-text-muted);
    flex: 0 0 auto;
}
.kl-rel-applied:hover .kl-rel-applied-drop[b-218m7accqd] { color: var(--k-critical); }

/* A6, same measurement as the flags above: it was 58.6x19 at every width while every chip beside it on the
   same row already held var(--k-touch). `display: inline-flex` + `align-items: center` is what makes the floor
   apply to a <button> whose content is one short line. */
.kl-rel-clear-all[b-218m7accqd] {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--k-critical);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    min-block-size: var(--k-touch);
    padding: 2px 4px;
    border-radius: var(--k-radius-sm);
}
.kl-rel-clear-all:hover[b-218m7accqd] { text-decoration: underline; }

/* The bar footer (the full-report link), pushed below the controls. */
/* `.kl-rel-bar-foot` is RETIRED (owner ruling 2026-07-25 — no single control alone on a band). It was a full-width
   strip whose sole occupant was the full-report link: 12px of pad, a hairline and a 190px control across a 1145px
   card. The link moved to the page header row (`.kl-section-head` > `.kl-head-actions`), where it is page-level
   navigation among page-level chrome rather than a filter that is not a filter. The rule is deleted with its
   markup — a dead selector left behind is the next author's false lead. */
.kl-rel-report-link[b-218m7accqd] { min-inline-size: auto; }

/* ---- Subject hero (single-K9 grain) --------------------------------------
   kl-rel-panel inherits the foundation card treatment ([class$="-panel"]); we add
   the internal rhythm: the subject-K9 identity on the left, the return-to-unit
   affordance on the right. */
.kl-rel-panel[b-218m7accqd] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--k-space-3) var(--k-space-6);
}
.kl-rel-subject[b-218m7accqd] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-inline-size: 0;
}
.kl-rel-subject-eyebrow[b-218m7accqd] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}
/* The scoped unit's call-name = the panel headline (R11 #1: a human name, never a GUID). */
.kl-rel-subject-name[b-218m7accqd] {
    font-family: var(--k-font-display);
    font-size: clamp(20px, 2vw, 26px);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -0.01em;
    color: var(--k-text);
}
.kl-rel-subject-handler[b-218m7accqd] {
    font-size: 14px;
    color: var(--k-text-muted);
}

/* The data-region loading state (only the data waits; the filter bar is already live). */
.kl-rel-loading[b-218m7accqd] { padding: var(--k-space-6) 0; }
.kl-rel-loading-message[b-218m7accqd] { margin: 0; font-size: 14px; color: var(--k-text-muted); }

/* ---- Sortable per-K9 table (the documented 2D-scroll exception) ------------ */
.kl-rel-table-wrap[b-218m7accqd] {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    /* Card padding: 16px block / 24px inline (--k-space-4 / --k-space-6, both on the foundation
       scale — kanine-design-system.css §1), giving the wide 2D-scroll table real breathing room. */
    padding: var(--k-space-4) var(--k-space-6);
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
}
.kl-rel-table-scroll[b-218m7accqd] {
    overflow-x: auto;
}
.kl-rel-table[b-218m7accqd] {
    inline-size: 100%;
    border-collapse: collapse;
    /* Metric VALUES stay on one line — a percentage broken across two lines stops being one number.
       (The `min-inline-size: 64rem` that used to sit here was removed 2026-07-24: see .kl-rel-th below.) */
    white-space: nowrap;
}
.kl-rel-th[b-218m7accqd] {
    position: sticky;
    inset-block-start: 0;
    background: var(--k-surface);
    color: var(--k-text-muted);
    text-align: end;
    /* The COLUMN LABEL wraps; the metric value beneath it does not. Measured 2026-07-24: this table is the
       documented 2D-scroll exception, but it was scrolling far more than it had to. Two declarations were doing
       it — a `min-inline-size: 64rem` (1024px) hard floor on the table, and the labels inheriting the table's
       `white-space: nowrap` so "Narc success %" demanded 153px for a column whose widest value is "100.0%".
       Releasing both, per `.kl-rel-table-scroll` scrollWidth − clientWidth:

           viewport 1024 → 388px hidden → 164   (client 892)
           viewport 1280 → 306px hidden →  82   (client 974)
           viewport 1400 → 306px hidden →  82   (client 974)
           viewport  393 → 969px hidden → 745   (client 311)

       It does not reach zero and it cannot: 15 analytical columns will not fit a measure capped at 1120px. This
       table deliberately keeps its 2D scroll rather than adopting `kl-table-cards` — the whole value of the
       surface is comparing K9s down a metric column, which a stacked card destroys, and its row-level action is
       the ROW itself (`role="button"`, keyboard-operable) anchored by the sticky K9/Handler identity column, so
       no control is ever the thing that hides. The residual scroll still needs a visible affordance — that is a
       shared `.kl-tablewrap`/scroll-container declaration, reported rather than patched in per page.

       CLOSED 2026-09-14. That shared declaration now exists: §8b-s `.kl-scrollcue` in
       kanine-design-system.css, built for the owner's landscape-tablet report that a grid offers no
       click-and-drag scrollbar. This table opts in by carrying the class in its markup. It needs no
       `--k-scrollcue-surface` override — the scroller sits directly on a --k-surface card, which is the
       token's default. */
    white-space: normal;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: var(--k-space-3) var(--k-space-4);
    cursor: pointer;
    user-select: none;
    border-block-end: 1px solid var(--k-border);
}
.kl-rel-th:first-child[b-218m7accqd] {
    text-align: start;
    position: sticky;
    inset-inline-start: 0;
    z-index: 2;
}
.kl-rel-th:hover[b-218m7accqd] { color: var(--k-text); }
/* The active-sort header is a TEXT/foreground accent → ride --k-accent so it stays AA-legible per
   mode (light teal-700, dark teal-400, outdoor #066159). */
.kl-rel-th[aria-sort="ascending"][b-218m7accqd],
.kl-rel-th[aria-sort="descending"][b-218m7accqd] { color: var(--k-accent); }
.kl-rel-th--chev[b-218m7accqd] { inline-size: 2.5rem; cursor: default; }
.kl-rel-th-label[b-218m7accqd]::after {
    content: "";
    display: inline-block;
}
.kl-rel-th[aria-sort="ascending"] .kl-rel-th-label[b-218m7accqd]::after { content: " \2191"; }
.kl-rel-th[aria-sort="descending"] .kl-rel-th-label[b-218m7accqd]::after { content: " \2193"; }

.kl-rel-row[b-218m7accqd] {
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease);
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
}
.kl-rel-row:hover[b-218m7accqd] { background: var(--k-surface-2); }
.kl-rel-row:focus-visible[b-218m7accqd] {
    outline: 2px solid var(--k-teal-500);
    outline-offset: -2px;
}
.kl-rel-row--outlier[b-218m7accqd] {
    background: color-mix(in srgb, var(--k-critical) 6%, var(--k-surface));
}
.kl-rel-row--outlier:hover[b-218m7accqd] {
    background: color-mix(in srgb, var(--k-critical) 11%, var(--k-surface));
}
.kl-rel-cell[b-218m7accqd] {
    padding: var(--k-space-3) var(--k-space-4);
    text-align: end;
    font-family: var(--k-font-mono);
    font-size: 14px;
    color: var(--k-text);
    font-variant-numeric: tabular-nums;
}
.kl-rel-cell--name[b-218m7accqd] {
    position: sticky;
    inset-inline-start: 0;
    background: inherit;
    text-align: start;
    font-family: inherit;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.kl-rel-row:hover .kl-rel-cell--name[b-218m7accqd] { background: var(--k-surface-2); }
.kl-rel-k9-name[b-218m7accqd] { font-weight: 600; color: var(--k-text); }
.kl-rel-row:hover .kl-rel-k9-name[b-218m7accqd] { color: var(--k-accent); }
.kl-rel-k9-handler[b-218m7accqd] { font-size: 12px; color: var(--k-text-muted); }
/* An undefined ("N/A") cell is muted so it never reads as a real measured value (PLAT-012). */
.kl-rel-cell--na[b-218m7accqd] { color: var(--k-text-muted); }
.kl-rel-cell--chev[b-218m7accqd] {
    text-align: center;
    color: var(--k-text-muted);
    inline-size: 2.5rem;
}
.kl-rel-row:hover .kl-rel-cell--chev[b-218m7accqd] { color: var(--k-accent); }

/* ---- Empty states --------------------------------------------------------- */
.kl-rel-empty[b-218m7accqd] {
    border: 1px dashed var(--k-border);
    border-radius: var(--k-radius-lg);
    background: var(--k-surface);
    padding: var(--k-space-8) var(--k-space-6);
    text-align: center;
}
.kl-rel-empty-state-message[b-218m7accqd] {
    font-family: var(--k-font-display);
    font-size: 16px;
    font-weight: 700;
    color: var(--k-text);
    margin: 0;
}
.kl-rel-empty-hint[b-218m7accqd] {
    font-size: 14px;
    color: var(--k-text-muted);
    margin: 0;
}

/* ---- Denied state (fail-closed) ------------------------------------------- */
.kl-rel-denied[b-218m7accqd] {
    border: 1px solid color-mix(in srgb, var(--k-critical) 35%, var(--k-border));
    border-radius: var(--k-radius-lg);
    background: color-mix(in srgb, var(--k-critical) 8%, var(--k-surface));
    color: var(--k-text);
    font-weight: 600;
    padding: var(--k-space-4) var(--k-space-6);
}

/* ---- Inclusion-flags fieldset (drawer) ------------------------------------ */
.kl-rel-flags[b-218m7accqd] {
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-3) var(--k-space-4) var(--k-space-4);
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    margin: 0;
}
.kl-rel-flags > legend[b-218m7accqd] {
    padding: 0 var(--k-space-2);
}
/* A6: the WHOLE label is the hit target, so the whole label holds the touch floor. Measured live on the
   drawer this replaced (which the mobile-a11y sweep never opened, so nothing ever reported it): 338x21 at
   1400 and 279x42 at 393 - under 44 at every width. It was survivable while the control lived off-canvas
   behind a modal; it is product surface on an inline panel. */
.kl-rel-flag[b-218m7accqd] {
    display: flex;
    align-items: center;
    gap: var(--k-space-3);
    min-block-size: var(--k-touch);
    font-size: 14px;
    color: var(--k-text);
    cursor: pointer;
}
.kl-rel-flag input[b-218m7accqd] {
    inline-size: 18px;
    block-size: 18px;
    margin: 0;
    accent-color: var(--k-teal-500);
    cursor: pointer;
}
.kl-rel-flag-hint[b-218m7accqd] { color: var(--k-text-muted); font-size: 12px; }
/* The quiet annotations under a control: what a bound dimension narrows TO, and the K9-roster read
   failure. Muted, never a disabled shell. (.kl-rel-unbound-hint kept for the roster-error case; the
   supervisor hint it was written for is now a BOUND dimension and uses the -bound- variant.) */
.kl-rel-bound-hint[b-218m7accqd],
.kl-rel-unbound-hint[b-218m7accqd] {
    margin: var(--k-space-1) 0 0;
    color: var(--k-text-muted);
    font-size: 12px;
}

/* ---- THE ACCORDION PANEL (owner ruling 2026-09-12) --------------------------
   The off-canvas drawer is GONE. What stood here declared `position: fixed`, `inset-inline-end: 0`, `z-index: 65`,
   `inline-size: min(420px, 92vw)` and `box-shadow: var(--k-elev-3)`, plus a dark `.kl-drawer-head` band with its own
   title and Close, and a scrolling `.kl-drawer-body`. Every one of those is deleted rather than overridden: the
   owner rejected the side car, and a fixed box restyled to look inline is the thing that comes back.

   THE PANEL'S BOX IS NOT DECLARED HERE AT ALL. `.kl-filterpanel` gets surface, border, radius, elevation and
   `padding: var(--k-space-6)` from kanine-design-system.css §8e, and `.kl-qcard > .kl-filterpanel.kl-qcard-open`
   butt-joins it under the header (no top border, no top radius) and drops the padding to `--k-space-3` at ≤640px.
   This block adds only what the shared sheet cannot know about this page's contents.

   D48: `box-sizing` is set EXPLICITLY. This sheet's elements are not direct children of `.kl-shell-main`, and
   `.kl-shell-main > *` is one of only two box-sizing resets in the whole design system — there is NO universal
   `border-box`. A panel that carries 24px of padding and a percentage or flex basis under `content-box` measures
   wider than its own cap, which is exactly how this page's drill-down popup ended up 8px past the viewport. */
.kl-rel-filterpanel[b-218m7accqd] {
    box-sizing: border-box;
    max-inline-size: 100%;
}
/* NO height cap and NO `overflow-y` on purpose. The drawer needed both because it was viewport-height and fixed;
   an accordion is in the flow, so a scroll region inside it would be a SECOND scrollbar on a page that already
   has one — the reader would have to discover which of two surfaces owns the wheel. It grows, and the tiles
   below move down. That is what "comes down to expose" means. */
.kl-rel-filterform[b-218m7accqd] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    min-inline-size: 0;
}
/* §5's `[class$="-grid"]` container family gives `.kl-filter-grid` a trailing `margin-block-end: var(--k-space-4)`,
   which inside a flex column with its own 16px gap spends 32px between the last select and the flags fieldset.
   Zeroed at (0,3,0) so it beats the (0,2,0) family without an `!important`, and the flex gap owns the rhythm —
   the same subtraction §8e-w1 makes for `.kl-filterpanel` itself. */
.kl-rel-filterform > .kl-filter-grid[b-218m7accqd] { margin-block-end: 0; }
.kl-rel-filternote[b-218m7accqd] { margin: 0; font-size: 13px; color: var(--k-text-muted); }
/* The foot. Not named `-actions`: that class ATTRIBUTE suffix is a live family in the shared sheet (§5d) which
   right-aligns the whole row, and the two discard gestures belong on the leading edge, away from Apply. */
.kl-rel-filterfoot[b-218m7accqd] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
    padding-block-start: var(--k-space-4);
    border-block-start: 1px solid var(--k-border);
}
.kl-rel-filterfoot-end[b-218m7accqd] {
    display: flex;
    align-items: center;
    gap: var(--k-space-3);
}

/* ---- Phone (<=640px). The header line's three items cannot share 361px of content, so the primary takes a
   line of its own and the scope flag + the disclosure share the next one - two rows instead of the eight
   controls' six. Nothing shrinks: the select, the pill and the button all keep var(--k-touch) (A6). ---- */
@media (max-width: 640px) {
    .kl-rel-field--scope[b-218m7accqd] {
        flex: 1 1 100%;
        min-inline-size: 0;
    }
    .kl-rel-k9[b-218m7accqd] { max-inline-size: none; }
    .kl-rel-completed[b-218m7accqd] { flex: 0 1 auto; min-inline-size: 0; }
    /* The chip row is the one place a long value can force horizontal overflow at 320px, because a chip is an
       inline-flex box with nowrap children. `min-inline-size: 0` lets the value's own ellipsis engage. */
    .kl-rel-applied[b-218m7accqd] { min-inline-size: 0; }
    /* The panel foot at 320-393: Close on its own line above Clear/Apply rather than three buttons fighting for
       361px of content. Nothing shrinks - every button keeps var(--k-touch) (A6). */
    .kl-rel-filterfoot > .kl-btn[b-218m7accqd],
    .kl-rel-filterfoot-end[b-218m7accqd] { flex: 1 1 100%; }
    .kl-rel-filterfoot-end > .kl-btn[b-218m7accqd] { flex: 1 1 auto; }
}

/* =============================================================================
   RPT-013 — THE DRILL-DOWN MODAL (owner ask 2026-09-11)
   -----------------------------------------------------------------------------
   "if i click on one of these tiles, it lists every record its referecning and i
   can click into any one i want to."

   A CENTRED POPUP, per design principle A12 — a selected item's detail never
   renders below its list. The scrim, the centering and the ESC / outside-click
   dismiss all come from <KlOverlay> (UI-GUAR-033); everything below is the PANEL
   only, and it rides the shared .kl-dialog base (viewport cap, its own scroll
   container, overscroll containment) rather than re-inventing any of it.

   The panel is WIDER than the 30rem .kl-dialog default because it holds a five-
   or six-column table. It stays `inline-size: calc(100% - 2rem)` from the base,
   so at 320/375/393/430 it is a phone-width sheet, never a 56rem panel with the
   page scrolling sideways underneath it.
   ========================================================================== */
.kl-drill-dialog[b-218m7accqd] {
    max-inline-size: 56rem;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    /* The base sets padding-inline on children and padding-block-start on the
       first; the last child needs the matching foot pad or the pager sits on the
       panel's edge. */
    padding-block-end: var(--k-space-6);

    /* ── CONTAINMENT — WHY THESE THREE DECLARATIONS EXIST ───────────────────────
       MEASURED on this host 2026-09-12, at SEVEN viewports, and the same at all
       seven: the panel stood 24px taller than its own computed max-height and so
       ran 8px past the bottom of the screen. Both numbers have ONE cause.

       `box-sizing` — the sheet ships NO universal `* { box-sizing: border-box }`.
       Its only two resets are `.kl-shell-main > *` (direct children of the shell
       main, which this panel is not) and the form-control rule. So .kl-dialog is
       CONTENT-BOX, its `max-block-size: calc(100dvh - 2 * var(--k-space-4))`
       caps the CONTENT box, and the `padding-block-end: var(--k-space-6)` above
       — 24px — is added OUTSIDE that cap. 868 + 24 = 892 at 1400x900, and
       628 + 24 = 652 at 393x660: the measured heights exactly.

       The 8px is the same fault seen from the other end, not a second one, and
       there is no missing 8 in any calc. The overlay insets the panel by
       `padding: var(--k-space-4)` = 16px, and the cap reserves 2 x 16 = 32px for
       that inset top and bottom. The 24px breach eats the 16px bottom reserve and
       overruns by the remaining 8. It reads the same at every viewport because
       both the inset and the breach are viewport-independent constants.

       border-box makes the declared cap the TRUE outer height, so the panel is
       contained whatever padding it is later given. THAT LINE IS NOW IN THE BASE
       and was removed from here on 2026-09-13: `.kl-dialog` declares
       `box-sizing: border-box` itself, naming this panel as one of the three that
       had bought the fix privately. The private copy is redundant and a redundant
       copy is how the two drift apart. The reasoning above is kept because it is
       why the base declaration exists.

       `overflow: hidden` — the base declares `overflow-y: auto` on .kl-dialog,
       which made the PANEL a scroll container as well as the row list inside it.
       The dialog no longer scrolls at all: .kl-drill-body below is the one scroll
       region, and a dialog that scrolls AND contains a scroller is the defect.
       `min-block-size: 0` on the body is what lets it be the one that shrinks.
       ------------------------------------------------------------------------ */
    overflow: hidden;
}

/* ── THE ONE SCROLL REGION ────────────────────────────────────────────────────
   The rows, the basis and the notes. The header above and the pager below are
   pinned (flex: none), so the reader can always see WHICH metric this is and
   WHICH rows of how many are on screen, however far down the list they are.

   `min-block-size: 0` is load-bearing. A flex item's `min-height: auto` is its
   content height, so without this the body refuses to shrink and pushes the
   panel past its cap again — the same shape of fault the containment note above
   records, one level down. */
.kl-drill-body[b-218m7accqd] {
    flex: 1 1 auto;
    min-block-size: 0;
    /* BOTH AXES, from 2026-09-13, and the inline axis is not a convenience.
       (a) A six-column table cannot fit 320px. That sideways scroll used to live
           on .kl-drill-tablewrap; `overflow-x: hidden` here plus a wrapper that
           no longer scrolls would CLIP the columns with no way to reach them,
           which is the exact defect class this panel already shipped once.
       (b) <Virtualize> finds its scroll container by walking up from its spacers
           to the first ancestor whose computed `overflow-y` is not `visible`. A
           box with `overflow-x: auto` reports a BLOCKIFIED `overflow-y: auto`
           even where the sheet declares `visible` (CSS Overflow 3; Chrome
           reports the used value), so while the wrapper carried the sideways
           scroll it answered that walk first — and a virtualizer measuring a box
           with no block overflow renders every row there is. One box scrolls, and
           it is the one both the reader and the virtualizer mean. */
    overflow: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
}
/* NOTHING INSIDE THE SCROLL REGION MAY SHRINK. This is the same trap as the one
   the containment note records, one level further in, and it was MEASURED here
   after the first fix: the row wrapper's `overflow-x: auto` forces its used
   `overflow-y` to `auto` (CSS Overflow 3), which makes its flex `min-height:
   auto` resolve to ZERO — so as a flex item of this column it shrank again and
   scrolled on its own, putting a second scroll region back inside the first
   (measured at 1400x900 as a 529px window over 714px of rows). `flex: none`
   makes every child keep its content height, so the only thing that can scroll
   is this element. */
.kl-drill-body > *[b-218m7accqd] {
    flex: none;
}

/* It takes focus on a page change (see PageDrillAsync). A ring is painted only
   when the engine judges the focus KEYBOARD-driven — which is exactly the case
   that needs it, because a sighted keyboard user who pressed Next has no other
   way to see that focus moved to the top of the new page. (`role="status"` on
   the pager's range sentence is the same fact for a screen reader.) A pointer
   user who clicked Next gets no ring: `:focus:not(:focus-visible)`, never a bare
   `outline: none`, which would suppress the keyboard ring too. */
.kl-drill-body:focus:not(:focus-visible)[b-218m7accqd] {
    outline: none;
}

/* The head is the ONE pinned half now. Named explicitly rather than left to
   `flex-shrink: 1`, so it cannot be squeezed into illegibility on a short
   viewport while the row list still has room. (There is no pager to pin: the
   list is the whole side and states its own total in the reconciliation line.) */
.kl-drill-head[b-218m7accqd] {
    flex: none;
}

/* ── ONE HEADER BAND (owner ask 2026-09-13, "make this part take up minimal space") ──
   MEASURED on this host BEFORE the change, with the title block, the side row and
   the gap between them as three separate bands:
       1400x900  86.8 + 16 + 48 = 150.8px
       393x852   78.8 + 16 + 104 = 198.8px
       780x360   80.2 + 16 + 48 = 144.2px  — of a 328px panel
   The side switch chooses WHICH population the panel is listing, which is the same
   kind of statement the title makes, so it belongs in the title's band rather than
   in one of its own.

   A GRID, not a flex row, because the three items have to REORDER between the two
   shapes and stay aligned in both: Close keeps the top-inline-end corner whether the
   sides are beside the title or under it, and a flex row cannot put a wrapped third
   item under the first while the second stays pinned to the corner. */
.kl-drill-head[b-218m7accqd] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "title close"
        "sides sides";
    column-gap: var(--k-space-4);
    row-gap: var(--k-space-2);
    align-items: center;
}
/* The shared .kl-section-title carries `margin-block-end: var(--k-space-3)` because it
   normally leads a section that follows it. Here it leads NOTHING — the figure is beside
   it and the band ends — so the margin was 12px of empty band at every viewport, measured
   as part of a 72px row that holds a 20.8px heading. */
.kl-drill-headtitle .kl-section-title[b-218m7accqd] {
    margin: 0;
}
.kl-drill-headtitle[b-218m7accqd] {
    grid-area: title;
    /* min-inline-size:0 so a long metric name shrinks instead of pushing Close off
       the panel's trailing edge — the same fix .kl-ur-dialog-headtitle records. */
    min-inline-size: 0;
    /* The figure sits on the TITLE's baseline. Wrapping, so a long metric name at
       320px drops it to a second line rather than squeezing the name. */
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: var(--k-space-3);
    row-gap: 0;
}
.kl-drill-iconbtn[b-218m7accqd] {
    grid-area: close;
}
/* ONE ROW from 48rem of viewport width up. Below that the panel is too narrow to
   hold a metric name, three side buttons and a Close on one line without the sides
   wrapping mid-group, which reads as two rows anyway and an untidy one. */
@media (min-width: 48rem) {
    .kl-drill-head[b-218m7accqd] {
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas: "title sides close";
    }
    .kl-drill-sides[b-218m7accqd] {
        justify-content: flex-end;
    }
}
/* The figure the rows belong to. Display face + tabular figures so it reads as
   the SAME number the card behind the scrim is showing. It is SMALLER than it was
   (30px -> 26px cap): beside the name it no longer has to carry the line on its
   own, and the line's height is now the 48px Close target either way. */
.kl-drill-figure[b-218m7accqd] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: clamp(20px, 2.4vw, 26px);
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -0.02em;
    color: var(--k-text);
    font-variant-numeric: tabular-nums;
}
/* A6 — the header Close is a real 44px target, not a 24px glyph. */
.kl-drill-iconbtn[b-218m7accqd] {
    min-inline-size: var(--k-touch);
    min-block-size: var(--k-touch);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    padding: 0;
}

/* The side switch. Wraps rather than scrolls: three short labels fit two lines
   at 320 and one line from 375 up. */
.kl-drill-sides[b-218m7accqd] {
    grid-area: sides;
    flex: none;
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
}
.kl-drill-side[b-218m7accqd] {
    min-block-size: var(--k-touch);
}
/* THREE EQUAL COLUMNS below the one-row band. Left to wrap, "Counted / Did not count /
   All rows" takes two 48px lines at 393px and the group costs 104px — more than the
   title band above it. Equal thirds put all three on ONE line and let the longest label
   wrap INSIDE its own button, which costs a few pixels of button height instead of a
   whole second row. The A6 48px floor is untouched. */
@media (max-width: 47.99rem) {
    .kl-drill-sides[b-218m7accqd] {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    .kl-drill-side[b-218m7accqd] {
        padding-inline: var(--k-space-2);
        font-size: 12px;
        line-height: 1.2;
        white-space: normal;
    }
}

/* WHAT SELECTS THESE ROWS. A definition list, because each line is genuinely a
   term and its value, and because a screen reader then announces the pairing
   rather than five loose sentences. */
/* COMPRESSED 2026-09-13, and the three facts are all still printed.
   It was a three-row two-column grid: a `max-content` term column and a `1fr`
   value column, one row per pair. MEASURED before: 82.5px at 1400x900, 66.5px at
   780x360 and 176.5px at 393x852 — on a phone the term column squeezed the value
   column to a few characters and every sentence became a paragraph of one-word
   lines, which is what made it the tallest single block in the panel.

   It is now ONE wrapping run: the pairs flow, and a line holds as many as fit.

   STILL A <dl>, and that is deliberate. `display: inline` on a dt/dd is the shorter
   way to write this and it costs the description-list semantics in the engine's
   accessibility tree; a wrapping FLEX container keeps every element's own display
   type block-ish, so the pairing is still announced as a pairing. The two facts
   that could not be dropped are the SCOPE, which names what selects these rows, and
   the RECONCILIATION, which is how a reader sees that the figure and the list do not
   disagree. Presentation is what got smaller. */
.kl-drill-basis[b-218m7accqd] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: var(--k-space-2);
    row-gap: 2px;
    margin: 0;
    font-size: 12px;
    line-height: 1.45;
}
/* The term reads as an eyebrow, not as a word in the sentence, so the eye can find
   "SCOPE" in a run of prose without the term needing a column of its own. */
.kl-drill-basis dt[b-218m7accqd] {
    flex: none;
    color: var(--k-text-muted);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}
.kl-drill-basis dd[b-218m7accqd] {
    flex: 0 1 auto;
    min-inline-size: 0;
    margin: 0;
    margin-inline-end: var(--k-space-2);
    color: var(--k-text);
    /* A long scope sentence (every dimension committed) must wrap inside the
       panel, never widen it. */
    overflow-wrap: anywhere;
}

/* THE SCOPE AND THE RECONCILIATION STAY ON SCREEN WHILE THE ROWS MOVE. They are
   the first block in the one scroll region and they stick to the top of it, so a
   reader who has scrolled to row 9 can still read what selected these rows and
   how the count reconciles against the figure. That is not a convenience on a
   court-facing surface: a list of records whose basis has scrolled away is the
   trap the basis exists to close.

   HEIGHT-GATED, and deliberately. Below 34rem of viewport height — a phone held
   sideways in a vehicle, ~360px — the pinned header, this block and the pinned
   pager together leave the rows a single line, and a block pinned over an empty
   list is worse than one the reader scrolls past. Under that height it is a plain
   block again and everything stays reachable.

   The background is required: a sticky element paints over what scrolls beneath
   it only where it has one, and --k-surface is the panel's own, so it is correct
   in both themes. The negative block margins plus the matching padding let the
   painted band cover the gap the flex column puts above the first row, which
   would otherwise show a sliver of a row sliding under the text. */
@media (min-height: 34rem) {
    .kl-drill-preamble[b-218m7accqd] {
        position: sticky;
        inset-block-start: 0;
        z-index: 1;
        background: var(--k-surface);
        margin-block: calc(-1 * var(--k-space-2)) calc(-1 * var(--k-space-2));
        padding-block: var(--k-space-2);
    }
}

/* ── THE PREAMBLE IS BOUNDED, AND THE BOUND IS WHY THE LIST RENDERS AT ALL ─────
   The markup note beside this block records the measurement. In one sentence:
   <Virtualize> initialises from an IntersectionObserver on its own spacer rows,
   so a preamble taller than this scroll region opens the spacers below the fold,
   the observer never fires, and the list renders zero rows for ever. Measured at
   780x360 on RPT-008-TOTAL: 421px of preamble, a 216px region, zero of 204 rows,
   at every wait up to nine seconds.

   26dvh, AND NOT 26%, and that is a correctness point rather than a preference.
   A percentage max-height resolves against the containing block's height, and this
   element's containing block is a flex item whose height flex layout computes
   rather than specifies — so the percentage resolved to `none` and the cap was
   MEASURED INERT on the running host, with the 421px preamble and the zero rows
   both exactly as before. A viewport unit is definite and always resolves.

   WHY 24 OF THEM, and it is bounded from both sides.
   THE UPPER BOUND is the deadlock. When a side is large the panel is at its own cap,
   so the scroll region is `100dvh - 144px`; the table head (30px) and the region's
   gap (16px) also have to fit above the spacers, so the preamble must stay under
   `100dvh - 190px`. 24dvh clears that at every viewport height this product supports
   and then some. Measured at 780x360: the cap is 86px, the spacers open at ~132px of
   a 216px region, well inside the observer's 50px reach.
   THE LOWER BOUND is the BASIS. This block is PINNED on any viewport taller than
   34rem, so whatever it holds is permanently on screen and whatever it cannot hold
   scrolls INSIDE it — and the one thing that must never be the part that scrolls away
   is the scope-and-reconciliation line at its top. The cap therefore has to clear the
   basis at every width. Measured basis heights: 36.8px at 1400x900, 90.8 at 393x852,
   142.8 at 320x720, and on the notes-heavy metric 36.8 / 142.6 / 177.4 at the same
   three; the tightest pair is 320x720, where the basis is 177.4 against a 187.2 cap.
   The NOTES are what scrolls when there are too many of them, and that is the right
   thing to give up: a caution the reader can scroll to beats a reconciliation they
   cannot see.
   24dvh was measured first and lost that pair by 4.6px at 320x720. 40dvh was measured
   before THAT and gave the notes-heavy metric a 340px pinned band over a 700px region
   at 393x852 — two cards of list under half a screen of preamble.

   INERT WHERE IT IS NOT NEEDED. At 1400x900 the preamble is 143px against a 302px
   cap; there is no second scrollbar, and this element behaves exactly as the
   three loose blocks it replaced did. Where it DOES engage, the overflow is
   reachable by a real scroll — which is the whole difference between this and the
   `overflow-y: hidden` clip this panel shipped once already.

   `flex: none` is inherited from `.kl-drill-body > *` and is kept: the item takes
   its content height and the max clamps it, so it can never be SHRUNK by the
   column, only capped. */
.kl-drill-preamble[b-218m7accqd] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    /* BORDER-BOX, and it is the D48.1 lesson one level in. The height-gated sticky
       rule above adds `padding-block: var(--k-space-2)` to this same element, and a
       content-box max would put those 16px OUTSIDE the cap — measured at 393x852 as
       a 356.8px block against a 340.8px cap, the identical shape of arithmetic that
       made this dialog overrun the viewport by 8px in the first place. */
    box-sizing: border-box;
    max-block-size: 26dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.kl-drill-note[b-218m7accqd] {
    align-self: flex-start;
    /* A note is a sentence, not a token: let it wrap rather than force the panel
       wide enough to hold it on one line. */
    white-space: normal;
    text-align: start;
    max-inline-size: 100%;
    /* …and a note may quote a raw activity id, which has no break opportunity in
       it at all. Measured at 320x720 on RPT-008-TOTAL: the divergence notes made
       the scroll region 286px wide inside a 256px box, so the whole list scrolled
       sideways under a 36-character GUID. The page itself never overflowed — the
       sideways scroll was inside the panel — which is exactly why it would not
       have been caught by a page-level overflow sweep. */
    overflow-wrap: anywhere;
}

.kl-drill-denied[b-218m7accqd],
.kl-drill-empty[b-218m7accqd] {
    margin: 0;
    color: var(--k-text-muted);
}

/* THE TABLE SCROLLS SIDEWAYS INSIDE ITS OWN CONTAINER, never the page. A six-
   column table cannot fit 320px and must not try.

   `overflow-y: visible` IS THE FIX, and it is not decoration. The shared
   `.kl-shell-main .kl-tablewrap` declares `overflow-y: hidden`, and this wrapper
   used to be a direct flex item of the panel. A flex item whose overflow is not
   `visible` takes `min-height: auto` as ZERO, so it shrank to whatever the column
   had left and then CLIPPED the overflow with no scrollbar and no scroll:
   measured at 1400x900 as a 553px window over 1,114px of rows, with 8 of 16 rows
   unreachable by any gesture, and at 780x360 as a 19px window over 1,218px with
   all 16 unreachable. Restoring `visible` in the block axis means this box can
   never clip a row: its height is always its content, and the scrolling is done
   once, by .kl-drill-body around it.

   THE `overflow-x: auto` WENT WITH IT, on 2026-09-13, and that closes the footnote
   this comment used to end on. An `overflow-x` that is not `visible` forces the used
   `overflow-y` to `auto` per CSS Overflow 3, and Chrome reports the blockified value
   — so this box reported itself as a scroll container even while declaring
   `visible`. Harmless for a reader; fatal for <Virtualize>, which walks up from its
   spacers to the first ancestor whose computed overflow-y is not `visible` and would
   have measured THIS box, which has no block overflow, and rendered every row of the
   side. The sideways scroll moved out to .kl-drill-body, which scrolls on both axes
   and is the one box both the reader and the virtualizer mean. This box now scrolls
   on neither: its size is always its content, in both axes. */
.kl-drill-tablewrap[b-218m7accqd] {
    overflow: visible;
}
.kl-drill-table[b-218m7accqd] {
    inline-size: 100%;
    border-collapse: collapse;
    font-size: 13px;
}
/* The block padding came down from --k-space-2 to --k-space-1 on 2026-09-13. The
   row's height is set by the A6 floor on .kl-drill-link (48px) plus this padding,
   so 8px of it was the only part that could go: a measured 64.5px desktop row
   becomes 57px, which is two more rows in the same window and costs the link not
   one pixel of its hit target. */
.kl-drill-table th[b-218m7accqd],
.kl-drill-table td[b-218m7accqd] {
    text-align: start;
    padding: var(--k-space-1) var(--k-space-3);
    border-block-end: 1px solid var(--k-border);
    vertical-align: top;
}
.kl-drill-table th[b-218m7accqd] {
    color: var(--k-text-muted);
    font-weight: 600;
    white-space: nowrap;
}
.kl-drill-table tbody tr:last-child td[b-218m7accqd] {
    border-block-end: 0;
}

/* The row link. A6: the whole two-line cell is the target, so the hit area is
   the row's height rather than the 13px of the case number. */
.kl-drill-link[b-218m7accqd] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-block-size: var(--k-touch);
    justify-content: center;
    color: var(--k-text);
    text-decoration: none;
}
.kl-drill-link:hover .kl-drill-rectype[b-218m7accqd],
.kl-drill-link:focus-visible .kl-drill-rectype[b-218m7accqd] {
    text-decoration: underline;
}
.kl-drill-link:focus-visible[b-218m7accqd] {
    outline: 2px solid var(--k-focus, var(--k-teal-500));
    outline-offset: 2px;
    border-radius: var(--k-radius-sm);
}
.kl-drill-rectype[b-218m7accqd] {
    font-weight: 600;
}
.kl-drill-recmeta[b-218m7accqd] {
    color: var(--k-text-muted);
    font-size: 12px;
}
/* A record the caller may not open: stated, muted, and NOT a link. */
.kl-drill-restricted[b-218m7accqd] {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--k-touch);
    color: var(--k-text-muted);
    font-style: italic;
}
.kl-drill-incomplete[b-218m7accqd] {
    margin-inline-start: var(--k-space-2);
}

/* A window whose rows have not landed yet. Quiet, and exactly as tall as the row it
   stands in for, so the list does not jump when the real rows arrive. */
.kl-drill-pending[b-218m7accqd] {
    color: var(--k-text-muted);
    font-style: italic;
    min-block-size: var(--k-touch);
}

/* ── PHONE ────────────────────────────────────────────────────────────────────
   There is NO stacking block here, and its absence is the finding.

   A hand-rolled `@media (max-width: 34rem)` reflow was written first and measured
   INERT on the running host: `matchMedia` matched, the scoped rules were in the
   CSSOM, and `getComputedStyle(tr).display` still read `table-row`. The design
   system's §5n table-structural guard sets `display: table-row !important` on
   every `tr` inside `.kl-shell-main` — deliberately, to stop the class-suffix
   families hijacking native table layout on five table-based pages — and no
   amount of specificity beats an `!important` from a scoped sheet.

   The right answer was already built: `.kl-table-cards` (design system §8b-m)
   carries the matching `!important` overrides and is what /records collapses
   with. The markup opts into it. Weakening §5n to make a private copy work would
   have traded a shared invariant for a duplicate, which is the trade the
   one-shared-CSS-surface ruling exists to refuse.

   What remains phone-specific here is only what the shared primitive does not
   know about: the card's own two-line record link, which keeps its A6 floor in
   both shapes (see .kl-drill-link above). */

/* The record link is a DELIBERATE two-line cell, and the shared card primitive assumes a one-line title.
   `.kl-table-cards .kl-tcard-title > *` sets `white-space: nowrap; overflow: hidden; text-overflow: ellipsis`
   so that a long title ellipsises instead of pushing a status badge off the line — correct for a one-line
   title, and on this cell it CLIPPED the case number mid-glyph with no ellipsis at all, because the ellipsis
   applies to the anchor's own inline content and the two lines inside it are nested boxes (measured at 393:
   "RCSO-TRN-2026-0340 - K9 Obe|"). A case number is the record's human identifier; half of one is worse than a
   wrapped one, so this restores wrapping for the two lines rather than accepting a cut. */
.kl-drill-table .kl-drill-link[b-218m7accqd] {
    overflow: visible;
    white-space: normal;
}
.kl-drill-table .kl-drill-rectype[b-218m7accqd],
.kl-drill-table .kl-drill-recmeta[b-218m7accqd] {
    white-space: normal;
    overflow: visible;
    overflow-wrap: anywhere;
}

/* ══ THE PHONE CARD, AND THE VIRTUALIZER'S SPACERS ═══════════════════════════════
   Owner ask 2026-09-13, verbatim: "on the popup for small screens were it shows the
   cards we need to have a special layout or something."

   WHAT HE IS REACTING TO, measured on this host at 393x852 before the change: a card
   was 166.8px tall on a 178.8px pitch, so ten of them stood 1,974px in a 486px window
   — four screens of scrolling for ten records. THE HEIGHT WAS NOT IN THE FACTS. Every
   labelled cell the shared primitive renders costs TWO lines, an uppercase eyebrow
   over its value, and this card has four of them; the eyebrows alone were most of the
   card. On a registry, where a card carries eight or ten fields the reader is
   scanning, an eyebrow per field earns its line. Here the card carries four, two of
   which are self-evident from their own value.

   WHAT WAS REMOVED: nothing. WHAT WAS DEMOTED: the K9, the date and (on a sum-shaped
   metric) the contribution give up their eyebrow LINE and keep their label INLINE, so
   "K9 Obe · Date Aug 28, 2026 09:14" is one line instead of six. The record link and
   the status chip keep the title line they already had (§A10), and the handler stays
   `kl-tcard-hide` as it already was — it is the one field that is genuinely dropped on
   a phone, and it was dropped before this change.

   HOW IT BEATS THE SHARED RULE. `.kl-shell-main .kl-table-cards td[data-label]::before`
   is (0,3,1). Blazor's scoped-CSS rewriter appends this page's `[b-…]` attribute to the
   LAST compound only, so `.kl-drill-table td.kl-drill-inline[data-label]::before`
   becomes (0,4,1) and wins on specificity rather than on source order — which matters,
   because the scoped bundle's position relative to the design system is a build
   detail and not something a page may depend on. */
@media (max-width: 640px) {
    /* The label stops being a caption and becomes the first word of the value. */
    .kl-drill-table td.kl-drill-inline[data-label][b-218m7accqd]::before {
        content: attr(data-label) " ";
        display: inline;
        font-size: 11px;
        font-weight: 700;
        letter-spacing: 0.03em;
        text-transform: uppercase;
        color: var(--k-text-muted);
    }
    /* …and the demoted fields share ONE line rather than taking a row each. `flex: none`
       plus the row's own column-gap is what puts them side by side; `basis: auto` would
       let a long date claim the whole line and push the K9 down. */
    .kl-drill-table td.kl-drill-inline[b-218m7accqd] {
        flex: none;
        font-size: 12px;
    }
    /* THE STATUS CELL MAY WRAP HERE, AND §A10's ONE-LINE CLAMP IS WHY IT COULD NOT.
       §8b-m clamps `.kl-tcard-badge` to `max-block-size: var(--k-tcard-line)` so the chip
       stays centred on the band the PINNED corner slot sits on. This table renders no
       corner slot, so there is no band to stay on — and a row that is counted while
       incomplete carries TWO chips ("Incomplete" plus "Counted while incomplete"), which
       at 320px measured 249.1px inside a 232px card and scrolled the whole list sideways
       under them. An undiscoverable sideways scroll is the defect §8b-m itself was written
       to end. Wrapping costs ~20px on the incomplete rows at 320 only, and it is the
       cheaper of the two. If a row menu is ever added to this table, this rule goes with
       it: the clamp would then be doing real work. */
    .kl-drill-table td.kl-tcard-badge[b-218m7accqd] {
        /* `flex: 0 0 auto` from the shared rule bases the cell at its MAX-CONTENT width, so
           `flex-wrap` alone changed nothing: the cell never got narrow enough for its own
           line to break. It has to be allowed to shrink first, and then to wrap. */
        flex: 0 1 auto;
        min-inline-size: 0;
        max-inline-size: 100%;
        flex-wrap: wrap;
        max-block-size: none;
        row-gap: var(--k-space-1);
    }
    .kl-drill-table .kl-drill-incomplete[b-218m7accqd] {
        margin-inline-start: 0;
        white-space: normal;
    }

    /* The card's own padding. --k-space-3/4 is right for a registry card the reader
       dwells on; this one is a row in a list they are scanning. Reached through
       `[data-testid]` so it is (0,3,2) against the shared rule's (0,2,2) — and so it
       can never touch a virtualizer spacer, which carries no testid. */
    .kl-drill-table > tbody > tr[data-testid][b-218m7accqd] {
        padding: var(--k-space-2) var(--k-space-3);
        row-gap: var(--k-space-1);
    }
    /* THE §8b-m CORNER RESERVE STAYS, AND IT WAS MEASURED BOTH WAYS. It reserves
       `--k-tcard-reserve` (56px) at the end of the title line for the pinned `.kl-tcard-actions`
       kebab, and this table renders no row menu at all — so reclaiming it looked free. It is not:
       with the reserve gone the status chip fits BESIDE the title, the title cell shrinks from
       199px to 114px, and the case number wraps from two lines to four. Measured at 393x852:
       129.5px per card with the reserve, 142px without it. The reserve buys the title its width,
       and the chip on its own 19.5px line is the cheaper of the two. Left alone deliberately, so
       the next reader does not re-derive it. */
    /* The stack gap between cards. --k-space-3 suits a registry card the reader dwells on; in a
       scan list it is 12px per row of nothing. */
    .kl-drill-tablewrap > .kl-drill-table > tbody[b-218m7accqd] {
        gap: var(--k-space-2);
    }
    /* THE SPACERS. <Virtualize> renders two of them, and with SpacerElement="tr" they
       are table rows — which means the shared card primitive paints each one as a
       bordered, padded, shadowed CARD several thousand pixels tall, and the reader
       scrolls through an empty box to reach the rows. They are rendered by Virtualize,
       not by this component, so they carry no scoped attribute and `::deep` is the only
       way a scoped sheet can reach them: it moves this page's attribute onto the
       WRAPPER instead, giving (0,3,2) over the shared rule's (0,2,2). The `!important`
       is needed for `display` alone, because the shared rule sets that with importance
       and importance is settled before specificity. */
    .kl-drill-tablewrap[b-218m7accqd]  tbody > tr:not([data-testid]) {
        display: block !important;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: none;
        box-shadow: none;
    }
}
/* _content/Kanine.Web/Components/Pages/ReportAnalytics.razor.rz.scp.css */
/* =============================================================================
   ReportAnalytics.razor.css — R11 (UI-GUAR-011) restrained-premium polish for the
   CHARTED-ANALYTICS surface (report-analytics.html · RPT-029 / RPT-009 / RPT-026).
   -----------------------------------------------------------------------------
   Blazor-SCOPED to this component (no edit to the central design-system sheet —
   parallel-safe). The page leans on the shared kl-* kit where the kit already
   ships the affordance:
     • the chart-type toggle + the export-format single-select reuse the kit's
       .kl-segmented pill-group (navy-ink-on-teal active); the chart-type group is
       a role="tablist" keyed on aria-selected (a coverage contract), so this file
       ADDS the active-fill rule for aria-selected="true" the kit only ships for
       aria-pressed,
     • the preset quick-picks are .kl-btn--ghost (secondary chrome — NOT the page
       primary), the Export action is the LONE .kl-btn--primary teal primary,
     • the three dimension <select>s inherit the kit's global form-control skin
       (.kl-shell-main select), so this file only lays them out + labels them,
     • the empty-data state reuses the kit-less .kl-empty composition the SIGNED
       MasterNames/Suspects pages define (elevated card, token-tinted disc).
   This file supplies ONLY the page-local register the kit doesn't: the controls
   card chrome, the field grid + labels, the chart card head + export toolbar, the
   composed empty-data card (with an analytics glyph), and the de-ambiguated
   drill-down list (was one teal text blob).
   Every colour is a --k-* token (no raw fills, NO gradient) and spacing is ONLY the
   defined 1/2/3/4/6/8/12/16 scale (NO --k-space-5) so the R11 objective
   token/canvas/0-gradient teeth hold across light / dark / dark-outdoor, with
   load-bearing dark remaps at the foot. POLISH, not redesign: every data-testid /
   data-anchor / data-* hook + binding is untouched.
   ========================================================================== */

/* The page stacks its cards with a calm rhythm (the .kl-page flex already gaps;
   this just guarantees it when the wrapper class is page-scoped). */
.kl-an-page[b-ajg4ndr4di] {
    gap: var(--k-space-4);
}

/* ---- Shared field label (selectors, chart-type group, presets) ---------------- */
.kl-an-field-label[b-ajg4ndr4di] {
    display: block;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--k-text-muted);
    margin-block-end: var(--k-space-2);
}

/* ---- Controls card: chart-type toggle + dimension selectors + presets ---------- */
.kl-an-controls[b-ajg4ndr4di] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-6);
}

/* The chart-type field lays the label above its segmented group. */
.kl-an-field--inline[b-ajg4ndr4di] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
}

/* The dimension selectors sit on a responsive grid so they fill the card width
   instead of stacking as full-bleed unstyled rows. */
.kl-an-selectors[b-ajg4ndr4di] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
    gap: var(--k-space-3) var(--k-space-4);
    align-items: end;
}

.kl-an-field[b-ajg4ndr4di] {
    min-inline-size: 0;
}

/* The <select>s inherit the kit's global control skin (.kl-shell-main select);
   only ensure they span their grid cell. */
.kl-an-field select[b-ajg4ndr4di] {
    inline-size: 100%;
}

/* ---- Chart-type segmented control ---------------------------------------------
   The group carries .kl-segmented (kit base: pill-group, hairline dividers, hover).
   The kit's active fill is keyed on aria-pressed; this is a role="tablist" keyed on
   aria-selected, so add the SAME teal-fill for the selected tab here. ------------ */
.kl-an-charttype.kl-segmented > .kl-an-charttype-tab[aria-selected="true"][b-ajg4ndr4di] {
    background: var(--k-teal-500);
    color: var(--k-ink-900);
    font-weight: 700;
}

/* ---- Presets: a labelled group of restrained ghost quick-picks ----------------- */
.kl-an-presets[b-ajg4ndr4di] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    border-block-start: 1px solid var(--k-border);
    padding-block-start: var(--k-space-4);
}

.kl-an-presets-row[b-ajg4ndr4di] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
}

/* The preset buttons carry .kl-btn--ghost (kit) — size them to the compact chip
   register so a row of five reads as quick-picks, not heavy actions. */
.kl-an-preset[b-ajg4ndr4di] {
    font-size: 13px;
    font-weight: 600;
    min-block-size: var(--k-touch); /* UI-GUAR-036 (R2-25): ≥44 CSS-px touch target (was 40). */
}

/* ---- Chart + aggregate-table card --------------------------------------------- */
.kl-an-chart[b-ajg4ndr4di] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-6);
}

/* The card head: heading on the leading edge, the export toolbar on the trailing
   edge, wrapping to its own row on narrow widths. */
.kl-an-chart-head[b-ajg4ndr4di] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--k-space-3) var(--k-space-4);
}

.kl-an-chart-heading[b-ajg4ndr4di] {
    min-inline-size: 0;
}

.kl-an-chart-title[b-ajg4ndr4di] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--k-text);
    line-height: 1.3;
}

.kl-an-chart-subtitle[b-ajg4ndr4di] {
    margin: var(--k-space-1) 0 0;
    font-size: 13px;
    color: var(--k-text-muted);
}

/* The export toolbar: the format SELECTORS (segmented, secondary) sit beside the
   single teal PRIMARY (Export). */
.kl-an-export-bar[b-ajg4ndr4di] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-3);
}

/* The format group is .kl-segmented (kit); the active fill is keyed on aria-pressed,
   which the kit already supplies — nothing more needed than letting it size. */
.kl-an-export-format[b-ajg4ndr4di] {
    font-size: 13px;
}

/* ---- Composed empty-data state ------------------------------------------------
   The dev seed legitimately has 0 buckets, so this render is what the R11 harness
   shoots. Reuse the .kl-empty composition the SIGNED MasterNames/Suspects pages use
   (elevated card, token-tinted disc, centred) and swap the disc glyph for a chart.
   Presence, not a naked sentence; never a grey void. ----------------------------- */
.kl-an-empty.kl-empty[b-ajg4ndr4di] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--k-space-3);
    padding: var(--k-space-12) var(--k-space-6);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}

.kl-an-empty.kl-empty[b-ajg4ndr4di]::before {
    content: "";
    inline-size: 72px;
    block-size: 72px;
    margin-block-end: var(--k-space-1);
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    /* a calm bar-chart glyph drawn as a masked background (no extra DOM / no icon
       font dependency — stays offline-safe), tinted with the accent. */
    -webkit-mask: center / 34px no-repeat
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M4 4a1 1 0 0 1 1 1v13h15a1 1 0 1 1 0 2H4a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1Z'/%3E%3Cpath fill='%23000' d='M8 12a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0v-2a1 1 0 0 1 1-1Zm4-4a1 1 0 0 1 1 1v6a1 1 0 1 1-2 0V9a1 1 0 0 1 1-1Zm4-2a1 1 0 0 1 1 1v8a1 1 0 1 1-2 0V7a1 1 0 0 1 1-1Z'/%3E%3C/svg%3E");
    mask: center / 34px no-repeat
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M4 4a1 1 0 0 1 1 1v13h15a1 1 0 1 1 0 2H4a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1Z'/%3E%3Cpath fill='%23000' d='M8 12a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0v-2a1 1 0 0 1 1-1Zm4-4a1 1 0 0 1 1 1v6a1 1 0 1 1-2 0V9a1 1 0 0 1 1-1Zm4-2a1 1 0 0 1 1 1v8a1 1 0 1 1-2 0V7a1 1 0 0 1 1-1Z'/%3E%3C/svg%3E");
    background-color: var(--k-accent);
}

.kl-an-empty .kl-empty-state-message[b-ajg4ndr4di] {
    margin: 0;
    max-inline-size: 44ch;
    color: var(--k-text);
    font-family: var(--k-font-display);
    font-size: 1.1rem;
    font-weight: 600;
    line-height: 1.4;
}

.kl-an-empty-hint[b-ajg4ndr4di] {
    margin: 0;
    max-inline-size: 52ch;
    color: var(--k-text-muted);
    font-size: 14px;
    line-height: 1.55;
}

/* ---- Inline-SVG chart (final-draft pass) ---------------------------------------
   Token-composed data marks over the loaded series. Marks carry the series color;
   axis text wears text tokens (never the series color); gridlines are recessive
   hairlines. Dark mode softens the large bar fill (never a large bright-teal fill
   on the dark surface) while the thin line/dots keep the accent. ---------------- */
.kl-an-plot[b-ajg4ndr4di] {
    display: block;
    inline-size: 100%;
    block-size: auto;
}

.kl-an-plot-region[b-ajg4ndr4di] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}

.kl-an-plot-grid[b-ajg4ndr4di] {
    stroke: var(--k-border);
    stroke-width: 1;
}

.kl-an-plot-baseline[b-ajg4ndr4di] {
    stroke: color-mix(in srgb, var(--k-border) 60%, var(--k-text-muted));
}

/* The axis/value text nodes are INJECTED markup (Razor reserves <text>), so they carry no
   CSS-isolation scope attribute — reach them via ::deep from the scoped svg. */
.kl-an-plot[b-ajg4ndr4di]  .kl-an-plot-axis {
    fill: var(--k-text-muted);
    font-family: var(--k-font-ui);
    font-size: 11px;
}

.kl-an-plot[b-ajg4ndr4di]  .kl-an-plot-val {
    fill: var(--k-text);
    font-family: var(--k-font-mono);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

/* ---- Series identity ----------------------------------------------------------
   MULTI-SERIES (2026-09-13). A chart can now draw one series per categorical
   bucket over one shared time axis, so every mark below reads its color from
   --k-an-series and every line its dash pattern from --k-an-dash. Both FALL BACK
   to the single-series values, so a 1-D chart -- which renders no identity class
   at all -- is byte-identical to the chart that shipped before this. -------------- */

.kl-an-plot-mark[b-ajg4ndr4di] {
    fill: var(--k-an-series, var(--k-accent));
}

/* The dark override keeps the SAME fallback shape, or it would win on specificity
   and repaint every series of a cross-tab in one color. */
html.dark .kl-an-plot-mark[b-ajg4ndr4di] {
    fill: var(--k-an-series, color-mix(in srgb, var(--k-accent) 55%, var(--k-surface)));
}

.kl-an-plot-line[b-ajg4ndr4di] {
    fill: none;
    stroke: var(--k-an-series, var(--k-accent));
    stroke-dasharray: var(--k-an-dash, none);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

/* End-dots: 8px marks with a 2px surface ring so they stay legible crossing the line. */
.kl-an-plot-dot[b-ajg4ndr4di] {
    fill: var(--k-an-series, var(--k-accent));
    stroke: var(--k-surface);
    stroke-width: 2;
}

/* Area fill = the series hue as a wash, never a saturated block. */
.kl-an-plot-areafill[b-ajg4ndr4di] {
    fill: var(--k-an-series, var(--k-accent));
    opacity: .12;
}

/* The 8 series identities. Each pairs a TONE with a DASH PATTERN, because hue alone
   is not an identity: two of these tones are close enough to argue about on a bright
   outdoor screen, and none of them survive a greyscale print. The legend draws the
   exact same mark with the exact same classes, so a swatch cannot drift from the line
   it labels. Tones mix the accent toward --k-text (darker in light mode, lighter in
   dark mode) and toward --k-surface, so the ramp stays legible in both themes. */
.kl-an-s0[b-ajg4ndr4di] { --k-an-series: var(--k-accent); }
.kl-an-s1[b-ajg4ndr4di] { --k-an-series: color-mix(in srgb, var(--k-accent) 45%, var(--k-text)); --k-an-dash: 7 4; }
.kl-an-s2[b-ajg4ndr4di] { --k-an-series: color-mix(in srgb, var(--k-accent) 70%, var(--k-surface)); --k-an-dash: 2 3; }
.kl-an-s3[b-ajg4ndr4di] { --k-an-series: color-mix(in srgb, var(--k-accent) 18%, var(--k-text)); --k-an-dash: 12 3 2 3; }
.kl-an-s4[b-ajg4ndr4di] { --k-an-series: color-mix(in srgb, var(--k-accent) 78%, var(--k-text)); --k-an-dash: 4 4; }
.kl-an-s5[b-ajg4ndr4di] { --k-an-series: color-mix(in srgb, var(--k-accent) 52%, var(--k-surface)); --k-an-dash: 14 5; }
.kl-an-s6[b-ajg4ndr4di] { --k-an-series: color-mix(in srgb, var(--k-accent) 62%, var(--k-text)); --k-an-dash: 1 4; }
.kl-an-s7[b-ajg4ndr4di] { --k-an-series: color-mix(in srgb, var(--k-accent) 32%, var(--k-text)); --k-an-dash: 9 3 3 3; }

/* The multi-series legend: a wrapping row of mark + name pairs under the plot. Each
   mark is a real 20x10 svg drawing the SAME element the chart drew. */
.kl-an-serieslegend[b-ajg4ndr4di] {
    list-style: none;
    margin: var(--k-space-3) 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2) var(--k-space-4);
}

.kl-an-serieslegend-entry[b-ajg4ndr4di] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    min-block-size: 24px;
    min-inline-size: 0;
    font-size: 13px;
    color: var(--k-text);
}

.kl-an-serieslegend-mark[b-ajg4ndr4di] {
    flex: none;
    inline-size: 20px;
    block-size: 10px;
    overflow: visible;
}

.kl-an-serieslegend-name[b-ajg4ndr4di] {
    min-inline-size: 0;
    max-inline-size: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---- Filter row ---------------------------------------------------------------
   The container class ends in "-filters" DELIBERATELY: the design system's
   [class$="-filters"] family already lays a filter row out (wrapping flex, gap,
   flex-end alignment), and re-declaring it here would be a second copy that drifts.
   Only the two things the family does not own are set below. --------------------- */

/* A stable floor so the row does not jump when a short "Any K9" becomes a long dog name, and never wider than
   the viewport at 320px (min() collapses the floor rather than pushing the page sideways). */
.kl-an-filter-select[b-ajg4ndr4di],
.kl-an-filter-date[b-ajg4ndr4di] {
    min-block-size: var(--k-touch);
    min-inline-size: min(11rem, 100%);
    max-inline-size: 100%;
}

.kl-an-filter-summary[b-ajg4ndr4di] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    margin: 0 0 var(--k-space-3);
    font-size: 13px;
    color: var(--k-text-muted);
}

.kl-an-filter-clear[b-ajg4ndr4di] {
    align-self: flex-end;
}

/* Pie: slices separated by a 2px surface gap (the stroke IS the surface color). */
.kl-an-plot-pierow[b-ajg4ndr4di] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-4) var(--k-space-6);
}

.kl-an-plot--pie[b-ajg4ndr4di] {
    inline-size: min(280px, 100%);
    flex: 0 0 auto;
}

.kl-an-slice[b-ajg4ndr4di] {
    stroke: var(--k-surface);
    stroke-width: 2;
}

.kl-an-plot-legend[b-ajg4ndr4di] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
    min-inline-size: 0;
    flex: 1 1 14rem;
}

.kl-an-legend-item[b-ajg4ndr4di] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    font-size: 13px;
    color: var(--k-text);
    min-block-size: 24px;
}

.kl-an-legend-swatch[b-ajg4ndr4di] {
    flex: none;
    inline-size: 12px;
    block-size: 12px;
    border-radius: var(--k-radius-sm);
    border: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
}

.kl-an-legend-label[b-ajg4ndr4di] {
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kl-an-legend-value[b-ajg4ndr4di] {
    margin-inline-start: auto;
    font-family: var(--k-font-mono);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--k-text-muted);
}

.kl-an-plot-note[b-ajg4ndr4di] {
    margin: 0;
    font-size: 13px;
    color: var(--k-text-muted);
}

/* The 8-step single-hue ramp (accent mixed over the surface) shared by pie slices
   (fill) and legend swatches (background) — one class carries both properties, so
   swatch and slice can never drift apart. Identity is carried by the legend text +
   per-slice <title>, never by hue alone. */
.kl-an-c0[b-ajg4ndr4di] { fill: color-mix(in srgb, var(--k-accent) 88%, var(--k-surface)); background-color: color-mix(in srgb, var(--k-accent) 88%, var(--k-surface)); }
.kl-an-c1[b-ajg4ndr4di] { fill: color-mix(in srgb, var(--k-accent) 72%, var(--k-surface)); background-color: color-mix(in srgb, var(--k-accent) 72%, var(--k-surface)); }
.kl-an-c2[b-ajg4ndr4di] { fill: color-mix(in srgb, var(--k-accent) 58%, var(--k-surface)); background-color: color-mix(in srgb, var(--k-accent) 58%, var(--k-surface)); }
.kl-an-c3[b-ajg4ndr4di] { fill: color-mix(in srgb, var(--k-accent) 45%, var(--k-surface)); background-color: color-mix(in srgb, var(--k-accent) 45%, var(--k-surface)); }
.kl-an-c4[b-ajg4ndr4di] { fill: color-mix(in srgb, var(--k-accent) 34%, var(--k-surface)); background-color: color-mix(in srgb, var(--k-accent) 34%, var(--k-surface)); }
.kl-an-c5[b-ajg4ndr4di] { fill: color-mix(in srgb, var(--k-accent) 25%, var(--k-surface)); background-color: color-mix(in srgb, var(--k-accent) 25%, var(--k-surface)); }
.kl-an-c6[b-ajg4ndr4di] { fill: color-mix(in srgb, var(--k-accent) 17%, var(--k-surface)); background-color: color-mix(in srgb, var(--k-accent) 17%, var(--k-surface)); }
.kl-an-c7[b-ajg4ndr4di] { fill: color-mix(in srgb, var(--k-accent) 10%, var(--k-surface)); background-color: color-mix(in srgb, var(--k-accent) 10%, var(--k-surface)); }

/* ---- Drill-down list ----------------------------------------------------------
   Was three teal links running together as one ambiguous blob. Recompose as a
   labelled list of discrete, bordered row affordances — each a clear, separately
   tappable navigation with a trailing arrow that nudges on hover. -------------- */
.kl-an-drilldown[b-ajg4ndr4di] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    border-block-start: 1px solid var(--k-border);
    padding-block-start: var(--k-space-4);
}

.kl-an-drilldown-label[b-ajg4ndr4di] {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

.kl-an-drill-list[b-ajg4ndr4di] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}

.kl-an-drill[b-ajg4ndr4di] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
    min-block-size: var(--k-touch);
    padding: var(--k-space-2) var(--k-space-4);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface);
    color: var(--k-accent);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    transition: background var(--k-dur-1) var(--k-ease),
        border-color var(--k-dur-1) var(--k-ease), color var(--k-dur-1) var(--k-ease);
}

.kl-an-drill:hover[b-ajg4ndr4di] {
    background: var(--k-surface-2);
    border-color: var(--k-accent);
}

.kl-an-drill-text[b-ajg4ndr4di] {
    min-inline-size: 0;
}

.kl-an-drill-arrow[b-ajg4ndr4di] {
    flex: none;
    font-size: 16px;
    line-height: 1;
    color: var(--k-text-muted);
    transition: transform var(--k-dur-1) var(--k-ease), color var(--k-dur-1) var(--k-ease);
}

.kl-an-drill:hover .kl-an-drill-arrow[b-ajg4ndr4di] {
    color: var(--k-accent);
    transform: translateX(3px);
}

/* ---- Access-denied notice (fail-closed read) ---------------------------------- */
.kl-an-denied[b-ajg4ndr4di] {
    margin: 0;
    padding: var(--k-space-4);
    border-radius: var(--k-radius-md);
    border: 1px solid color-mix(in srgb, var(--k-critical) 35%, var(--k-surface));
    border-inline-start: 3px solid var(--k-critical);
    background: color-mix(in srgb, var(--k-critical) 8%, var(--k-surface));
    color: var(--k-text);
    font-size: 14px;
    line-height: 1.55;
}

/* =============================================================================
   Dark + dark-outdoor remaps — load-bearing legibility. The card + chip edges and
   the empty-disc need a darker-surface variant (mirrors the foundation pill-contrast
   pattern: definition survives the darker / brighter variants).
   ========================================================================== */
html.dark .kl-an-controls[b-ajg4ndr4di],
html.dark .kl-an-chart[b-ajg4ndr4di],
html.dark .kl-an-empty.kl-empty[b-ajg4ndr4di] {
    border-color: var(--k-border);
    box-shadow: var(--k-elev-2);
}

html.dark .kl-an-denied[b-ajg4ndr4di] {
    background: color-mix(in srgb, var(--k-critical) 18%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-critical) 50%, var(--k-surface));
}

/* Dark-outdoor (sunlight-legibility) — push the card + control edges a touch harder
   so definition survives the brighter, higher-contrast variant. */
html.dark[data-outdoor="true"] .kl-an-controls[b-ajg4ndr4di],
html.dark[data-outdoor="true"] .kl-an-chart[b-ajg4ndr4di],
html.dark[data-outdoor="true"] .kl-an-empty.kl-empty[b-ajg4ndr4di],
html.dark[data-outdoor="true"] .kl-an-drill[b-ajg4ndr4di] {
    border-color: color-mix(in srgb, var(--k-border) 78%, var(--k-text));
}

/* ---- Honour reduced-motion: drop the drill micro-motion (a11y) ----------------- */
@media (prefers-reduced-motion: reduce) {
    .kl-an-drill[b-ajg4ndr4di],
    .kl-an-drill-arrow[b-ajg4ndr4di] {
        transition: none;
    }
}
/* _content/Kanine.Web/Components/Pages/ReportBuilder.razor.rz.scp.css */
/* UI-GUAR-003 / RPT-014 — Report builder (report-builder.html), page-major R11 (restrained-premium). Consumes the
   global foundation vocabulary (kf-input/-textarea, kl-btn + --primary/--secondary/--ghost, kl-segmented, kl-chip,
   kl-visually-hidden, the suffix card/field/denied/error families) from kanine-design-system.css; this scoped sheet
   adds ONLY the two-column config/preview shell, the column-picker rows + analyzable/PII badges, the filter + group/
   sort surfaces, the live-preview table, the export cluster, and the save dialog. Every colour is a --k-* token (via
   color-mix where a tint is needed) — no raw fills, no gradients, no off-token colour — so the R11 token/canvas teeth
   hold across light / dark / outdoor. Only defined spacing tokens are used (no --k-space-5). */

.kl-rb-intro[b-wivlxb9fzq] {
    margin: 0 0 var(--k-space-4);
    color: var(--k-text-muted);
    font-size: 15px;
    max-inline-size: 70ch;
}

/* ---- Analytics-drill active-scope chip ------------------------------------ */
.kl-rb-scopechips[b-wivlxb9fzq] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin: 0 0 var(--k-space-4);
}

.kl-rb-scopechip[b-wivlxb9fzq] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-rb-scopechip-x[b-wivlxb9fzq] {
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 20px;
    block-size: 20px;
    min-block-size: auto;
    padding: 0;
    border: 0;
    border-radius: var(--k-radius-full);
    background: transparent;
    color: inherit;
    cursor: pointer;
    font-size: 12px;
}

.kl-rb-scopechip-x:hover[b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-text) 12%, transparent);
}

/* ---- Card-title lead glyphs (iconned headers law) -------------------------
   Only the COLOUR is this page's. §5a sizes the glyph at 0.92em of its head and gives it the product's 8px
   gutter; the 16px and the 4px that stood here were this page reading a size and a gutter of its own. */
.kl-rb-card-icon[b-wivlxb9fzq] {
    color: var(--k-accent);
}

/* ---- Top / bottom action bars (mirrored) --------------------------------- */
/* A multi-class element (kl-rb-actionbar kl-rb-actionbar-top) can't lean on the foundation's whole-attribute
   [class$="-actionbar"] suffix, so the bar chrome is set explicitly here. */
.kl-rb-actionbar[b-wivlxb9fzq] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--k-space-3);
}

.kl-rb-actionbar-top[b-wivlxb9fzq] {
    padding-block-end: var(--k-space-4);
    margin-block-end: var(--k-space-4);
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
}

.kl-rb-actionbar-bottom[b-wivlxb9fzq] {
    padding-block-start: var(--k-space-4);
    margin-block-start: var(--k-space-2);
    border-block-start: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
    /* Comb fix (02/05) — clearance for the app-wide FIXED feedback FAB (48px disc at right/bottom 20px, another
       lane's component — never moved from here): the sticky preview column pins this bar near the viewport's
       bottom-right, exactly the FAB's home, so the bar's right-aligned buttons sat under the disc. Page-scoped
       trailing padding keeps every button clear of the 68px FAB zone at desktop AND at the single-column width. */
    padding-block-end: 72px;
}

.kl-rb-btn .ki[b-wivlxb9fzq],
.kl-rb-export-run .ki[b-wivlxb9fzq] {
    font-size: 20px;
}

/* Review fix (M4): the visible schedule-gate reason line inside the mirrored action bars — a small muted inline
   note (never tooltip-only); outdoor lifts it to full text with the other guidance lines below. */
.kl-rb-schedule-gate-note[b-wivlxb9fzq] {
    font-size: 12.5px;
    color: var(--k-text-muted);
}

/* ---- Two-column shell: configuration (left) + live preview (right) ------- */
.kl-rb-layout[b-wivlxb9fzq] {
    display: grid;
    grid-template-columns: minmax(0, 23rem) minmax(0, 1fr);
    gap: var(--k-space-6);
    align-items: start;
}

/* W1 redesign (report-builder-redesign-spec.md): the PREVIEW is the sticky column now — "the paper is the product",
   so it stays on screen for the whole ~3,600px config rail scroll. The config rail loses its sticky (it is the tall
   one); the preview card scrolls INTERNALLY inside the viewport-height cap. */
.kl-rb-config[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    min-inline-size: 0;
}

.kl-rb-preview-col[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    min-inline-size: 0;
    position: sticky;
    inset-block-start: var(--k-space-4);
    max-block-size: calc(100vh - 2rem);
}

/* The preview CARD owns the internal scroll (the column itself never overflows the viewport cap). */
.kl-rb-preview-col .kl-rb-preview-card[b-wivlxb9fzq] {
    flex: 1 1 auto;
    min-block-size: 0;
    overflow-y: auto;
}

/* The config cards already pick up the foundation card chrome via [class$="-card"]; trim the default block margin so
   the column's own gap governs rhythm, and keep dense inner spacing for the picker. */
.kl-rb-config .kl-rb-card[b-wivlxb9fzq],
.kl-rb-preview-col .kl-rb-card[b-wivlxb9fzq] {
    margin-block-end: 0;
}

/* ---- Column picker ------------------------------------------------------- */
.kl-rb-col-group-title[b-wivlxb9fzq] {
    margin: var(--k-space-3) 0 var(--k-space-2);
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--k-text-muted);
}

.kl-rb-col-group-title:first-of-type[b-wivlxb9fzq] {
    margin-block-start: 0;
}

/* W1 density (reworked twice): the picker is a dense grid instead of one airy row per checkbox — Activities'
   ~26 columns drop from two screenfuls to one, rows keep their 40px touchable height. History: W1's
   `auto-fill, minmax(11rem, 1fr)` never fit two tracks in the 23rem rail (silently one column); the W4 polish
   pass hard-coded two tracks, which crushed badge-row labels to two letters on narrow/mobile widths. The
   auto-fit floor below + the badge-row span rule are the final shape: density where it fits, full-width
   readable labels where it doesn't. */
.kl-rb-col-list[b-wivlxb9fzq] {
    list-style: none;
    margin: 0 0 var(--k-space-2);
    padding: 0;
    display: grid;
    /* Owner fix (2026-07-14): labels must stay READABLE at every width. auto-fit with a 10rem floor keeps the
       two-up density in the desktop rail but honestly collapses to ONE column in a narrow container (the fixed
       two-track template crushed labels to two letters on phones); min(100%, …) keeps the track legal below 10rem. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
    gap: 2px;
}

/* A row that carries a badge (Dimension/Measure/PII) needs label + badge on one line — it SPANS the grid so the
   label is never sacrificed to a half-width cell. Plain rows keep flowing two-up around it; the badge row reads
   as gentle emphasis (deliberate for PII). */
.kl-rb-col-row:has(.kl-rb-badge)[b-wivlxb9fzq] {
    grid-column: 1 / -1;
}

/* The honest empty-state note spans the whole grid (it is a message, not a cell). */
.kl-rb-col-list .kl-rb-col-empty[b-wivlxb9fzq] {
    grid-column: 1 / -1;
}

/* Override the foundation's heavy bordered [class$="-row"] card so each column toggle reads as a light, tappable
   picker row (hover wash, no per-row border) — the dense list shouldn't look like a stack of cards. */
.kl-rb-col-row[b-wivlxb9fzq] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    /* A6 2026-09-13 — THE PADDING MOVED TO THE LABEL, and that is the whole trick. The row was already 50px and
       the bare checkbox inside it measured a 18.4px box with an 18px continuous hit span, eleven times over: the
       /dogs/{id}/edit precedent exactly, where the row was 44px and only the control inside it fell short. The
       answer there was to make the label fill the row, so it is the answer here.
       The padding cannot stay on the <li>, because the label would then stop at the padding edge and measure 42 —
       two pixels under the floor, which is how a fix like this reads green and is not one. Moving the same tokens
       onto the label changes NOTHING visually and makes the label's box the row's box.
       Everything list-level stays on the <li>: the `:has(.kl-rb-badge)` grid span, `--filtered`'s `display:none`
       (a label with display:none inside a surviving <li> would leave an empty grid cell and break step 2's
       search), and the hover wash. */
    padding: 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--k-radius-md);
    min-block-size: 2.5rem;
    transition: background var(--k-dur-1) var(--k-ease);
}

/* The pressable body of a column-toggle row. It fills the row in both axes and carries the row's old padding, so
   the whole row — checkbox, label text and badge — activates the checkbox. These inputs had NO <label> of any
   kind before this, so this also gives each one an accessible name from its own visible text. */
.kl-rb-col-label[b-wivlxb9fzq] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    flex: 1 1 auto;
    min-inline-size: 0;
    min-block-size: var(--k-touch);
    padding: var(--k-space-1) var(--k-space-2);
    cursor: pointer;
}

/* W1 — a search-hidden row: CSS-only (the checkbox STAYS in the DOM for every contracted selector).
   Comb fix (B1) — this rule MUST beat the `.kl-rb-col-row { display: flex }` base above: it once sat BEFORE that
   base rule at EQUAL specificity, so the later `display: flex` won the cascade and the step-② search hid nothing.
   It now (a) sits AFTER the base rule AND (b) carries the doubled-class selector, so it wins on specificity even
   if this sheet is ever reordered again. Regression anchor: kl-rb-col-row--filtered-after-base (a Web.Tests
   sheet-order test reads this file and asserts both the order and the doubled-class selector). */
.kl-rb-col-row.kl-rb-col-row--filtered[b-wivlxb9fzq] {
    display: none;
}

.kl-rb-col-row:hover[b-wivlxb9fzq] {
    background: var(--k-surface-2);
}

.kl-rb-col-row input[type="checkbox"][b-wivlxb9fzq] {
    inline-size: 1.15rem;
    block-size: 1.15rem;
    min-block-size: auto;
    margin: 0;
    accent-color: var(--k-teal-500);
    cursor: pointer;
    flex: 0 0 auto;
}

.kl-rb-col-row input[type="checkbox"]:disabled[b-wivlxb9fzq] {
    cursor: not-allowed;
    opacity: .55;
}

/* W4 polish — dense-grid labels stay ONE line and ellipsize (the row's title attribute carries the full text);
   without this a long header re-wraps the 40px row back into the tall airy rows the density pass removed. */
.kl-rb-col-row .kl-rb-col-label > span:first-of-type[b-wivlxb9fzq] {
    flex: 1 1 auto;
    min-inline-size: 0;
    color: var(--k-text);
    font-size: 13.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A disabled (non-analyzable) row reads quieter so the picker is honest about why it can't be added. */
.kl-rb-col-row:has(input:disabled) .kl-rb-col-label > span:first-of-type[b-wivlxb9fzq] {
    color: var(--k-text-muted);
}

/* Honest empty-state line for the auto-enumerated custom-field group — a small inline note (NOT the foundation's big
   centered [class$="-empty"] state block, which this scoped rule overrides). */
.kl-rb-col-empty[b-wivlxb9fzq] {
    display: block;
    padding: var(--k-space-2) var(--k-space-3);
    color: var(--k-text-muted);
    font-size: 13px;
    line-height: 1.5;
}

/* Inline guidance under the visualization cards (why every card but Table is disabled) + the honest letterhead note.
   Both are calm accent-tinted info lines, not alarms — they explain and point, never scold. */
.kl-rb-viz-hint[b-wivlxb9fzq],
.kl-rb-check-note[b-wivlxb9fzq] {
    display: block;
    margin: var(--k-space-2) 0 0;
    padding: var(--k-space-2) var(--k-space-3);
    border-radius: var(--k-radius-md, 8px);
    background: color-mix(in srgb, var(--k-accent) 10%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-accent) 30%, var(--k-surface));
    color: var(--k-text-muted);
    font-size: 13px;
    line-height: 1.5;
}

.kl-rb-viz-hint-icon[b-wivlxb9fzq] {
    color: var(--k-accent);
    margin-right: 4px;
    vertical-align: -2px;
}

.kl-rb-check-note a[b-wivlxb9fzq],
.kl-rb-viz-hint .kl-linkbtn[b-wivlxb9fzq] {
    color: var(--k-accent);
    font-weight: 600;
}

/* A text button that reads as a link (used to jump focus to step ④) — no chrome, keyboard-focusable. */
.kl-linkbtn[b-wivlxb9fzq] {
    appearance: none;
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--k-accent);
    font-weight: 600;
    text-decoration: underline;
    cursor: pointer;
}

.kl-linkbtn:hover[b-wivlxb9fzq] {
    text-decoration: none;
}

/* ---- Analyzable / PII badges (shape + text + colour, never colour alone) -- */
.kl-rb-badge[b-wivlxb9fzq] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: 0 0 auto;
    padding: 2px 8px;
    border-radius: var(--k-radius-full);
    border: 1px solid;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    line-height: 1.6;
    white-space: nowrap;
}

.kl-rb-badge-dim[b-wivlxb9fzq] {
    color: #0b5c3c;
    background: color-mix(in srgb, var(--k-success) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-success) 35%, var(--k-surface));
}

.kl-rb-badge-measure[b-wivlxb9fzq] {
    color: #0b4f8a;
    background: color-mix(in srgb, var(--k-info) 10%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-info) 32%, var(--k-surface));
}

.kl-rb-badge-pii[b-wivlxb9fzq] {
    color: #7a1b12;
    background: color-mix(in srgb, var(--k-critical) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-critical) 35%, var(--k-surface));
}

.kl-rb-badge-muted[b-wivlxb9fzq] {
    color: var(--k-text-muted);
    background: var(--k-surface-2);
    border-color: var(--k-border);
}

/* Dark-mode badge contrast (the fixed dark-on-tint above is near-invisible on the dark surface — re-map to light text
   on a more-saturated fill so the load-bearing analyzable/PII signal stays legible in dark + dark-outdoor). */
html.dark .kl-rb-badge-dim[b-wivlxb9fzq] {
    color: #9ce6c1;
    background: color-mix(in srgb, var(--k-success) 30%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-success) 55%, var(--k-surface));
}

html.dark .kl-rb-badge-measure[b-wivlxb9fzq] {
    color: #aacdff;
    background: color-mix(in srgb, var(--k-info) 30%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-info) 55%, var(--k-surface));
}

html.dark .kl-rb-badge-pii[b-wivlxb9fzq] {
    color: #f6ab9d;
    background: color-mix(in srgb, var(--k-critical) 30%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-critical) 55%, var(--k-surface));
}

/* ---- Filters + group/sort ------------------------------------------------ */
.kl-rb-filter-form[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}

.kl-rb-filter-form > label[b-wivlxb9fzq] {
    font-size: 13px;
    font-weight: 600;
    color: var(--k-text-muted);
    margin-block-start: var(--k-space-2);
}

.kl-rb-filter-form > label:first-of-type[b-wivlxb9fzq] {
    margin-block-start: 0;
}

/* Override the foundation's bordered [class$="-row"] card for the two inline check rows — a plain inline label. */
.kl-rb-check-row[b-wivlxb9fzq] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    padding: var(--k-space-1) 0;
    margin-block-start: var(--k-space-2);
    background: transparent;
    border: 0;
    border-radius: 0;
    /* A6 2026-09-13 — was `min-block-size: auto`, which resolved to 29px. The checkbox inside measured a 18.4px
       box and the LABEL carried the target at 30px, so the label was already the right mechanism and was simply
       too short. A box floor on the label, not a band: this row sits directly under a <select> and directly above
       a card edge, and a band would reach both. Measured after: hit 48. */
    min-block-size: var(--k-touch);
    font-size: 14px;
    color: var(--k-text);
    cursor: pointer;
}

.kl-rb-check-row input[type="checkbox"][b-wivlxb9fzq] {
    inline-size: 1.15rem;
    block-size: 1.15rem;
    min-block-size: auto;
    margin: 0;
    accent-color: var(--k-teal-500);
    cursor: pointer;
}

/* Sort-direction segmented control. */
.kl-rb-sortdir[b-wivlxb9fzq] {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    overflow: hidden;
    margin-block-start: var(--k-space-1);
    inline-size: fit-content;
}

.kl-rb-sortdir-btn[b-wivlxb9fzq] {
    appearance: none;
    min-block-size: var(--k-touch);
    padding: 0 var(--k-space-4);
    background: transparent;
    color: var(--k-text);
    border: 0;
    border-inline-end: 1px solid var(--k-border);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease), color var(--k-dur-1) var(--k-ease);
}

.kl-rb-sortdir-btn:last-child[b-wivlxb9fzq] {
    border-inline-end: 0;
}

.kl-rb-sortdir-btn:hover[b-wivlxb9fzq] {
    background: var(--k-surface-2);
}

/* Selected = a restrained TONAL accent wash (NOT the saturated teal reserved for the sole Export primary): the
   sort direction is a low-stakes state toggle, so it speaks the same quiet selected-state language as the export-
   format segmented control and every other signed page's aria-pressed control. */
.kl-rb-sortdir-btn[aria-pressed="true"][b-wivlxb9fzq] {
    /* Final-draft bump: the 14% wash read barely-active in the shots — a stronger tint + an inset accent
       ring so the pressed direction is unmistakable in light AND dark (still tonal, not the primary teal). */
    background: color-mix(in srgb, var(--k-accent) 22%, var(--k-surface));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--k-accent) 55%, var(--k-border));
    color: var(--k-text);
    font-weight: 700;
}

/* ---- Live preview -------------------------------------------------------- */
.kl-rb-preview-head[b-wivlxb9fzq] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3) var(--k-space-4);
    margin-block-end: var(--k-space-4);
}

.kl-rb-preview-head .kl-rb-card-title[b-wivlxb9fzq] {
    margin: 0;
}

/* Export cluster: format segmented control + the single filled-teal primary. */
.kl-rb-export[b-wivlxb9fzq] {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-rb-export-format[b-wivlxb9fzq] {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    overflow: hidden;
}

.kl-rb-format[b-wivlxb9fzq] {
    appearance: none;
    /* A6 2026-09-13 — was 2.5rem (40px), measured box 40 / hit 40. Four segments of one control, side by side,
       so the floor is block-axis only: an inline minimum would push a segment over its neighbour's divider. */
    min-block-size: var(--k-touch);
    padding: 0 var(--k-space-3);
    background: transparent;
    color: var(--k-text-muted);
    border: 0;
    border-inline-end: 1px solid var(--k-border);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease), color var(--k-dur-1) var(--k-ease);
}

.kl-rb-format:last-child[b-wivlxb9fzq] {
    border-inline-end: 0;
}

.kl-rb-format:hover[b-wivlxb9fzq] {
    background: var(--k-surface-2);
    color: var(--k-text);
}

/* Selected export format = the SAME restrained tonal accent wash the sort-direction control uses, so the page's two
   segmented controls speak one quiet selected-state language and only Export wears the saturated primary teal. */
.kl-rb-format[aria-pressed="true"][b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-accent) 14%, var(--k-surface));
    color: var(--k-text);
    font-weight: 700;
}

.kl-rb-export-run[b-wivlxb9fzq] {
    /* A6 2026-09-13 — was 2.5rem (40px), measured box 40 / hit 40. */
    min-block-size: var(--k-touch);
}

/* Preview table — the right-aligned measure column + a self-describing header. */
.kl-rb-table[b-wivlxb9fzq] {
    inline-size: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.kl-rb-table thead th[b-wivlxb9fzq] {
    text-align: start;
    padding: var(--k-space-2) var(--k-space-3);
    background: var(--k-surface-2);
    color: var(--k-text-muted);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    white-space: nowrap;
    border-block-end: 1px solid var(--k-border);
}

.kl-rb-table thead th:last-child[b-wivlxb9fzq] {
    text-align: end;
}

.kl-rb-table tbody td[b-wivlxb9fzq] {
    padding: var(--k-space-2) var(--k-space-3);
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 55%, transparent);
    color: var(--k-text);
    vertical-align: middle;
}

.kl-rb-table tbody td:last-child[b-wivlxb9fzq] {
    text-align: end;
    font-family: var(--k-font-mono);
    font-variant-numeric: tabular-nums;
}

.kl-rb-table tbody tr:last-child td[b-wivlxb9fzq] {
    border-block-end: 0;
}

.kl-rb-table tbody tr[b-wivlxb9fzq] {
    transition: background var(--k-dur-1) var(--k-ease);
}

.kl-rb-table tbody tr:hover[b-wivlxb9fzq] {
    background: var(--k-surface-2);
}

/* ---- Save dialog ---------------------------------------------------------- */
/* UI-GUAR-033: overlay/scrim retired — <KlOverlay> now supplies the fixed scrim + centering. This only sizes the
   card + carries its surface/elevation. */
.kl-rb-dialog[b-wivlxb9fzq] {
    inline-size: min(34rem, calc(100vw - 2rem));
    max-block-size: calc(100vh - 4rem);
    overflow-y: auto;
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-3);
}

.kl-rb-save-form[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    padding: var(--k-space-6);
}

.kl-rb-dialog-title[b-wivlxb9fzq] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 18px;
    font-weight: 700;
    color: var(--k-text);
}

.kl-rb-field[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
}

.kl-rb-field label[b-wivlxb9fzq] {
    font-size: 13px;
    font-weight: 600;
    color: var(--k-text-muted);
}

.kl-rb-dialog-note[b-wivlxb9fzq] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-2);
    margin: 0;
    padding: var(--k-space-3);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
    color: var(--k-text-muted);
    font-size: 13px;
    line-height: 1.5;
}

.kl-rb-dialog-note .ki[b-wivlxb9fzq] {
    font-size: 18px;
    color: var(--k-teal-700);
    flex: 0 0 auto;
}

html.dark .kl-rb-dialog-note .ki[b-wivlxb9fzq] {
    color: var(--k-teal-400);
}

.kl-rb-dialog-actions[b-wivlxb9fzq] {
    display: flex;
    justify-content: flex-end;
    gap: var(--k-space-2);
    margin-block-start: var(--k-space-2);
}

/* ---- Resilient-load banner (RPT-014 increment 2) -------------------------- */
/* Foundation .kl-banner supplies colour/spacing; this only lays out the retry affordance on the same row. */
.kl-rb-load-error[b-wivlxb9fzq] {
    align-items: center;
    gap: var(--k-space-3);
}

.kl-rb-load-error-text[b-wivlxb9fzq] {
    flex: 1 1 12rem;
    min-inline-size: 0;
}

.kl-rb-load-retry[b-wivlxb9fzq] {
    flex: 0 0 auto;
    min-block-size: 2.25rem;
}

/* ---- Inline update-conflict message --------------------------------------- */
.kl-rb-update-error[b-wivlxb9fzq] {
    margin: calc(-1 * var(--k-space-2)) 0 var(--k-space-4);
    padding: var(--k-space-2) var(--k-space-3);
    border-radius: var(--k-radius-md);
    background: color-mix(in srgb, var(--k-caution) 12%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-caution) 40%, var(--k-surface));
    color: var(--k-text);
    font-size: 13px;
    line-height: 1.5;
}

/* ---- My-reports library ---------------------------------------------------- */
.kl-rb-library-head[b-wivlxb9fzq] {
    appearance: none;
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    inline-size: 100%;
    /* A6 2026-09-13 — measured box 24 / hit 24. It is the whole card header and the only way to open the saved-
       reports list, and it was the smallest target on the page. A full-width header button has no horizontal
       neighbour to steal from, so the box floor is free of risk; the card grows 24px once. */
    min-block-size: var(--k-touch);
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--k-text);
    font: inherit;
    cursor: pointer;
    text-align: start;
}

.kl-rb-library-title[b-wivlxb9fzq] {
    margin: 0;
    flex: 1 1 auto;
    font-family: var(--k-font-display);
    font-size: 16px;
    font-weight: 700;
}

.kl-rb-library-count[b-wivlxb9fzq] {
    flex: 0 0 auto;
    min-inline-size: 22px;
    padding: 1px 7px;
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    color: var(--k-text-muted);
    font-size: 11px;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.kl-rb-library-chev[b-wivlxb9fzq] {
    flex: 0 0 auto;
    font-size: 16px;
    color: var(--k-text-muted);
}

.kl-rb-library-error[b-wivlxb9fzq] {
    margin: var(--k-space-3) 0 0;
    padding: var(--k-space-2) var(--k-space-3);
    border-radius: var(--k-radius-md);
    background: color-mix(in srgb, var(--k-caution) 12%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-caution) 40%, var(--k-surface));
    color: var(--k-text);
    font-size: 13px;
    line-height: 1.5;
}

.kl-rb-library-empty[b-wivlxb9fzq] {
    margin: var(--k-space-3) 0 0;
    color: var(--k-text-muted);
    font-size: 13px;
    line-height: 1.5;
}

.kl-rb-library-list[b-wivlxb9fzq] {
    list-style: none;
    margin: var(--k-space-3) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
}

/* Override the foundation's heavy bordered [class$="-item"] chrome: a light, hoverable library row. */
.kl-rb-library-item[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
    padding: var(--k-space-2) var(--k-space-3);
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--k-radius-md);
    transition: background var(--k-dur-1) var(--k-ease), border-color var(--k-dur-1) var(--k-ease);
}

.kl-rb-library-item:hover[b-wivlxb9fzq] {
    background: var(--k-surface-2);
    border-color: color-mix(in srgb, var(--k-border) 70%, transparent);
}

.kl-rb-library-main[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-inline-size: 0;
}

.kl-rb-library-name[b-wivlxb9fzq] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    font-size: 14px;
    font-weight: 600;
    color: var(--k-text);
    overflow-wrap: anywhere;
}

.kl-rb-library-loaded[b-wivlxb9fzq] {
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: var(--k-radius-full);
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    background: color-mix(in srgb, var(--k-accent) 16%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-accent) 45%, var(--k-surface));
    color: var(--k-text);
}

.kl-rb-library-loaded--dirty[b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-caution) 16%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-caution) 45%, var(--k-surface));
}

.kl-rb-library-meta[b-wivlxb9fzq] {
    font-size: 12px;
    color: var(--k-text-muted);
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-rb-library-version[b-wivlxb9fzq] {
    padding: 0 6px;
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    font-size: 10px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.kl-rb-library-actions[b-wivlxb9fzq] {
    display: flex;
    align-items: center;
    gap: var(--k-space-1);
}

/* A6 wave 3, 2026-09-13 — Load / Duplicate / Delete on every saved report. MEASURED box 32 / hit 32 at
   1400x900 AND at 393x852, three per row.

   THE BAND IS INLINE-CONSTRAINED, and that is what makes it the right answer rather than a floor. These three
   are horizontal siblings 4px apart, so `inset-inline: 0` holds each band inside its own button's width and no
   band can reach the button beside it — including Delete, whose band must never grow toward Duplicate.
   Vertically, the next saved report's Load button is 66-67px away at both widths and the library head is 66px
   above the first row, so a `--k-touch` band on a 32px box (7.6px of overhang) clears every neighbour by 58px.
   Every sample point inside the band is this row's own `li.kl-rb-library-item`.

   A floor was rejected: it adds 12px to every saved report's row, and a library is a list that grows. */
.kl-rb-library-act[b-wivlxb9fzq] {
    appearance: none;
    position: relative;
    min-block-size: 2rem;
    padding: 0 var(--k-space-2);
    border: 0;
    border-radius: var(--k-radius-sm, var(--k-radius-md));
    background: transparent;
    color: var(--k-teal-700);
    font: inherit;
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease);
}

.kl-rb-library-act[b-wivlxb9fzq]::after {
    content: "";
    position: absolute;
    inset-block: calc((100% - var(--k-touch, 44px)) / 2);
    inset-inline: 0;
}

.kl-rb-library-act:hover[b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-accent) 14%, var(--k-surface));
}

.kl-rb-library-act--danger[b-wivlxb9fzq] {
    color: var(--k-critical);
}

.kl-rb-library-act--danger:hover[b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-critical) 12%, var(--k-surface));
}

html.dark .kl-rb-library-act[b-wivlxb9fzq] {
    color: var(--k-teal-400);
}

html.dark .kl-rb-library-act--danger[b-wivlxb9fzq] {
    color: color-mix(in srgb, var(--k-critical) 70%, white);
}

/* ---- The numbered step rail (orientation, never gating) -------------------- */
/* W4 polish — the step header is a 2-row GRID: row 1 = number/tick · title+hint · chevron; row 2 = the LIVE
   summary on its OWN full-width line. Squeezed right of the hint (the W1 flex layout, max-inline-size 45%) the
   summary truncated to slivers ("5 …", "No…", "Deployments & activit…") in the live QA shots — its own line gives
   it the card's whole width, one line, honest ellipsis only when genuinely long. */
.kl-rb-step-head[b-wivlxb9fzq] {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    column-gap: var(--k-space-3);
    row-gap: 2px;
    margin-block-end: var(--k-space-3);
}

.kl-rb-step-head .kl-rb-step-num[b-wivlxb9fzq] {
    grid-column: 1;
    grid-row: 1 / span 2;
}

.kl-rb-step-head .kl-rb-step-text[b-wivlxb9fzq] {
    grid-column: 2;
    grid-row: 1;
}

.kl-rb-step-head .kl-rb-step-chev[b-wivlxb9fzq] {
    grid-column: 3;
    grid-row: 1;
}

.kl-rb-step-num[b-wivlxb9fzq] {
    flex: 0 0 auto;
    inline-size: 28px;
    block-size: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    color: var(--k-text-muted);
    font-size: 13px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    transition: background var(--k-dur-2) var(--k-ease), color var(--k-dur-2) var(--k-ease),
                border-color var(--k-dur-2) var(--k-ease);
}

/* Configured = the teal tick (shape + glyph, never colour alone — the glyph swaps from the digit to a check). */
.kl-rb-step-num--done[b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-accent) 20%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-accent) 55%, var(--k-border));
    color: var(--k-teal-700);
}

html.dark .kl-rb-step-num--done[b-wivlxb9fzq] {
    color: var(--k-teal-400);
}

.kl-rb-step-num .ki[b-wivlxb9fzq] {
    font-size: 17px;
}

.kl-rb-step-text[b-wivlxb9fzq] {
    min-inline-size: 0;
}

.kl-rb-step-title[b-wivlxb9fzq] {
    margin: 0;
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    font-family: var(--k-font-display);
    font-size: 16px;
    font-weight: 700;
    color: var(--k-text);
}

.kl-rb-step-hint[b-wivlxb9fzq] {
    margin: 2px 0 0;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--k-text-muted);
}

/* Active-filter count badge on the Filters step title. */
.kl-rb-filter-count[b-wivlxb9fzq] {
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: var(--k-radius-full);
    background: color-mix(in srgb, var(--k-accent) 16%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-accent) 45%, var(--k-surface));
    color: var(--k-text);
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    white-space: nowrap;
}

/* The focus hand-off target (the empty-draft CTA): a visible ring, no layout jump. */
.kl-rb-step:focus-visible[b-wivlxb9fzq] {
    outline: 2px solid var(--k-accent);
    outline-offset: 2px;
}

/* ---- Preview toolbar: row-count chip + WYSIWYG caption --------------------- */
.kl-rb-rowcount[b-wivlxb9fzq] {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.kl-rb-wysiwyg[b-wivlxb9fzq] {
    margin: calc(-1 * var(--k-space-2)) 0 var(--k-space-4);
    font-size: 12.5px;
    color: var(--k-text-muted);
}

/* Comb fix (B5) — the after-export confirmation by the Export button: a calm success line (accent tint) that
   fades in; the unconfirmed (browser-blocked) variant re-tints caution. Token-only; dark/outdoor ride the tokens. */
.kl-rb-export-done[b-wivlxb9fzq] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-2);
    margin: 0 0 var(--k-space-3);
    padding: var(--k-space-2) var(--k-space-3);
    border-radius: var(--k-radius-md);
    background: color-mix(in srgb, var(--k-accent) 10%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-accent) 30%, var(--k-surface));
    color: var(--k-text);
    font-size: 13px;
    line-height: 1.5;
    animation: kl-rb-fade-in-b-wivlxb9fzq var(--k-dur-3) var(--k-ease);
}

.kl-rb-export-done .ki[b-wivlxb9fzq] {
    flex: 0 0 auto;
    font-size: 16px;
    color: var(--k-accent);
}

.kl-rb-export-done[data-pushed="false"][b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-caution) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-caution) 40%, var(--k-surface));
}

.kl-rb-export-done[data-pushed="false"] .ki[b-wivlxb9fzq] {
    color: var(--k-caution);
}

@media (prefers-reduced-motion: reduce) {
    .kl-rb-export-done[b-wivlxb9fzq] {
        animation: none;
    }
}

/* ---- Composed empty-draft state -------------------------------------------- */
.kl-rb-empty-draft[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--k-space-2);
    padding: var(--k-space-8) var(--k-space-6);
    margin-block-end: var(--k-space-4);
    border: 1px dashed color-mix(in srgb, var(--k-border) 85%, var(--k-text-muted));
    border-radius: var(--k-radius-lg);
    background: color-mix(in srgb, var(--k-surface-2) 55%, var(--k-surface));
    text-align: center;
}

.kl-rb-empty-draft-icon[b-wivlxb9fzq] {
    font-size: 34px;
    color: var(--k-text-muted);
}

.kl-rb-empty-draft-lead[b-wivlxb9fzq] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 16px;
    font-weight: 700;
    color: var(--k-text);
}

.kl-rb-empty-draft-sub[b-wivlxb9fzq] {
    margin: 0 0 var(--k-space-2);
    max-inline-size: 42ch;
    font-size: 13px;
    line-height: 1.5;
    color: var(--k-text-muted);
}

/* ---- Series summary sub-heading + diagnostics polish ------------------------ */
.kl-rb-series-title[b-wivlxb9fzq] {
    display: flex;
    align-items: baseline;
    gap: var(--k-space-2);
    margin: var(--k-space-4) 0 var(--k-space-2);
    font-family: var(--k-font-display);
    font-size: 14px;
    font-weight: 700;
    color: var(--k-text);
}

/* Definition notices read as small dismissible-looking cards (they clear themselves when the draft heals). */
.kl-rb-defdiag[b-wivlxb9fzq] {
    list-style: none;
    margin: 0 0 var(--k-space-3);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
}

.kl-rb-defdiag-item[b-wivlxb9fzq] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-2);
    padding: var(--k-space-2) var(--k-space-3);
    border-radius: var(--k-radius-md);
    background: color-mix(in srgb, var(--k-info) 8%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-info) 28%, var(--k-surface));
    color: var(--k-text);
    font-size: 12.5px;
    line-height: 1.5;
}

.kl-rb-defdiag-icon[b-wivlxb9fzq] {
    flex: 0 0 auto;
    font-size: 15px;
    color: var(--k-info);
}

/* ---- Motion: the paper preview fades in on each recompile (rows-hash keyed) -- */
.kl-rb-defpreview[b-wivlxb9fzq] {
    animation: kl-rb-fade-in-b-wivlxb9fzq var(--k-dur-3) var(--k-ease);
}

/* Comb fix (11) — the Orientation toggle is VISIBLE on the paper: the shared component's own landscape rule only
   raises max-inline-size 800→1080px, which the preview pane (usually narrower than 800px is wider than… the pane
   clamps both) rendered identically. Page-scoped: PORTRAIT reads as a narrower upright sheet (a US-Letter-ish
   612:792 width cut against the pane), LANDSCAPE stretches to the full pane width — so flipping the toggle
   visibly reshapes the sheet. CSS only; the component markup already stamps .is-landscape from the layout. */
.kl-rb-defpreview[b-wivlxb9fzq]  .kl-repdoc {
    max-inline-size: 640px;
}

.kl-rb-defpreview[b-wivlxb9fzq]  .kl-repdoc.is-landscape {
    max-inline-size: 100%;
}

@keyframes kl-rb-fade-in-b-wivlxb9fzq {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .kl-rb-defpreview[b-wivlxb9fzq] {
        animation: none;
    }

    .kl-rb-step-num[b-wivlxb9fzq],
    .kl-rb-library-item[b-wivlxb9fzq],
    .kl-rb-library-act[b-wivlxb9fzq],
    .kl-rb-col-row[b-wivlxb9fzq],
    .kl-rb-sortdir-btn[b-wivlxb9fzq],
    .kl-rb-format[b-wivlxb9fzq],
    .kl-rb-table tbody tr[b-wivlxb9fzq] {
        transition: none;
    }
}

/* ---- Delete-confirm dialog --------------------------------------------------- */
.kl-rb-confirm-shell[b-wivlxb9fzq] {
    inline-size: min(26rem, calc(100vw - 2rem));
}

.kl-rb-confirm-body[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    padding: var(--k-space-6);
}

.kl-rb-confirm-copy[b-wivlxb9fzq] {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--k-text-muted);
}

/* ---- Deliberate dark + outdoor (R11 punch-list) -------------------------- */
html.dark .kl-rb-config .kl-rb-card[b-wivlxb9fzq],
html.dark .kl-rb-preview-col .kl-rb-card[b-wivlxb9fzq],
html.dark .kl-rb-dialog[b-wivlxb9fzq],
html.dark .kl-rb-export-format[b-wivlxb9fzq],
html.dark .kl-rb-sortdir[b-wivlxb9fzq] {
    border-color: color-mix(in srgb, var(--k-border) 72%, var(--k-text-muted));
}

html[data-outdoor="true"] .kl-rb-config .kl-rb-card[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-preview-col .kl-rb-card[b-wivlxb9fzq] {
    border-width: 2px;
}

html[data-outdoor="true"] .kl-rb-col-group-title[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-step-hint[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-library-meta[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-library-empty[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-wysiwyg[b-wivlxb9fzq] {
    color: var(--k-text);
}

/* Dark: the new bordered micro-surfaces keep the same deliberate border lift the cards get. */
html.dark .kl-rb-empty-draft[b-wivlxb9fzq] {
    border-color: color-mix(in srgb, var(--k-border) 72%, var(--k-text-muted));
}

/* ---- Narrow viewport: collapse to a single column ------------------------ */
@media (max-width: 64rem) {
    .kl-rb-layout[b-wivlxb9fzq] {
        grid-template-columns: minmax(0, 1fr);
    }

    .kl-rb-config[b-wivlxb9fzq] {
        position: static;
        inset-block-start: auto;
    }

    /* W1 — single-column flow: the preview un-sticks and the card scrolls with the page again. */
    .kl-rb-preview-col[b-wivlxb9fzq] {
        position: static;
        inset-block-start: auto;
        max-block-size: none;
    }

    .kl-rb-preview-col .kl-rb-preview-card[b-wivlxb9fzq] {
        overflow-y: visible;
    }
}

/* ---- Step 5: Presentation (Wave D) ---------------------------------------- */
.kl-rb-step[data-step="5"] > label[b-wivlxb9fzq],
.kl-rb-pres-grouplabel[b-wivlxb9fzq] {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--k-text-muted);
    margin-block-start: var(--k-space-3);
}

.kl-rb-step[data-step="5"] .kf-input[b-wivlxb9fzq] {
    inline-size: 100%;
}

/* The visualization icon cards — a quiet 3-up grid; the selected card speaks the same tonal accent-wash language
   as the sort-direction segmented control (never the saturated Export teal). */
.kl-rb-vizgrid[b-wivlxb9fzq] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--k-space-2);
    margin-block-start: var(--k-space-1);
}

.kl-rb-vizcard[b-wivlxb9fzq] {
    appearance: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--k-space-1);
    padding: var(--k-space-2);
    min-block-size: var(--k-touch);
    background: transparent;
    color: var(--k-text);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease), box-shadow var(--k-dur-1) var(--k-ease);
}

.kl-rb-vizcard:hover:not(:disabled)[b-wivlxb9fzq] {
    background: var(--k-surface-2);
}

.kl-rb-vizcard[aria-pressed="true"][b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-accent) 22%, var(--k-surface));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--k-accent) 55%, var(--k-border));
    font-weight: 700;
}

.kl-rb-vizcard:disabled[b-wivlxb9fzq] {
    opacity: 0.45;
    cursor: not-allowed;
}

/* CSS-drawn mini glyphs (no icon-font dependency): each card sketches its mark with gradients/borders. */
.kl-rb-vizcard-icon[b-wivlxb9fzq] {
    inline-size: 26px;
    block-size: 18px;
    border-radius: 2px;
    background-color: transparent;
}

.kl-rb-vizcard-icon--rb-viz-table[b-wivlxb9fzq] {
    background:
        linear-gradient(to bottom, currentColor 0 2px, transparent 2px 5px) repeat-y,
        linear-gradient(to right, transparent 0 12px, currentColor 12px 13px, transparent 13px);
    background-size: 100% 5px, 100% 100%;
    opacity: 0.75;
}

.kl-rb-vizcard-icon--rb-viz-bands[b-wivlxb9fzq] {
    background: linear-gradient(
        to bottom,
        currentColor 0 4px, transparent 4px 7px,
        color-mix(in srgb, currentColor 40%, transparent) 7px 9px, transparent 9px 11px,
        currentColor 11px 15px, transparent 15px);
    opacity: 0.75;
}

.kl-rb-vizcard-icon--rb-viz-bar[b-wivlxb9fzq] {
    background:
        linear-gradient(to right, currentColor 0 100%, transparent 0) 0 0 / 100% 3px no-repeat,
        linear-gradient(to right, currentColor 0 100%, transparent 0) 0 6px / 60% 3px no-repeat,
        linear-gradient(to right, currentColor 0 100%, transparent 0) 0 12px / 80% 3px no-repeat;
    opacity: 0.75;
}

.kl-rb-vizcard-icon--rb-viz-column[b-wivlxb9fzq] {
    background:
        linear-gradient(to top, currentColor 0 60%, transparent 60%) 0 100% / 5px 100% no-repeat,
        linear-gradient(to top, currentColor 0 100%, transparent 0) 8px 100% / 5px 100% no-repeat,
        linear-gradient(to top, currentColor 0 35%, transparent 35%) 16px 100% / 5px 100% no-repeat;
    opacity: 0.75;
}

.kl-rb-vizcard-icon--rb-viz-line[b-wivlxb9fzq] {
    background: linear-gradient(135deg, transparent 44%, currentColor 44% 56%, transparent 56%);
    opacity: 0.75;
}

.kl-rb-vizcard-icon--rb-viz-pie[b-wivlxb9fzq] {
    inline-size: 18px;
    border-radius: 50%;
    background: conic-gradient(currentColor 0 65%, color-mix(in srgb, currentColor 35%, transparent) 65%);
    opacity: 0.75;
}

/* W1 — month-bands gets its OWN glyph (it borrowed nothing before): a small top-left calendar tick over three
   band rules, distinct from grouped-bands' plain stripes. */
.kl-rb-vizcard-icon--rb-viz-monthbands[b-wivlxb9fzq] {
    background:
        linear-gradient(to right, currentColor 0 7px, transparent 7px) 0 0 / 100% 3px no-repeat,
        linear-gradient(
            to bottom,
            transparent 0 5px,
            currentColor 5px 8px, transparent 8px 10px,
            color-mix(in srgb, currentColor 45%, transparent) 10px 13px, transparent 13px 15px,
            currentColor 15px 18px, transparent 18px);
    opacity: 0.75;
}

/* W1 — the muted second line on every viz card ("what you get" in plain language). */
.kl-rb-vizcard-sub[b-wivlxb9fzq] {
    font-size: 10.5px;
    font-weight: 500;
    line-height: 1.3;
    color: var(--k-text-muted);
    text-align: center;
}

/* =========================================================================================
   W1 ground-up UX redesign (report-builder-redesign-spec.md) — step-nav, collapsible steps,
   column chips + tools, filter chips, dataset guidance, quick starts. Tokens only; dark +
   outdoor + reduced-motion + coarse-pointer parity at the end of this section.
   ========================================================================================= */

/* ---- Step-nav strip (rb-stepnav): five jump pills under the intro --------- */
.kl-rb-stepnav[b-wivlxb9fzq] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin: 0 0 var(--k-space-4);
}

.kl-rb-stepnav-pill[b-wivlxb9fzq] {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    /* A6 2026-09-13 — was 2.25rem (36px); measured box 36 / hit 38 at both widths. Six pills sit in ONE wrapping
       flex row, so they are horizontal siblings like the breadcrumb row: a band with an inline minimum would
       reach over the gap onto the next pill. A block-axis box floor cannot. The strip grows 36 -> 48 at 1400x900
       and 80 -> 96 at 393x852 (it wraps to two lines there), and each pill still jumps to its OWN step. */
    min-block-size: var(--k-touch);
    padding: 0 var(--k-space-3);
    background: var(--k-surface);
    color: var(--k-text);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-full);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease), border-color var(--k-dur-1) var(--k-ease);
}

.kl-rb-stepnav-pill:hover[b-wivlxb9fzq] {
    background: var(--k-surface-2);
}

/* The pill's number/tick disc speaks the SAME done-language as the step cards' discs. */
.kl-rb-stepnav-num[b-wivlxb9fzq] {
    flex: 0 0 auto;
    inline-size: 20px;
    block-size: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--k-radius-full);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    color: var(--k-text-muted);
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.kl-rb-stepnav-num--done[b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-accent) 20%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-accent) 55%, var(--k-border));
    color: var(--k-teal-700);
}

.kl-rb-stepnav-num .ki[b-wivlxb9fzq] {
    font-size: 13px;
}

/* ---- Collapsible step cards: live summary + chevron; CSS-only body hide ---- */
/* W4 polish — the summary rides the header grid's SECOND row (see .kl-rb-step-head): full width under the
   title/hint, spanning through the chevron column, single line with an honest ellipsis. */
.kl-rb-step-summary[b-wivlxb9fzq] {
    grid-column: 2 / -1;
    grid-row: 2;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    color: var(--k-text-muted);
}

.kl-rb-step-chev[b-wivlxb9fzq] {
    appearance: none;
    flex: 0 0 auto;
    /* A6 2026-09-13 — was `align-self:center` at a fixed 28x28: box 28 / hit 28-30. The header it sits in
       (`.kl-rb-step-head`) is 64.1px tall, so this is the /dogs/{id}/edit shape again — the row was already big
       enough and the control inside it was not. Stretching the button to its own grid cell costs ZERO layout and
       the glyph stays centred by `align-items:center`. `inline-size` stays 28px so the target never widens across
       the header into the step title beside it. */
    align-self: stretch;
    inline-size: 28px;
    min-block-size: var(--k-touch);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: var(--k-radius-full);
    background: transparent;
    color: var(--k-text-muted);
    font-size: 16px;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease);
}

.kl-rb-step-chev:hover[b-wivlxb9fzq] {
    background: var(--k-surface-2);
}

/* The collapse: hide every direct child EXCEPT the header. The controls STAY IN THE DOM (display:none only) so
   every contracted data-testid/data-anchor selector keeps resolving — the zero-contract-regression rule. */
.kl-rb-step[data-open="false"] > :not(.kl-rb-step-head)[b-wivlxb9fzq] {
    display: none;
}

.kl-rb-step[data-open="false"] .kl-rb-step-head[b-wivlxb9fzq] {
    margin-block-end: 0;
}

/* Comb fix (31) — collapsed = number + title + one-line summary + chevron ONLY: the multi-line hint belongs to the
   open body's guidance, so it hides with the collapse (CSS-only; the hint stays in the DOM like every collapsed
   control). The summary is already a single ellipsized line (.kl-rb-step-summary). */
.kl-rb-step[data-open="false"] .kl-rb-step-hint[b-wivlxb9fzq] {
    display: none;
}

/* ---- Step ①: dataset guidance line -------------------------------------- */
.kl-rb-dataset-desc[b-wivlxb9fzq] {
    margin: var(--k-space-1) 0 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--k-text-muted);
}

/* ---- Step ②: ordered-column chips (rb-col-order) -------------------------- */
.kl-rb-col-order[b-wivlxb9fzq] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-1);
    margin: 0 0 var(--k-space-3);
}

.kl-rb-col-chip[b-wivlxb9fzq] {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    padding: 2px 3px;
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-full);
    font-size: 12.5px;
    color: var(--k-text);
}

.kl-rb-col-chip-label[b-wivlxb9fzq] {
    padding: 0 3px;
    max-inline-size: 11rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

.kl-rb-col-chip-btn[b-wivlxb9fzq] {
    appearance: none;
    inline-size: 24px;
    block-size: 24px;
    min-block-size: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: var(--k-radius-full);
    background: transparent;
    color: var(--k-text-muted);
    font-size: 10px;
    line-height: 1;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease), color var(--k-dur-1) var(--k-ease);
}

.kl-rb-col-chip-btn--remove[b-wivlxb9fzq] {
    font-size: 15px;
}

.kl-rb-col-chip-btn:hover:not(:disabled)[b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-text) 12%, transparent);
    color: var(--k-text);
}

.kl-rb-col-chip-btn:disabled[b-wivlxb9fzq] {
    opacity: .35;
    cursor: default;
}

/* ---- Step ②: search + bulk tools over a long column list ------------------ */
.kl-rb-col-tools[b-wivlxb9fzq] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
    margin: 0 0 var(--k-space-2);
}

.kl-rb-col-search[b-wivlxb9fzq] {
    flex: 1 1 9rem;
    min-inline-size: 0;
    min-block-size: 2.25rem;
    font-size: 13px;
}

/* Comb fix (15) — the two bulk actions are ONE wrapping unit: at rail width they drop below the search TOGETHER
   (a coherent action row), never "Select all shown" beside the search with "Clear" orphaned on its own line. */
.kl-rb-col-tool-actions[b-wivlxb9fzq] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-1);
    flex: 0 0 auto;
    margin-inline-start: auto;
}

.kl-rb-col-tool[b-wivlxb9fzq] {
    appearance: none;
    flex: 0 0 auto;
    min-block-size: 2.25rem;
    padding: 0 var(--k-space-2);
    border: 0;
    border-radius: var(--k-radius-sm, var(--k-radius-md));
    background: transparent;
    color: var(--k-teal-700);
    font: inherit;
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease);
}

.kl-rb-col-tool:hover[b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-accent) 14%, var(--k-surface));
}

/* ---- Step ③: active-filter chips ------------------------------------------ */
.kl-rb-filter-chips[b-wivlxb9fzq] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin: 0 0 var(--k-space-3);
}

.kl-rb-filter-chip[b-wivlxb9fzq] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
}

/* ---- Step ③: the one-row date range ---------------------------------------- */
.kl-rb-daterange-label[b-wivlxb9fzq] {
    font-size: 13px;
    font-weight: 600;
    color: var(--k-text-muted);
    margin-block-start: var(--k-space-2);
}

.kl-rb-daterow[b-wivlxb9fzq] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--k-space-2);
}

.kl-rb-datefield[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-inline-size: 0;
}

/* The per-input captions stay (they carry the honest grain wording + the label[for] wiring) but read small. */
.kl-rb-datefield label[b-wivlxb9fzq] {
    font-size: 11px;
    font-weight: 600;
    color: var(--k-text-muted);
}

/* ---- Quick starts (empty-draft state) --------------------------------------- */
.kl-rb-quickstarts[b-wivlxb9fzq] {
    inline-size: 100%;
    margin-block-start: var(--k-space-4);
    text-align: start;
}

.kl-rb-quickstarts-lead[b-wivlxb9fzq] {
    margin: 0 0 var(--k-space-2);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--k-text-muted);
    text-align: center;
}

.kl-rb-quickstart-grid[b-wivlxb9fzq] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: var(--k-space-2);
}

.kl-rb-quickstart[b-wivlxb9fzq] {
    appearance: none;
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-block-size: var(--k-touch);
    padding: var(--k-space-3);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    font: inherit;
    text-align: start;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease), border-color var(--k-dur-1) var(--k-ease);
}

.kl-rb-quickstart:hover[b-wivlxb9fzq] {
    background: var(--k-surface-2);
    border-color: color-mix(in srgb, var(--k-accent) 45%, var(--k-border));
}

.kl-rb-quickstart-name[b-wivlxb9fzq] {
    font-size: 13.5px;
    font-weight: 700;
    color: var(--k-text);
}

.kl-rb-quickstart-desc[b-wivlxb9fzq] {
    font-size: 12px;
    line-height: 1.4;
    color: var(--k-text-muted);
}

/* ---- W1 focus-visible: every new interactive element gets the visible ring --- */
.kl-rb-stepnav-pill:focus-visible[b-wivlxb9fzq],
.kl-rb-step-chev:focus-visible[b-wivlxb9fzq],
.kl-rb-col-chip-btn:focus-visible[b-wivlxb9fzq],
.kl-rb-col-tool:focus-visible[b-wivlxb9fzq],
.kl-rb-quickstart:focus-visible[b-wivlxb9fzq],
.kl-rb-filter-chip .kl-rb-scopechip-x:focus-visible[b-wivlxb9fzq] {
    outline: 2px solid var(--k-accent);
    outline-offset: 2px;
}

/* ---- W1 coarse-pointer touch targets: chips'/pills' buttons grow to ≥44px ---- */
@media (pointer: coarse) {
    .kl-rb-col-chip-btn[b-wivlxb9fzq],
    .kl-rb-step-chev[b-wivlxb9fzq] {
        inline-size: var(--k-touch);
        block-size: var(--k-touch);
    }

    .kl-rb-stepnav-pill[b-wivlxb9fzq],
    .kl-rb-col-tool[b-wivlxb9fzq] {
        min-block-size: var(--k-touch);
    }
}

/* ---- W1 dark parity: the new bordered micro-surfaces get the same deliberate lift the cards get ----
   W4 parity audit (live-QA polish batch): the W2 sort select + W3 schedule dialog reuse .kl-rb-select /
   .kl-rb-dialog / .kl-rb-field / .kl-rb-dialog-note, all of which already carry the sheet's dark (and outdoor)
   variants above; the W4 second-chart controls reuse .kl-rb-check-row / .kl-rb-select / .kl-rb-viz-hint (token-
   based, theme-safe). The step-nav number discs get the same dark lift here so the pills' inner border doesn't
   sink into the dark pill fill. */
html.dark .kl-rb-stepnav-pill[b-wivlxb9fzq],
html.dark .kl-rb-col-chip[b-wivlxb9fzq],
html.dark .kl-rb-quickstart[b-wivlxb9fzq] {
    border-color: color-mix(in srgb, var(--k-border) 72%, var(--k-text-muted));
}

html.dark .kl-rb-stepnav-num[b-wivlxb9fzq],
html.dark .kl-rb-step-num[b-wivlxb9fzq] {
    border-color: color-mix(in srgb, var(--k-border) 72%, var(--k-text-muted));
}

html.dark .kl-rb-stepnav-num--done[b-wivlxb9fzq] {
    color: var(--k-teal-400);
}

html.dark .kl-rb-col-tool[b-wivlxb9fzq] {
    color: var(--k-teal-400);
}

/* ---- W1 outdoor parity: guidance lines lift from muted to full text ----------
   Review fix (L6): the shared date-range group label + the chip ◀/▶/× glyphs (muted at rest) join the lift —
   outdoor sunlight readability applies to every muted control glyph, not only the captions. */
html[data-outdoor="true"] .kl-rb-dataset-desc[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-step-summary[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-vizcard-sub[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-quickstarts-lead[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-quickstart-desc[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-datefield label[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-daterange-label[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-col-chip-btn[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-scopechip-x[b-wivlxb9fzq],
html[data-outdoor="true"] .kl-rb-schedule-gate-note[b-wivlxb9fzq] {
    color: var(--k-text);
}

/* ---- W1 reduced motion: the new transitions go still too ---------------------- */
@media (prefers-reduced-motion: reduce) {
    .kl-rb-stepnav-pill[b-wivlxb9fzq],
    .kl-rb-step-chev[b-wivlxb9fzq],
    .kl-rb-col-chip-btn[b-wivlxb9fzq],
    .kl-rb-col-tool[b-wivlxb9fzq],
    .kl-rb-quickstart[b-wivlxb9fzq] {
        transition: none;
    }
}

/* =========================================================================================
   R2 — the Privacy step (⑥): the per-report redaction choice. Tokens only; dark + outdoor +
   reduced-motion + coarse-pointer parity at the end of this section. The picker list + PII
   badges reuse .kl-rb-col-list/.kl-rb-col-row/.kl-rb-badge-pii (already theme-complete).
   ========================================================================================= */

/* The plain-language state line — the card's LEAD truth, deliberately stronger than a hint. */
.kl-rb-privacy-state[b-wivlxb9fzq] {
    margin: 0 0 var(--k-space-2);
    font-size: 14px;
    font-weight: 600;
    color: var(--k-text);
}

/* The stacked master control: three full-width choice rows (long labels need the vertical
   layout), speaking the same quiet aria-pressed tonal language as .kl-rb-sortdir-btn. */
.kl-rb-redactmode[b-wivlxb9fzq] {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    overflow: hidden;
    margin-block-start: var(--k-space-1);
}

.kl-rb-redactmode-btn[b-wivlxb9fzq] {
    appearance: none;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    min-block-size: var(--k-touch);
    padding: var(--k-space-2) var(--k-space-3);
    background: transparent;
    color: var(--k-text);
    border: 0;
    border-block-end: 1px solid var(--k-border);
    text-align: left;
    font: inherit;
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease), color var(--k-dur-1) var(--k-ease);
}

.kl-rb-redactmode-btn:last-child[b-wivlxb9fzq] {
    border-block-end: 0;
}

.kl-rb-redactmode-btn:hover[b-wivlxb9fzq] {
    background: var(--k-surface-2);
}

.kl-rb-redactmode-btn:focus-visible[b-wivlxb9fzq] {
    outline: 2px solid var(--k-accent);
    outline-offset: -2px;
}

/* Selected = the SAME restrained tonal wash + inset accent ring the sort-direction control speaks
   (a privacy pick is load-bearing, but the saturated teal stays reserved for the sole Export primary). */
.kl-rb-redactmode-btn[aria-pressed="true"][b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-accent) 22%, var(--k-surface));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--k-accent) 55%, var(--k-border));
}

.kl-rb-redactmode-name[b-wivlxb9fzq] {
    font-size: 14px;
    font-weight: 700;
}

.kl-rb-redactmode-sub[b-wivlxb9fzq] {
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--k-text-muted);
}

/* The picker keeps a little air under the segmented control. */
.kl-rb-privacy-col-list[b-wivlxb9fzq] {
    margin-block-start: var(--k-space-2);
}

/* The paper's privacy chip: shape + text carry the state (never colour alone); the disclosing
   states get a warmer tint so an unredacted paper is visibly declared at a glance. */
.kl-rb-privacy-chip[b-wivlxb9fzq] {
    white-space: nowrap;
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    color: var(--k-text);
}

.kl-rb-privacy-chip[data-state="shown"][b-wivlxb9fzq],
.kl-rb-privacy-chip[data-state="unredacted"][b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-critical) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-critical) 35%, var(--k-surface));
}

/* ---- R2 dark parity: the new bordered micro-surfaces get the same deliberate lift ---- */
html.dark .kl-rb-redactmode[b-wivlxb9fzq],
html.dark .kl-rb-redactmode-btn[b-wivlxb9fzq],
html.dark .kl-rb-privacy-chip[b-wivlxb9fzq] {
    border-color: color-mix(in srgb, var(--k-border) 72%, var(--k-text-muted));
}

html.dark .kl-rb-privacy-chip[data-state="shown"][b-wivlxb9fzq],
html.dark .kl-rb-privacy-chip[data-state="unredacted"][b-wivlxb9fzq] {
    background: color-mix(in srgb, var(--k-critical) 30%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-critical) 55%, var(--k-surface));
}

/* ---- R2 outdoor parity: the muted sub-lines lift to full text (sunlight readability) ---- */
html[data-outdoor="true"] .kl-rb-redactmode-sub[b-wivlxb9fzq] {
    color: var(--k-text);
}

/* ---- R2 reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
    .kl-rb-redactmode-btn[b-wivlxb9fzq] {
        transition: none;
    }
}

/* ---- R2 coarse-pointer: the choice rows already meet var(--k-touch); nothing shrinks below it ---- */
@media (pointer: coarse) {
    .kl-rb-redactmode-btn[b-wivlxb9fzq] {
        min-block-size: var(--k-touch);
    }
}

/* ── OWNER RULING 2026-09-16 (D75 #9) — the printed builder is the SHEET document, never the six steps ─────────────
   Print preview hides the workspace on screen and unparks the sheets (ReportBuilder.razor, .kl-rb-print). On paper
   the page heading and the workspace are hidden whenever a sheet document exists, and the sheets print in their
   place. A heading left above the first sheet would push that sheet past the foot of the paper and add a page. */
.kl-rb-workspace[data-print-preview="open"][b-wivlxb9fzq] {
    display: none;
}

.kl-rb-printbar[b-wivlxb9fzq] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin-block-end: var(--k-space-4);
}

.kl-rb-printopen[b-wivlxb9fzq] {
    margin-block-start: var(--k-space-2);
}

@media print {
    h1[data-print-twin="true"][b-wivlxb9fzq],
    .kl-rb-workspace[data-print-twin="true"][b-wivlxb9fzq] {
        display: none;
    }

    .kl-rb-print[b-wivlxb9fzq] {
        margin: 0;
        padding: 0;
    }
}
/* _content/Kanine.Web/Components/Pages/Reports.razor.rz.scp.css */
/* UI-GUAR-003 / RPT-* — Reports landing (reports.html), page-major R11 (restrained-premium). Consumes the global
   foundation vocabulary (kf-input/-label/-select/-field, kl-btn + variants, kl-chip variants, kl-count, kl-data-table,
   kl-dialog/-dialog-actions, kl-visually-hidden) from kanine-design-system.css; this scoped sheet adds ONLY the
   triple-pane shell (catalog sidebar · workspace · docked generate bar), the catalog list, the report-preview cards,
   and the picker / step-up dialog surfaces. Every colour is a --k-* token (via color-mix where a tint is needed) — no
   raw fills, no gradients, no off-token colour — so the R11 token/canvas teeth hold across light/dark/outdoor. */

.kl-reports[b-56l51hopg1] {
    display: grid;
    grid-template-columns: 20rem minmax(0, 1fr);
    gap: var(--k-space-6);
    align-items: start;
}

/* OWNER RULING 2026-08-10 — ONE COLUMN. The reports region no longer spends a 20rem column on the catalog while
   a court artifact is being checked in what is left. Measured on the live host at 1400x900 before this change:
   the preview pane was 588px and the default Formal K-9 Record's table 911px, so six of its eleven columns were
   visible, Alert was cut mid-column, and Indication / Successful / Apprehensions / Finds were off the edge with
   nothing on screen saying they existed. The catalog is not deleted — it is rendered on demand into THIS SAME
   GRID CELL (see #report-catalog-panel) so it floats over the workspace and costs the artifact nothing.

   ⚠ EVERY RULE OF THE NEW LAYOUT IS GATED ON [data-catalog], WHICH ONLY THE NEW MARKUP EMITS, and that is not
   defensive habit — it is a state this host produced today. A stylesheet hot-reloads on its own; a Razor delta
   can be blocked behind an unrelated file's compile error, or need a restart. In the gap the sheet is live and
   the markup is not, and the owner is looking at the page. Ungated, that gap paints the catalog permanently over
   the artifact — worse than the defect. Gated, the old markup renders EXACTLY today's two-column layout. */
.kl-reports[data-catalog][b-56l51hopg1] {
    grid-template-columns: minmax(0, 1fr);
}

/* ---- Pane 1 — catalog sidebar (FLOATS; rendered only while open) --------- */
.kl-reports-catalog[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-4);
    position: sticky;
    inset-block-start: var(--k-space-4);
    max-block-size: calc(100vh - 8rem);
    overflow: hidden;
}

/* THE OVERLAY. Keyed on the PANEL'S ID, which only the new markup emits (see the note on .kl-reports[data-catalog]).
   grid-area 1/1 on both children is what makes this an overlay rather than a column: the panel and the workspace
   occupy the same cell, the panel is start-aligned at its own 20rem and painted above. It keeps `position:
   sticky` from the rule above — its containing block is the shared grid area, which is as tall as the workspace,
   so the panel follows a reader who scrolls a long preview instead of scrolling off the top. */
#report-catalog-panel[b-56l51hopg1] {
    grid-area: 1 / 1;
    justify-self: start;
    inline-size: min(20rem, 100%);
    z-index: 20;
    /* Elevated one step over the docked generate bar (--k-elev-2): it is floating over content, and a panel that
       overlaps a document at the same elevation as the document reads as part of it. */
    box-shadow: var(--k-elev-3);
}

.kl-reports-catalog-head[b-56l51hopg1] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-2);
}

.kl-reports-catalog-heading[b-56l51hopg1] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 15px;
    color: var(--k-text);
}

.kl-reports-catalog-close[b-56l51hopg1] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2rem;
    block-size: 2rem;
    flex: none;
    padding: 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--k-radius-full);
    color: var(--k-text-muted);
    cursor: pointer;
    line-height: 1;
}

.kl-reports-catalog-close:hover[b-56l51hopg1] {
    background: var(--k-surface-2);
    color: var(--k-text);
}

.kl-reports-catalog-search[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    padding-block-end: var(--k-space-3);
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
}

.kl-reports-catalog-count[b-56l51hopg1] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 0;
    font-size: 12px;
    color: var(--k-text-muted);
}

.kl-reports-catalog-list[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-6);
    overflow-y: auto;
    padding-inline-end: var(--k-space-1);
}

.kl-reports-catalog-group[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}

.kl-reports-catalog-group-title[b-56l51hopg1] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--k-text-muted);
}

.kl-reports-catalog-items[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.kl-reports-catalog-item[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: 1px;
    text-align: start;
    padding: var(--k-space-2) var(--k-space-3);
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--k-radius-md);
    color: var(--k-text);
    cursor: pointer;
    transition: background var(--k-dur-1) var(--k-ease);
}

.kl-reports-catalog-item:hover[b-56l51hopg1] {
    background: var(--k-surface-2);
}

.kl-reports-catalog-item.is-active[b-56l51hopg1] {
    background: color-mix(in srgb, var(--k-teal-500) 14%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-teal-500) 30%, transparent);
    color: var(--k-teal-700);
    font-weight: 600;
}

.kl-reports-catalog-item-label[b-56l51hopg1] {
    line-height: 1.2;
}

.kl-reports-catalog-item-legacy[b-56l51hopg1] {
    font-family: var(--k-font-mono);
    font-size: 11px;
    color: var(--k-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kl-reports-catalog-empty[b-56l51hopg1] {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    color: var(--k-text-muted);
    padding: var(--k-space-8) var(--k-space-4);
}

/* ---- Pane 2 — workspace -------------------------------------------------- */
.kl-reports-workspace[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-6);
    min-inline-size: 0;
}

/* The other half of the overlay, under the same [data-catalog] guard and for the same reason. */
.kl-reports[data-catalog] .kl-reports-workspace[b-56l51hopg1] {
    grid-area: 1 / 1;
}

.kl-reports-workspace-head[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
}

/* The catalog opener and the report title share a row (§ related things share a row) — and it is a row rather
   than a rail because a rail costs the artifact 72px it does not have: at 1400 the reclaimed measure is 344px,
   a 3rem strip plus its gap gives 72 of that back, and the report the ruling was written about needs all of it. */
.kl-reports-titlerow[b-56l51hopg1] {
    display: flex;
    align-items: center;
    gap: var(--k-space-3);
    flex-wrap: wrap;
}

/* OWNER RULING 2026-08-10 — "make the choose report part very primary and very prominent instead just a little
   grey label". The variant change to kl-btn--primary is the substance; this is the prominence. It is sized up
   from the foundation button (15px/600 over a taller box) because it sits on a title row next to a 24px display
   heading, where a default-height button reads as a chip beside the title rather than as the page's way in.
   The count rides INSIDE it as a contrast pill rather than as a separate muted span, so "40 reports" is part of
   the invitation instead of a grey number floating next to it. */
.kl-reports-catalogtoggle[b-56l51hopg1] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    flex: none;
    font-size: 15px;
    font-weight: 600;
    padding-block: var(--k-space-3);
    padding-inline: var(--k-space-5);
    box-shadow: var(--k-elev-1);
}

.kl-reports-catalogtoggle .ki[b-56l51hopg1] {
    font-size: 18px;
}

/* The count pill: legible ON the filled primary, so it inherits the button's foreground rather than the muted
   page token .kl-count carries (which would be near-invisible on a filled accent fill). */
.kl-reports-catalogtoggle .kl-count[b-56l51hopg1] {
    background: color-mix(in srgb, var(--k-header-text) 22%, transparent);
    color: inherit;
    border-radius: var(--k-radius-full);
    padding-inline: var(--k-space-2);
    font-variant-numeric: tabular-nums;
}

.kl-reports-title[b-56l51hopg1] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 24px;
    color: var(--k-text);
}

/* Iconned headers law (A.1): the workspace title + card heads lead with a ki glyph. */
.kl-reports-title-icon[b-56l51hopg1] {
    font-size: 20px;
    color: var(--k-accent);
    margin-inline-end: var(--k-space-1);
}

/* Only the COLOUR is this page's. §5a sizes a card head's leading glyph at 0.92em and gives it the product's
   8px gutter; the 14px and the 4px that stood here were this page reading a size and a gutter of its own. */
.kl-reports-card-icon[b-56l51hopg1] {
    color: var(--k-accent);
}

/* Span-filter pair: from + to date inputs on one row. */
.kl-reports-daterange[b-56l51hopg1] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-reports-daterange .kf-input[b-56l51hopg1] {
    min-inline-size: 0;
    flex: 1 1 0;
}

.kl-reports-daterange-sep[b-56l51hopg1] {
    color: var(--k-text-muted);
    flex: none;
}

.kl-reports-legacy-id[b-56l51hopg1] {
    font-family: var(--k-font-mono);
    font-size: 14px;
    color: var(--k-text-muted);
    vertical-align: middle;
}

.kl-reports-purpose[b-56l51hopg1] {
    margin: 0;
    color: var(--k-text-muted);
    font-size: 14px;
}

.kl-reports-filters[b-56l51hopg1] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    align-items: center;
}

.kl-reports-chip[b-56l51hopg1] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-reports-chip-x[b-56l51hopg1] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.25rem;
    block-size: 1.25rem;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: var(--k-radius-full);
    font-size: 11px;
    color: inherit;
    cursor: pointer;
    line-height: 1;
}

.kl-reports-chip-x:hover[b-56l51hopg1] {
    background: color-mix(in srgb, var(--k-text) 12%, transparent);
}

/* .kl-reports-emptytoggle — REMOVED with the retired "Preview zero-result state" control. */

/* Formal/court gating notice. Uses the flipping --k-text foreground on a caution-tinted
   --k-surface mix so it stays legible (>=4.5:1) in light / dark / outdoor — it must NOT
   borrow the kl-btn--seal button variant (fixed white-on-ink fg that washed out on the
   light/outdoor canvas: the UI-GUAR-030 re-shoot contrast finding). */
.kl-reports-banner[b-56l51hopg1] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-2);
    padding: var(--k-space-3) var(--k-space-4);
    border-radius: var(--k-radius-md);
    font-size: 14px;
    color: var(--k-text);
    background: color-mix(in srgb, var(--k-caution) 14%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-caution) 45%, var(--k-border));
    border-left: 3px solid var(--k-caution);
}

/* ---- Workspace cards ----------------------------------------------------- */
.kl-reports-card[b-56l51hopg1] {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    overflow: hidden;
}

.kl-reports-card-head[b-56l51hopg1] {
    inline-size: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--k-space-4);
    background: transparent;
    border: 0;
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
    cursor: pointer;
    color: var(--k-text);
}

.kl-reports-card-title[b-56l51hopg1] {
    font-weight: 600;
}

.kl-reports-card-body[b-56l51hopg1] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--k-space-6);
    padding: var(--k-space-6);
}

.kl-reports-field-wide[b-56l51hopg1] {
    grid-column: 1 / -1;
}

.kl-reports-types[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    margin: 0;
    padding: 0;
    border: 0;
}

/* The LABEL is the hit target for these checkboxes (the input itself is a ~13px box), so the label is what has to
   satisfy A6's 44px minimum. Measured at 320/375/393/430 before this rule: every one of them was 21px tall.

   It is one rule rather than three, because the two record-type checkboxes that were already here were the same
   21px. Sizing only the new Record Status controls would have left two neighbours in the same fieldset below the
   minimum and made the fieldset look like two different kinds of control. */
.kl-reports-check[b-56l51hopg1] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    min-block-size: 44px;
    font-size: 14px;
    color: var(--k-text);
    cursor: pointer;
}

.kl-reports-pickbtn[b-56l51hopg1] {
    inline-size: 100%;
    justify-content: center;
}

.kl-reports-pick-summary[b-56l51hopg1] {
    margin: var(--k-space-2) 0 0;
    font-size: 12px;
    color: var(--k-text-muted);
}

/* ---- Report preview ------------------------------------------------------ */
.kl-reports-preview[b-56l51hopg1] {
    padding: 0;
}

.kl-reports-preview-head[b-56l51hopg1] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-4);
    padding: var(--k-space-6);
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
    text-align: center;
}

.kl-reports-preview-head-mid[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--k-space-1);
}

.kl-reports-preview-org[b-56l51hopg1] {
    margin: 0;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--k-text);
}

.kl-reports-preview-name[b-56l51hopg1] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 18px;
    color: var(--k-text);
}

.kl-reports-pagechip[b-56l51hopg1] {
    font-family: var(--k-font-mono);
    font-size: 12px;
}

.kl-reports-page-btn[b-56l51hopg1] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.5rem;
    block-size: 2.5rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--k-radius-full);
    color: var(--k-text-muted);
    cursor: pointer;
    font-size: 18px;
}

.kl-reports-page-btn:hover:not(:disabled)[b-56l51hopg1] {
    background: var(--k-surface-2);
    color: var(--k-teal-700);
}

.kl-reports-page-btn:disabled[b-56l51hopg1] {
    opacity: .4;
    cursor: not-allowed;
}

.kl-reports-preview-body[b-56l51hopg1] {
    padding: var(--k-space-6);
    overflow-x: auto;
    /* The pane scrolls sideways when the sheet is wider than it is (measured: 666px hidden at 393px with
       no cue at all). It carries the shared scroll cue (section 8b-s) in its MASK form, not the shadow
       form: the pane holds an opaque paper document that would paint over any background the container
       draws. The inline end padding is the fade depth, so at full scroll the fade lands on empty space
       rather than dimming the edge of the sheet. */
    padding-inline-end: 32px;
}

/* ⚠ GIVING THE PANE THE WHOLE PAGE IS ONLY HALF OF IT — and the missing half is why the first attempt at this
   ruling would have measured as "no change". The shared document component caps its paper at
   `max-inline-size: 800px` (1080px landscape) so it reads as PAPER. That cap does not move with the pane, so
   widening the pane from 588px to 1044px widened the WHITESPACE either side of an 800px sheet and left the
   911px table cut inside it exactly as before — 734px of usable width against 911px of table.

   Here the sheet takes the width its own content needs and the CARD becomes the scroller:
     • inline-size: fit-content  — the sheet grows to its table's max-content (headers are `nowrap`), so the
       nested scroller inside the sheet stops being the thing that hides columns;
     • min-inline-size          — never NARROWER than the cap it had, so a two-column analysis report still
       renders as a sheet rather than shrink-wrapping to a stub;
     • max-inline-size: none    — beats the component's cap (this selector carries the page's scope attribute,
       so it also out-specifies it).
   The consequence is deliberate: when the artifact beats the measure, the whole document scrolls inside the
   card and its right edge visibly runs off — one scroller the reader can see, not a nested one they cannot. */
.kl-reports[data-catalog] .kl-reports-preview-body[b-56l51hopg1]  .kl-repdoc {
    /* ⚠ box-sizing is LOAD-BEARING and was measured wrong once. Without it `min-inline-size: min(100%, 1080px)`
       resolves 100% against the CONTENT box, so a landscape sheet came out at 1080/998 CONTENT plus its own 66px
       of padding and border and overflowed the pane by exactly 66px — on EVERY landscape report, including
       two-column ones with nothing to hide. It read as a one-column cut on twenty-one of thirty-five reports. */
    box-sizing: border-box;
    inline-size: fit-content;
    min-inline-size: min(100%, 800px);
    max-inline-size: none;
}

.kl-reports[data-catalog] .kl-reports-preview-body[b-56l51hopg1]  .kl-repdoc.is-landscape {
    min-inline-size: min(100%, 1080px);
}

/* THE CUT SIGNAL (kanine-widetable.js writes the sentence; this only dresses it). Quiet rather than alarming:
   a scrollable artifact is not an error, it is a fact the reader has to know before they sign. It sits OUTSIDE
   the scroller on purpose — a notice that scrolls away with the thing it is describing is not a notice. */
.kl-reports-cutnote[b-56l51hopg1] {
    margin: 0;
    padding: var(--k-space-2) var(--k-space-6) var(--k-space-3);
    border-block-start: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
    background: var(--k-surface-2);
    color: var(--k-text-muted);
    font-size: 13px;
}

.kl-reports-cutnote[hidden][b-56l51hopg1] {
    display: none;
}

.kl-reports-empty-body[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--k-space-2);
    padding: var(--k-space-8) var(--k-space-6);
    text-align: center;
    color: var(--k-text-muted);
}

.kl-reports-empty-title[b-56l51hopg1] {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--k-text);
}

/* ---- Companion CTAs + aid drill-in --------------------------------------- */
.kl-reports-ctas[b-56l51hopg1] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--k-space-3);
}

.kl-reports-cta[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
    padding: var(--k-space-4) var(--k-space-6);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    text-decoration: none;
    color: var(--k-text);
    transition: background var(--k-dur-1) var(--k-ease);
}

.kl-reports-cta:hover[b-56l51hopg1] {
    background: var(--k-surface-2);
}

.kl-reports-cta-title[b-56l51hopg1] {
    font-weight: 600;
    font-size: 15px;
}

.kl-reports-cta-sub[b-56l51hopg1] {
    font-size: 13px;
    color: var(--k-text-muted);
}

.kl-reports-aidlink-row[b-56l51hopg1] {
    display: flex;
}

.kl-reports-aidlink[b-56l51hopg1] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    color: var(--k-teal-700);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
}

.kl-reports-aidlink:hover[b-56l51hopg1] {
    color: var(--k-teal-500);
    text-decoration: underline;
}

/* ---- Pane 3 — docked generate bar ---------------------------------------- */
.kl-reports-generatebar[b-56l51hopg1] {
    position: sticky;
    inset-block-end: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-4);
    padding: var(--k-space-4);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-2);
    z-index: 10;
}

.kl-reports-formats[b-56l51hopg1] {
    display: inline-flex;
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    overflow: hidden;
}

/* UI-GUAR-036: the format buttons are touch targets. Padding alone made them 31px tall at every phone width
   (measured 60-69 x 31 on /reports). The floor is the shared --k-touch token. */
.kl-reports-format[b-56l51hopg1] {
    min-block-size: var(--k-touch);
    padding: var(--k-space-2) var(--k-space-4);
    background: var(--k-surface);
    border: 0;
    border-inline-end: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
    color: var(--k-text-muted);
    font-weight: 600;
    cursor: pointer;
}

.kl-reports-format:last-child[b-56l51hopg1] {
    border-inline-end: 0;
}

.kl-reports-format.is-active[b-56l51hopg1] {
    background: var(--k-header-bg);
    color: var(--k-header-text);
}

/* The bottom margin is zeroed DELIBERATELY, and it is the whole fix for a visible misalignment (owner review
   2026-07-28: "the pdf,xlsx,csv,json component and 'Internal (no redaction)' component and the Generate report
   button are not vertically aligned/centered with each other").
   .kf-field is a FORM-COLUMN primitive — it carries `margin-block-end: var(--k-space-4)` so stacked fields space
   themselves. Here it is a flex ITEM in a bar that centres its children, and `align-items: center` centres the
   MARGIN box, not the border box. A 16px bottom margin therefore lifts the select ~8px above the format buttons
   and the generate button, which is exactly the offset the film shows. Setting the margin to 0 is what makes the
   three controls share one centre line; changing align-items would not, because the margin would still be there. */
.kl-reports-redaction[b-56l51hopg1] {
    flex: 1 1 auto;
    min-inline-size: 12rem;
    max-inline-size: 18rem;
    margin-block-end: 0;
}

.kl-reports-generate[b-56l51hopg1] {
    flex: 0 0 auto;
}

/* ---- Dialogs (picker + step-up) ------------------------------------------- */
/* UI-GUAR-033: overlay/scrim retired — <KlOverlay> now supplies the fixed scrim + centering. This only sizes the
   card, lays out its head/body, and carries its surface/elevation. */
.kl-reports-dialog[b-56l51hopg1] {
    inline-size: min(44rem, calc(100vw - 2rem));
    max-block-size: calc(100vh - 4rem);
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    padding: var(--k-space-6);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-3);
    overflow-y: auto;
}

.kl-reports-dialog-head[b-56l51hopg1] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-reports-dialog-head h2[b-56l51hopg1] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 18px;
    color: var(--k-text);
}

.kl-reports-dialog-body[b-56l51hopg1] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    font-size: 14px;
    color: var(--k-text);
}

.kl-reports-dialog-actions[b-56l51hopg1] {
    margin-block-start: var(--k-space-2);
}

.kl-reports-pickall[b-56l51hopg1] {
    font-weight: 500;
}

.kl-reports-pick-list[b-56l51hopg1] {
    list-style: none;
    margin: 0;
    padding: 0;
    max-block-size: 18rem;
    overflow-y: auto;
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
}

.kl-reports-pick-row[b-56l51hopg1] {
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 50%, transparent);
}

.kl-reports-pick-row:last-child[b-56l51hopg1] {
    border-block-end: 0;
}

.kl-reports-pick-row .kl-reports-check[b-56l51hopg1] {
    inline-size: 100%;
    padding: var(--k-space-3);
}

.kl-reports-pick-id[b-56l51hopg1] {
    font-family: var(--k-font-mono);
    font-size: 13px;
    color: var(--k-teal-700);
}

.kl-reports-pick-meta[b-56l51hopg1] {
    font-size: 12px;
    color: var(--k-text-muted);
}

.kl-reports-pick-empty[b-56l51hopg1] {
    text-align: center;
    color: var(--k-text-muted);
    font-size: 13px;
    padding: var(--k-space-4) 0;
}

/* ---- Deliberate dark + outdoor (R11 punch-list) -------------------------- */
html.dark .kl-reports-catalog[b-56l51hopg1],
html.dark .kl-reports-card[b-56l51hopg1],
html.dark .kl-reports-generatebar[b-56l51hopg1],
html.dark .kl-reports-dialog[b-56l51hopg1] {
    border-color: color-mix(in srgb, var(--k-border) 72%, var(--k-text-muted));
}

html[data-outdoor="true"] .kl-reports-catalog[b-56l51hopg1],
html[data-outdoor="true"] .kl-reports-card[b-56l51hopg1],
html[data-outdoor="true"] .kl-reports-generatebar[b-56l51hopg1] {
    border-width: 2px;
}

html[data-outdoor="true"] .kl-reports-title[b-56l51hopg1],
html[data-outdoor="true"] .kl-reports-preview-name[b-56l51hopg1] {
    font-weight: 800;
}

/* ---- Narrow viewport ------------------------------------------------------
   The shell is one column at EVERY width now, so there is no second collapse to do here and the old
   `grid-template-columns: minmax(0,1fr)` override has nothing left to override.

   What changes below 64rem is the panel's measure, not its behaviour. It stays FLOATING and STICKY: the old
   `position: static` would drop it back into flow inside the grid cell it shares with the workspace, which is
   how a phone reader used to have to scroll past all forty catalog entries to reach the artifact. Now the
   catalog is closed by default here too, and opening it lays a full-measure sheet over the workspace that
   scrolls inside its own max-block-size. That is a strict improvement at 393px, not a second collapse. */
@media (max-width: 64rem) {
    /* The pre-[data-catalog] fallback keeps its old narrow-width collapse verbatim. */
    .kl-reports:not([data-catalog])[b-56l51hopg1] {
        grid-template-columns: minmax(0, 1fr);
    }

    .kl-reports:not([data-catalog]) .kl-reports-catalog[b-56l51hopg1] {
        position: static;
        max-block-size: none;
    }

    /* The panel carries its own padding and border. On the default content-box, 100% plus 34px ran past the
       viewport and cut the last word of the count line. border-box makes 100% include them. */
    #report-catalog-panel[b-56l51hopg1] {
        inline-size: 100%;
        box-sizing: border-box;
    }

    .kl-reports-card-body[b-56l51hopg1],
    .kl-reports-ctas[b-56l51hopg1] {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ---- SEC-SIG-001 step-up: the inline server-verified rejection ----------- */
.kl-reports-stepup-error[b-56l51hopg1] {
    margin-block: 0.5rem 0;
    padding: 0.5rem 0.75rem;
    border: 1px solid #b3261e;
    border-radius: 0.375rem;
    color: #b3261e;
    background: color-mix(in srgb, #b3261e 8%, transparent);
    font-size: 0.875rem;
}

/* ---- Print: the page owns the print counterpart of its own screen scroller ----
   THE SCREEN RULING ABOVE IS RIGHT, AND IT IS A SCREEN RULING. The card is deliberately the scroller
   and the sheet deliberately takes its content width (`inline-size: fit-content`, `max-inline-size:
   none`), so a wide artifact runs off one visible edge instead of hiding columns in a nested box. A
   reader can drag it. Paper cannot be dragged, so on paper the same pair silently deletes whatever
   falls past the sheet edge: measured 2026-09-15 at the Letter content width, a 1033px document in a
   718px box, three of eleven columns gone and nothing on the page to say so.

   On paper the document therefore takes the sheet's width instead of its content's width. The shared
   document component wraps its header cells under print for this exact case, so all eleven columns
   are on the sheet rather than seven and a half. The pane's own scroll padding goes too: the 32px
   inline-end gutter exists to give the screen's fade somewhere to land, and the shared print block
   removes that fade.

   The nested `::deep` selectors carry this page's scope attribute, which is what lets them out-specify
   the component's own cap the same way their screen counterparts do. */
@media print {
    .kl-reports-preview-body[b-56l51hopg1] {
        overflow: visible;
        padding-inline-end: var(--k-space-6);
    }

    .kl-reports[data-catalog] .kl-reports-preview-body[b-56l51hopg1]  .kl-repdoc,
    .kl-reports[data-catalog] .kl-reports-preview-body[b-56l51hopg1]  .kl-repdoc.is-landscape {
        inline-size: 100%;
        min-inline-size: 0;
        max-inline-size: 100%;
    }

    /* A card that hides its overflow cannot let a long document flow onto the next sheet. */
    .kl-reports-preview[b-56l51hopg1] {
        overflow: visible;
    }
}

/* ── OWNER RULING 2026-09-16 (D75 #9) — the printed report is the SHEET document, never the workspace ─────────────
   Print preview hides the workspace on screen and unparks the sheets (Reports.razor, .kl-reports-print). The class is
   doubled so the rule outranks the gated `.kl-reports[data-catalog]` layout rules on specificity rather than on file
   order. No importance flag. */
.kl-reports.kl-reports[data-print-preview="open"][b-56l51hopg1] {
    display: none;
}

/* `-printbar`, not `-actions` or `-toolbar-row`: `[class$="-actions"]` and `[class$="-row"]` are foundation suffix
   families. Static and in flow, above the first sheet. */
.kl-reports-printbar[b-56l51hopg1] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin-block-end: var(--k-space-4);
}

.kl-reports-printopen[b-56l51hopg1] {
    margin-block-start: var(--k-space-1);
}

@media print {
    /* PAPER CARRIES THE REPORT, NOT THE CONTROLS THAT CHOSE IT. The catalog, the parameter controls, the preview window
       and the generate bar are hidden, and the sheet document prints in their place. Its identity head states the
       report and the parameters on every sheet, so nothing the workspace said about the report is lost. Gated on the
       sheets EXISTING: with no report, a refused one or an empty one there is no sheet document, and the workspace's
       own honest state is what prints. */
    .kl-reports.kl-reports[data-print-twin="true"][b-56l51hopg1] {
        display: none;
    }

    .kl-reports-print[b-56l51hopg1] {
        margin: 0;
        padding: 0;
    }
}

/* ── OWNER RULING 2026-10-10 Q13 (ruling C5) — a browser print of /reports prints no report data ─────────────────────
   The Print button gives the recorded server PDF. A browser print (Ctrl+P) skips that button and writes no row, so
   on paper this page shows one line only: "Use the Print button so that the print is recorded." The workspace, the
   preview, the sheet document and the dialogs are hidden on paper. The line is hidden on screen. */
.kl-reports-print-recorded[b-56l51hopg1] {
    display: none;
}

.kl-reports-print-refusal[b-56l51hopg1] {
    margin-block: 0 var(--k-space-4);
    color: #b3261e;
}

@media print {
    .kl-reports.kl-reports[b-56l51hopg1],
    .kl-reports.kl-reports[data-print-twin="true"][b-56l51hopg1],
    .kl-reports-print.kl-reports-print[b-56l51hopg1],
    .kl-reports-dialog.kl-reports-dialog[b-56l51hopg1] {
        display: none;
    }

    .kl-reports-print-recorded.kl-reports-print-recorded[b-56l51hopg1] {
        display: block;
        margin: 0;
        font-size: 1rem;
    }
}
/* _content/Kanine.Web/Components/Pages/ScheduledReports.razor.rz.scp.css */
/* RPT-024 — Scheduled reports (scheduled-reports.html), page-major R11 (restrained-premium). Consumes the global
   cross-cutting vocabulary (kl-page, kl-section-head, kl-count, kl-head-actions, kl-banner, kl-chip, kl-btn,
   kl-field, kl-input, kl-readonly-note) from kanine-design-system.css; this scoped sheet adds ONLY the definitions
   TABLE rhythm, the per-row overflow MENU, the create SHEET, and the degraded-delivery affordance. Every colour is a
   --k-* token via color-mix (no raw fills, no gradients) so the R11 token/canvas teeth hold. */

.kl-scheduled-reports[b-4h3aevwg1p] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-6);
}

/* The email-degrade banner now carries a route (owner ruling 2026-09-09), so its message and its action are two
   flex items rather than one run of text. The message takes the elastic share and the action keeps its own size;
   `min-inline-size: 0` is what lets the message shrink instead of forcing the banner wider than the card at 320px
   (the shared `.kl-banner` is a flex row, and a flex item's default min-width is auto). The "who can change it"
   sentence is a BLOCK inside the message so it reads as its own line without becoming a third flex item. */
.kl-sr-degrade-text[b-4h3aevwg1p] {
    flex: 1 1 18rem;
    min-inline-size: 0;
}

.kl-sr-degrade-who[b-4h3aevwg1p] {
    display: block;
    margin-block-start: var(--k-space-1);
}

.kl-sr-section[b-4h3aevwg1p] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
}

/* ---- Page head (title + last-evaluated stamp + primary action) ----------- */
.kl-sr-pagehead[b-4h3aevwg1p] {
    align-items: flex-start;
    gap: var(--k-space-4);
}

.kl-sr-pagehead-text[b-4h3aevwg1p] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
}

/* The primary action(s) — icon + label, ≥48px touch target (kit), flat teal fill (no gradient). */
.kl-sr-new[b-4h3aevwg1p] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    min-block-size: 2.75rem;
}

.kl-sr-new .ki[b-4h3aevwg1p] {
    font-size: 20px;
}

/* ---- Sub-section heads (icon + label) ------------------------------------ */
.kl-sr-subhead h2[b-4h3aevwg1p] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
}

.kl-sr-subhead-icon[b-4h3aevwg1p] {
    font-size: 20px;
    color: var(--k-teal-700);
}

/* ---- Owner cell ---------------------------------------------------------- */
.kl-sr-owner[b-4h3aevwg1p] {
    color: var(--k-text);
}

.kl-sr-sr-only[b-4h3aevwg1p] {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ---- Definitions table ----------------------------------------------------
   Base skin now comes from the canonical .kl-tablewrap > .kl-data-table pair
   (card wrapper + internal h-scroll + sticky uppercase thead); the kl-sr-*
   rules below stay as the page's ADDITIVE skin only. */
.kl-sr-row > td[b-4h3aevwg1p] {
    padding: var(--k-space-3) var(--k-space-4);
    border-block-end: 1px solid color-mix(in srgb, var(--k-border) 60%, transparent);
    vertical-align: top;
    font-size: 14px;
    color: var(--k-text);
}

.kl-sr-row[b-4h3aevwg1p] {
    transition: background var(--k-dur-1) var(--k-ease);
}

.kl-sr-row:hover[b-4h3aevwg1p] {
    background: var(--k-surface-2);
}

/* A SUSPENDED row reads as an attention state (owner lost scope) — a faint critical wash + a left rule, never
   colour alone (the Status chip carries the word). */
.kl-sr-row[data-status="SUSPENDED"] > td:first-child[b-4h3aevwg1p] {
    box-shadow: inset 3px 0 0 0 color-mix(in srgb, var(--k-critical) 55%, transparent);
}

.kl-sr-row[data-status="SUSPENDED"]:hover[b-4h3aevwg1p] {
    background: color-mix(in srgb, var(--k-critical) 7%, var(--k-surface));
}

.kl-sr-report-title[b-4h3aevwg1p] {
    font-weight: 600;
    color: var(--k-text);
}

.kl-sr-report-id[b-4h3aevwg1p],
.kl-sr-row td[data-testid="row-formats"][b-4h3aevwg1p],
.kl-sr-row td[data-testid="row-next-run"][b-4h3aevwg1p] {
    font-family: var(--k-font-mono);
    font-size: 12px;
    color: var(--k-text-muted);
    font-variant-numeric: tabular-nums;
}

/* The backing-report reference is ONE quiet line, never a three-line uuid wall: a long reference ellipsizes
   (the full value rides the title tooltip + data-report-ref), so the REPORT column can no longer force the
   table wide enough to shove the row kebab behind the wrapper's horizontal scrollbar. */
.kl-sr-report-id[b-4h3aevwg1p] {
    max-inline-size: 26ch;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* THE ACTIONS CELL IS NOT PINNED, and the deletion is the fix rather than the regression.

   It used to be `position: sticky; inset-inline-end: 0` carrying an opaque row background, so the row kebab
   stayed reachable when this nine-column table overflowed the .kl-tablewrap h-scroll. MEASURED on the 1600x900
   desktop profile while filming A18: the table is 1143px of content in a 972px wrapper, the actions column
   absorbs 202px of surplus width beside its 32px button, and the pinned cell therefore painted an opaque 235px
   box straight across the STATUS and NEXT RUN columns — the two columns a scheduled-reports table exists to
   show — at scroll position zero, with nothing on screen to say anything was underneath it. Every content
   assertion passed the whole time; only a frame showed it.

   Unpinned, both columns are legible at this width AND the kebab still is, because it sits at the LEFT edge of
   its own wide column. On a genuinely narrow window the kebab now scrolls with its row, which is how every
   other wide table in this product behaves and is exactly what the wrapper's h-scroll is for. `relative` is
   kept so the open-menu z-index rule below still has a positioned box to raise. */
.kl-sr-row > td:last-child[b-4h3aevwg1p] {
    position: relative;
}

/* A row whose overflow menu is OPEN floats its sticky actions cell above the sibling rows' sticky cells, so the
   dropdown never paints beneath a later row's pinned cell. */
.kl-sr-row > td:last-child:has(.kl-sr-menu-list)[b-4h3aevwg1p] {
    z-index: 60;
}

/* ---- Per-row overflow menu -----------------------------------------------
   THE WRAPPER IS NO LONGER CALLED `kl-sr-menu`, AND THE RENAME IS THE FIX.

   Owner defect, 2026-08-06, film A20 at 1:25: "the more actions button … has a large box around it. Can we just
   make sure it looks like the rest of the app's more button." The box was drawn on the WRAPPER, not the button.
   kanine-design-system.css §5l styles every floating popover through `[class$="-menu"]`, a selector that keys on
   the end of the class ATTRIBUTE — so a wrapper named `kl-sr-menu` matched it and inherited a menu PANEL's chrome:
   min-inline-size 12rem, an opaque --k-surface fill, a --k-border hairline, a radius and an --k-elev-3 shadow.
   Every row therefore carried a 192px bordered, shadowed card around a 32px glyph. Nothing failed, because nothing
   asked. This is the class-suffix family trap, and it is the second time it has been paid for here.

   That 12rem floor is also what made the actions column ~202px wide. An earlier pass measured the width, blamed
   the button's `min-inline-size` and capped the BUTTON — a change that could not reach the real cause and left the
   box exactly where it was. The lesson is recorded rather than summarised: measure the element that DRAWS the box,
   not the one inside it.

   The wrapper now wears `kl-rowmenu-wrap` — the shared class the RowContextMenu primitive uses on the other
   fourteen row lists — and this page adds only the positioning its own absolutely-placed dropdown needs.
   `kl-sr-menuhost` does not end in `-menu`, `-list` or any other family suffix in §5, which is checked by a test
   rather than by eye. */
.kl-sr-menuhost[b-4h3aevwg1p] {
    position: relative;
}

/* THIS PAGE DECLARES NOTHING ABOUT THE KEBAB'S APPEARANCE, AND THAT IS THE POINT.

   A `.kl-sr-overflow` rule used to sit here and cap the button to 32px, on the reading that the actions column was
   wide because the button was. It was not: the 12rem floor came from the WRAPPER (see the note above), so the cap
   narrowed the glyph's target below the standard --k-touch square while the box it was meant to remove stayed.
   Both are gone. The trigger now carries `kl-rowmenu-kebab` and resolves every visual property from
   kanine-design-system.css §5c-k — the same declarations the other fourteen row lists resolve. A page-local
   override here would re-open the drift this fix closed, so there is none. */

/* Shrink-to-content for the actions column (the `width: 1%` table idiom): table layout otherwise hands it the
   leftover width, which is what made the pinned cell wide enough to hide two columns. */
.kl-sr-table th:last-child[b-4h3aevwg1p],
.kl-sr-row > td:last-child[b-4h3aevwg1p] {
    inline-size: 1%;
    white-space: nowrap;
}

.kl-sr-menu-list[b-4h3aevwg1p] {
    position: absolute;
    inset-inline-end: 0;
    inset-block-start: calc(100% + var(--k-space-1));
    z-index: 50;
    min-inline-size: 14rem;
    display: flex;
    flex-direction: column;
    padding: var(--k-space-1);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    box-shadow: var(--k-elev-2);
}

.kl-sr-menu-item[b-4h3aevwg1p] {
    text-align: start;
    padding: var(--k-space-2) var(--k-space-3);
    background: transparent;
    border: 0;
    border-radius: var(--k-radius-sm);
    font-size: 14px;
    color: var(--k-text);
    cursor: pointer;
}

.kl-sr-menu-item:hover:not(:disabled)[b-4h3aevwg1p] {
    background: var(--k-surface-2);
}

.kl-sr-menu-item:disabled[b-4h3aevwg1p] {
    color: var(--k-text-muted);
    cursor: not-allowed;
    opacity: .65;
}

.kl-sr-menu-item--danger[b-4h3aevwg1p] {
    color: var(--k-critical);
}

.kl-sr-menu-item--danger:hover:not(:disabled)[b-4h3aevwg1p] {
    background: color-mix(in srgb, var(--k-critical) 10%, var(--k-surface));
}

/* ---- Empty state (titled, composed — never an emoji void) ---------------- */
.kl-sr-empty[b-4h3aevwg1p] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--k-space-3);
    padding: var(--k-space-12) var(--k-space-6);
    text-align: center;
    background: var(--k-surface);
    border: 1px dashed var(--k-border);
    border-radius: var(--k-radius-lg);
    color: var(--k-text-muted);
}

.kl-sr-empty-icon[b-4h3aevwg1p] {
    font-size: 40px;
    color: var(--k-teal-700);
    /* the icon primitive clips to 1em; widen the box so the 40px glyph is not cropped */
    inline-size: 40px;
    block-size: 40px;
    overflow: visible;
}

.kl-sr-empty-title[b-4h3aevwg1p] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 18px;
    font-weight: 700;
    color: var(--k-text);
}

.kl-sr-empty-body[b-4h3aevwg1p] {
    margin: 0;
    max-inline-size: 38rem;
    font-size: 14px;
    line-height: 1.5;
    color: var(--k-text-muted);
}

.kl-sr-empty-cta[b-4h3aevwg1p] {
    margin-block-start: var(--k-space-2);
}

/* ---- Run-history deferred card (intentional, not broken) ----------------- */
.kl-sr-runhistory[b-4h3aevwg1p] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-3);
    padding: var(--k-space-4) var(--k-space-6);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
}

.kl-sr-runhistory-icon[b-4h3aevwg1p] {
    font-size: 22px;
    color: var(--k-teal-700);
    flex: 0 0 auto;
    margin-block-start: 2px;
}

.kl-sr-runhistory-text[b-4h3aevwg1p] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}

.kl-sr-runhistory-title[b-4h3aevwg1p] {
    margin: 0;
    font-weight: 600;
    color: var(--k-text);
}

.kl-sr-runhistory .kl-readonly-note[b-4h3aevwg1p] {
    margin: 0;
}

.kl-sr-runhistory-link[b-4h3aevwg1p] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-1);
    align-self: flex-start;
    color: var(--k-teal-700);
    font-weight: 500;
    text-decoration: none;
}

.kl-sr-runhistory-link:hover[b-4h3aevwg1p] {
    color: var(--k-teal-500);
    text-decoration: underline;
}

.kl-sr-runhistory-link .ki[b-4h3aevwg1p] {
    font-size: 16px;
}

/* ---- Create / edit sheet ------------------------------------------------- */
/* UI-GUAR-033: the .kl-sr-sheet is no longer the overlay — <KlOverlay> now supplies the single
   full-viewport opaque navy scrim + centering + ESC/outside-click. This element is now just the
   role="dialog" PANEL wrapper: a content-sized flex box (NOT full-viewport, NOT display:contents —
   it must own a real bounding box so it can be centered + measured) that holds the .kl-sr-form card.
   RETIRED the old defects: position:fixed/inset:0 overlay placement, align-items:flex-start
   (top-pinned, not centered), and background:color-mix(--k-text 38%) (a mode-flipping scrim that
   washed out / went light in dark). */
.kl-sr-sheet[b-4h3aevwg1p] {
    display: flex;
    inline-size: min(46rem, 100%);
    /* THIS CAP IS THE ONLY ONE THAT WORKS, AND REMOVING IT WAS TRIED AND MEASURED (D57, 2026-09-13).
       D56-R handed this back as one of four "restated caps within reserve" - a copy of the identical
       `max-block-size: min(90vh, 52rem)` on `.kl-sr-form` below. Reading the two rules says the child cap
       is the real one, because the child is also the scroll container. The measurement says the opposite:
       the `.kl-sr-form` rule does not apply to anything at all (see the note on that rule), so this
       declaration is the whole containment.

       Deleting it and opening the real sheet at 1400x900 / 393x852 / 780x360 gave a saturated panel of
       4617.56 / 4650.56 / 4617.56 px against 868 / 820 / 328 px of reserve - an overrun of 3749.56 px at
       the smallest. That is the case D56-R named: a cap that looks restated and is load-bearing. */
    max-block-size: min(90vh, 52rem);
}

/* `::deep`, AND IT IS NOT A STYLE PREFERENCE - WITHOUT IT THIS ENTIRE RULE APPLIED TO NOTHING.
   Found by measurement, D57 2026-09-13, while checking whether the cap below was a redundant copy.
   The element this rule names is rendered by `<EditForm>`, which is a Blazor COMPONENT. Scoped CSS stamps
   its `b-…` attribute onto elements DECLARED IN THIS FILE; a child component's own root element is not one
   of them, so the `<form>` carries no scope attribute and `.kl-sr-form[b-…]` matched nothing. Measured on
   the live create sheet, the `<form>` computed `max-block-size: none`, `overflow-y: visible`,
   `padding: 0px`, `background: rgba(0,0,0,0)`, `border-width: 0px`, `border-radius: 0px` and
   `display: block` - every declaration below, absent.
   It was VISIBLE, and had been for as long as the rule existed: the create sheet rendered with no card at
   all, its fields sitting straight on the dimmed page with the page showing through between them.
   `.kl-sr-sheet ::deep .kl-sr-form` compiles to `.kl-sr-sheet[b-…] .kl-sr-form` - the scope moves onto the
   ancestor this file DOES own, and the rule reaches the form.
   The DESCENDANT rules below (`.kl-fieldset`, `.kl-sr-actions`, …) were never affected: their subject is an
   element written in this file, so it carries the scope. Only a rule whose SUBJECT is `.kl-sr-form` itself
   was dead, which is this rule and the two theme rules at the foot of the file. */
.kl-sr-sheet[b-4h3aevwg1p]  .kl-sr-form {
    inline-size: min(46rem, 100%);
    max-block-size: min(90vh, 52rem);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    padding: var(--k-space-6);
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-3);
}

.kl-fieldset[b-4h3aevwg1p] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-3);
    margin: 0;
    padding: var(--k-space-3);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
}

.kl-fieldset legend[b-4h3aevwg1p] {
    padding-inline: var(--k-space-2);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--k-text-muted);
}

.kl-radio[b-4h3aevwg1p],
.kl-check[b-4h3aevwg1p] {
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-2);
    font-size: 14px;
    color: var(--k-text);
}

.kl-check--disabled[b-4h3aevwg1p] {
    color: var(--k-text-muted);
    opacity: .7;
}

.kl-sr-degraded[b-4h3aevwg1p] {
    font-family: var(--k-font-mono);
    font-size: 12px;
    color: var(--k-text-muted);
}

.kl-sr-fixed[b-4h3aevwg1p] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-3);
    inline-size: 100%;
}

.kl-sr-error[b-4h3aevwg1p] {
    margin: 0;
    color: var(--k-critical);
    font-size: 13px;
}

.kl-sr-actions[b-4h3aevwg1p] {
    display: flex;
    justify-content: flex-end;
    gap: var(--k-space-2);
}

/* ---- Deliberate dark + outdoor (R11 punch-list) -------------------------- */
html.dark .kl-sr-sheet[b-4h3aevwg1p]  .kl-sr-form {
    border-color: color-mix(in srgb, var(--k-border) 72%, var(--k-text-muted));
}

html[data-outdoor="true"] .kl-sr-sheet[b-4h3aevwg1p]  .kl-sr-form {
    border-width: 2px;
}

html[data-outdoor="true"] .kl-sr-report-title[b-4h3aevwg1p] {
    font-weight: 800;
}
/* _content/Kanine.Web/Components/Pages/SettingsHub.razor.rz.scp.css */
/* Agency settings guide (owner-directed 2026-07-18) — the durable configuration hub the setup checklist
   graduates into. Quiet link-card rows: the page is navigation, so nothing competes with the destinations. */

.kl-hub-intro[b-rkv7r61itx] { max-width: 70ch; margin-block-end: var(--k-space-7); }

.kl-hub-group[b-rkv7r61itx] { margin-block-end: var(--k-space-7); }

.kl-hub-list[b-rkv7r61itx] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--k-space-3); }

.kl-hub-link[b-rkv7r61itx] {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--k-space-4) var(--k-space-5);
  background: var(--k-surface-2); border: 1px solid var(--k-border); border-radius: var(--k-radius-md);
  color: inherit; text-decoration: none;
  transition: border-color .12s, background-color .12s;
}
.kl-hub-link:hover[b-rkv7r61itx] { border-color: var(--k-accent); background: color-mix(in oklab, var(--k-accent) 6%, var(--k-surface-2)); }
.kl-hub-link:focus-visible[b-rkv7r61itx] { outline: 2px solid var(--k-accent); outline-offset: 2px; }
.kl-hub-link:hover .kl-hub-link-title[b-rkv7r61itx] { color: var(--k-accent); }

.kl-hub-link-title[b-rkv7r61itx] { font-size: 14px; font-weight: 600; color: var(--k-text); transition: color .12s; }
.kl-hub-link-why[b-rkv7r61itx] { font-size: 12.5px; line-height: 1.5; color: var(--k-text-muted); }
/* _content/Kanine.Web/Components/Pages/SignaturePad.razor.rz.scp.css */
/* REC-005 / SEC-SIG-001 — signature-pad sign-to-seal surface, page-major R11 (restrained-premium).
   Consumes the global cross-cutting vocabulary (kl-page, kl-card, kl-btn, kl-btn--seal, kl-btn--ghost, kl-chip,
   kl-section-head, kl-mono) from kanine-design-system.css; this scoped sheet adds ONLY the review surface (owner
   ruling 2026-10-01: no drawing pad), the accepted (sealed) card rhythm, and the single CALM sign-to-seal confirm
   transition. Every colour is a --k-* token
   (no raw fills, no gradients) so the R11 token/canvas objective teeth hold; the global prefers-reduced-motion guard
   neutralizes the seal animation. Scoped (b-hash) selectors target this page's own elements only. */

.kl-sign[b-zlymn7f07v] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-6);
}

.kl-sign-head[b-zlymn7f07v] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}

.kl-sign-title[b-zlymn7f07v] {
    font-family: var(--k-font-display);
    font-size: 22px;
    font-weight: 800;
    margin: 0;
    color: var(--k-text);
}

.kl-sign-desc[b-zlymn7f07v] {
    margin: 0;
    color: var(--k-text-muted);
}

.kl-sign-ref[b-zlymn7f07v] {
    padding: var(--k-space-1) var(--k-space-2);
    border-radius: var(--k-radius-sm);
    background: var(--k-surface-2);
    color: var(--k-text);
}

/* ---- Review surface (owner ruling 2026-10-01: no drawing pad) ------------------------------------------- */
.kl-sign-review[b-zlymn7f07v] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    padding: var(--k-space-4);
}

.kl-sign-facts[b-zlymn7f07v] {
    margin: 0;
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--k-space-2) var(--k-space-4);
    align-items: center;
}

.kl-sign-facts dt[b-zlymn7f07v] {
    color: var(--k-text-muted);
    font-size: 13px;
}

.kl-sign-facts dd[b-zlymn7f07v] {
    margin: 0;
    color: var(--k-text);
    min-inline-size: 0;
}

.kl-sign-how[b-zlymn7f07v] {
    margin: 0;
    color: var(--k-text-muted);
    font-size: 13px;
}

.kl-sign-actions[b-zlymn7f07v] {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--k-space-4);
    padding-block-start: var(--k-space-2);
    border-block-start: 1px solid var(--k-border);
}

/* ---- Step-up surface ----------------------------------------------------- */
/* UI-GUAR-033: the step-up is a layout-TRANSPARENT marker (display:contents) — each face supplies its OWN
   .kl-modal-overlay scrim (the self-scrimming SignatureStepUpDialog for the credential face; an inline overlay for
   the 2FA face), and those scrims are position:fixed full-viewport. So this wrapper must NOT insert a box (which
   would sit in normal flow and offset/clip the fixed overlay); display:contents makes it vanish from layout while
   keeping the data-testid="sign-stepup" hook the tests assert. */
.kl-sign-stepup[b-zlymn7f07v] {
    display: contents;
}

.kl-sign-2fa[b-zlymn7f07v] {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: var(--k-space-1);
    background: none;
    border: 0;
    padding: 0;
    font-size: 13px;
    color: var(--k-accent);
    cursor: pointer;
}

.kl-sign-2fa:hover[b-zlymn7f07v] {
    text-decoration: underline;
}

/* The honest-defer note on the 2FA face (no second factor enrolled on this build). */
.kl-sign-2fa-note[b-zlymn7f07v] {
    margin: var(--k-space-3) 0;
    color: var(--k-text-muted);
    font-size: 13px;
    line-height: 1.5;
}

.kl-sign-failure[b-zlymn7f07v] {
    padding: var(--k-space-3) var(--k-space-4);
    border-radius: var(--k-radius-md);
    background: color-mix(in srgb, var(--k-critical) 10%, var(--k-surface));
    border: 1px solid color-mix(in srgb, var(--k-critical) 40%, transparent);
    color: var(--k-text);
}

/* ---- COMMITTED accepted (sealed) state ----------------------------------- */
.kl-sign-accepted[b-zlymn7f07v] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-4);
    padding: var(--k-space-6);
    border: 1px solid color-mix(in srgb, var(--k-success) 35%, var(--k-border));
}

.kl-sign-accepted-icon[b-zlymn7f07v] {
    flex-shrink: 0;
    inline-size: 3rem;
    block-size: 3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--k-radius-full);
    background: color-mix(in srgb, var(--k-success) 14%, transparent);
    color: var(--k-success);
}

.kl-sign-accepted-icon .ki[b-zlymn7f07v] {
    font-size: 28px;
    font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}

/* Record-sealed badge: the brand "officially sealed" animation glows on a navy chip. The black gif background
   drops out via screen blend, so it reads in every theme; reduced-motion users see the static seal mark instead. */
.kl-sign-accepted-icon--seal[b-zlymn7f07v] {
    inline-size: 4.5rem;
    block-size: 4.5rem;
    border-radius: var(--k-radius-lg);
    background: var(--k-ink-900);
    overflow: hidden;
}
.kl-sign-accepted-icon--seal .kl-seal-anim[b-zlymn7f07v] {
    inline-size: 4rem;
    block-size: 4rem;
    object-fit: contain;
    mix-blend-mode: screen;
}
.kl-sign-accepted-icon--seal .kl-seal-static[b-zlymn7f07v] {
    display: none;
    color: var(--k-teal-400);
}
/* LOAD-FAILURE fallback — a separate condition from the motion preference below. kanine-shell-nav.js stamps
   data-kanine-img-failed on any [data-kanine-img-fallback] <img> whose asset never arrived, so a 404 reveals the
   static seal glyph instead of leaving an empty navy box that reads as a deliberate design choice. */
.kl-sign-accepted-icon--seal .kl-seal-anim[data-kanine-img-failed][b-zlymn7f07v] { display: none; }
.kl-sign-accepted-icon--seal .kl-seal-anim[data-kanine-img-failed] ~ .kl-seal-static[b-zlymn7f07v] { display: inline-flex; }
@media (prefers-reduced-motion: reduce) {
    .kl-sign-accepted-icon--seal .kl-seal-anim[b-zlymn7f07v] { display: none; }
    .kl-sign-accepted-icon--seal .kl-seal-static[b-zlymn7f07v] { display: inline-flex; }
}

.kl-sign-accepted-body[b-zlymn7f07v] {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
    min-inline-size: 0;
}

.kl-sign-accepted-title[b-zlymn7f07v] {
    font-family: var(--k-font-display);
    font-size: 18px;
    font-weight: 700;
    margin: 0 0 var(--k-space-1);
    color: var(--k-text);
}

.kl-sign-accepted-line[b-zlymn7f07v] {
    margin: 0;
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    font-size: 13px;
    color: var(--k-text-muted);
    flex-wrap: wrap;
}

.kl-sign-accepted-status[b-zlymn7f07v] {
    margin: var(--k-space-2) 0 0;
    font-size: 13px;
    color: var(--k-text-muted);
}

/* The whole sealed card eases in once on commit: a calm, precise seal transition (no gimmick/bounce). */
.kl-seal-in[b-zlymn7f07v] {
    animation: kl-seal-in-b-zlymn7f07v 320ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

@keyframes kl-seal-in-b-zlymn7f07v {
    from {
        opacity: 0;
        transform: translateY(8px) scale(0.985);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}
/* _content/Kanine.Web/Components/Pages/SpecReport.razor.rz.scp.css */
/*
  P1-13 — the spec report page: a parameter rail beside the preview on a wide screen, stacked on a phone. Tokens only
  (--k-*), logical properties (RTL-safe). The preview document scrolls inside its own column, so the page never
  scrolls sideways at phone width.
*/

.kl-spec[b-75ozq9g2l5] {
  display: flex;
  flex-direction: column;
  gap: var(--k-space-4);
  padding: var(--k-space-4);
  min-inline-size: 0;
}

.kl-spec-head[b-75ozq9g2l5] {
  display: flex;
  flex-direction: column;
  gap: var(--k-space-1);
}

.kl-spec-back[b-75ozq9g2l5] {
  align-self: flex-start;
  font-size: 0.85rem;
  color: var(--k-text);
}

.kl-spec-title[b-75ozq9g2l5] {
  margin: 0;
  font-family: var(--k-font-display);
  font-size: 1.4rem;
  line-height: 1.2;
}

.kl-spec-banner[b-75ozq9g2l5] {
  border: 1px solid var(--k-border);
  border-inline-start: 4px solid var(--k-caution);
  border-radius: var(--k-radius-md);
  background: var(--k-surface);
  padding: var(--k-space-3) var(--k-space-4);
}

.kl-spec-banner-title[b-75ozq9g2l5] {
  margin: 0 0 var(--k-space-1);
  font-weight: 600;
}

.kl-spec-banner ul[b-75ozq9g2l5] {
  margin: 0;
  padding-inline-start: var(--k-space-4);
}

.kl-spec-locked[b-75ozq9g2l5] {
  border: 1px solid var(--k-border);
  border-radius: var(--k-radius-md);
  background: var(--k-surface);
  padding: var(--k-space-6);
  max-inline-size: 40rem;
}

.kl-spec-locked h2[b-75ozq9g2l5] {
  margin: var(--k-space-2) 0;
  font-size: 1.1rem;
}

.kl-spec-locked-icon[b-75ozq9g2l5] {
  font-size: 1.5rem;
  color: var(--k-text-muted);
}

.kl-spec-locked-keys[b-75ozq9g2l5] {
  margin: var(--k-space-2) 0;
  padding-inline-start: var(--k-space-6);
}

.kl-spec-body[b-75ozq9g2l5] {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--k-space-4);
}

@media (min-width: 960px) {
  .kl-spec-body[b-75ozq9g2l5] {
    grid-template-columns: minmax(16rem, 20rem) minmax(0, 1fr);
    align-items: start;
  }
}

.kl-spec-params[b-75ozq9g2l5] {
  display: flex;
  flex-direction: column;
  gap: var(--k-space-3);
  min-inline-size: 0;
}

.kl-spec-preview[b-75ozq9g2l5] {
  display: flex;
  flex-direction: column;
  gap: var(--k-space-3);
  min-inline-size: 0;
  overflow-x: auto;
}

.kl-spec-actions[b-75ozq9g2l5],
.kl-spec-pager[b-75ozq9g2l5] {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--k-space-2);
}

.kl-spec-action[b-75ozq9g2l5] {
  min-block-size: 44px;
  padding: var(--k-space-1) var(--k-space-3);
  border: 1px solid var(--k-border);
  border-radius: var(--k-radius-sm);
  background: var(--k-surface);
  color: var(--k-text);
  font: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}

.kl-spec-action[disabled][b-75ozq9g2l5] {
  opacity: 0.55;
  cursor: not-allowed;
}

.kl-spec-note[b-75ozq9g2l5] {
  margin: 0;
  font-size: 0.85rem;
  color: var(--k-text-muted);
}

.kl-spec-job[b-75ozq9g2l5] {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--k-space-2);
}

.kl-spec-job p[b-75ozq9g2l5] {
  margin: 0;
}

/* Owner ruling 2026-10-10 Q13 (ruling C5): the Print button gives the recorded server PDF. A browser print (Ctrl+P)
   writes no row, so on paper the page shows one line only and no report data. The line is hidden on screen. */
.kl-spec-print-recorded[b-75ozq9g2l5] {
  display: none;
}

@media print {
  .kl-spec[b-75ozq9g2l5] {
    display: none;
  }

  .kl-spec-print-recorded[b-75ozq9g2l5] {
    display: block;
    margin: 0;
    font-size: 1rem;
  }
}
/* _content/Kanine.Web/Components/Pages/Templates.razor.rz.scp.css */
/* =============================================================================
   Templates (/templates) — page-scoped R11 refinement (UI-GUAR-011).
   -----------------------------------------------------------------------------
   Consumes the foundation primitives (kl-page, kl-section-head, kl-count,
   kl-head-actions, kl-btn--*, kf-field/kf-input/kf-textarea, kl-chip + variants,
   kl-dialog, States kit). This file adds ONLY what the two-pane Templates surface
   needs beyond the system: the responsive list/editor split, the elevated list
   card with a teal-fill SELECTED row, chip/name presentation, and the deliberate
   dark/outdoor edges. On-token colour only (var(--k-*)); no gradients, no body-bg
   change — the central R11 token/canvas teeth stay green. Blazor scopes every
   selector to this component, so the class names need not be globally unique.
   ========================================================================== */

/* ---- Two-pane workspace: list (left) + editor (right). Collapses to one column
   on a narrow viewport so neither pane is squeezed below a usable measure. ---- */
.kl-tpl-workspace[b-leafuad94h] {
    display: grid;
    grid-template-columns: minmax(16rem, 24rem) minmax(0, 1fr);
    gap: var(--k-space-6);
    align-items: start;
}

@media (max-width: 56rem) {
    .kl-tpl-workspace[b-leafuad94h] {
        grid-template-columns: 1fr;
    }
}

/* ---- LEFT COLUMN: choose, then act (layout rethink 2026-09-12) ----------------------------------------------
   One flex column holding the phone picker, the list card and the create card, in that order. It exists so the
   three can be sticky AS A UNIT at two-pane widths (the sticky block moved here from .kl-tpl-listcard — see the
   min-width band at the foot of this file) and so the list can shrink and scroll INSIDE the column while the create
   card keeps its size. Named "-side": no shared suffix family ends in -side, so nothing repaints it. */
.kl-tpl-side[b-leafuad94h] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    min-inline-size: 0;
}

/* THE CREATE CARD. Named like its two siblings (kl-tpl-listcard / kl-tpl-editorcard): "createcard" does NOT end in
   the "-card" suffix, so the shared card family does not paint it — deliberately, the same choice the siblings made,
   because the family's 24px padding and trailing 16px margin are wrong inside this column. The chrome below is the
   SAME four token declarations the list card carries (surface, hairline, radius, elevation) at the list card's 16px
   padding, so the three cards read as one surface. Measured on the first cut without this block: the heading and
   the two creates floated on the page ground under the list with no edge at all. */
.kl-tpl-createcard[b-leafuad94h] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    padding: var(--k-space-4);
    min-inline-size: 0;
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
}

/* The heading rides the shared -card-title family (18px display, bold); the column's gap replaces its margin. */
.kl-tpl-createcard-title[b-leafuad94h] {
    margin: 0;
}

/* What the create makes: the stored name, then a muted one-line summary. Both wrap rather than widen the column. */
.kl-tpl-createfrom[b-leafuad94h] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    min-inline-size: 0;
    font-size: 14px;
    line-height: 1.35;
}

.kl-tpl-createname[b-leafuad94h] {
    font-weight: 700;
    color: var(--k-text);
    overflow-wrap: anywhere;
}

.kl-tpl-createsummary[b-leafuad94h],
.kl-tpl-creategroup[b-leafuad94h] {
    font-size: 13px;
    color: var(--k-text-muted);
    overflow-wrap: anywhere;
}

.kl-tpl-creategroup[b-leafuad94h] {
    margin: 0;
}

/* The two creates, stacked full width so the pair reads as a CHOICE (group run above, single-template opt-out
   under it) and so neither can wrap its own label at 320. A6: each keeps the shared .kl-btn 48px floor. */
.kl-tpl-createstack[b-leafuad94h] {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--k-space-2);
    margin-block-start: var(--k-space-1);
}

.kl-tpl-createstack > .kl-btn[b-leafuad94h] {
    inline-size: 100%;
}

/* ---- PHONE: the left column collapsed to one row (owner request 2026-07-25) ------------------------------
   Hidden by default so DESKTOP AND TABLET ARE UNTOUCHED — the list card remains the navigation there. It is only
   turned on inside the max-width:640px block at the foot of this file, where it replaces the card one-for-one.
   A display:none element is not a grid item at all, so it creates no track and no gap and the wide two-pane
   layout is byte-identical to before.
   NOT lifted into the shared design system: the only genuinely shared part of this pattern is the full-width
   native select, which IS the shared .kf-select primitive both this page and Lookups already use. What is left
   is four layout declarations bound to THIS page's container and THIS page's loader — no shared declaration is
   duplicated, and no colour is declared here at all. */
.kl-tpl-listpicker[b-leafuad94h] { display: none; }

.kl-tpl-listpicker-label[b-leafuad94h] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

.kl-tpl-listpicker-select[b-leafuad94h] {
    inline-size: 100%;
    max-inline-size: 100%;
    min-inline-size: 0;
    box-sizing: border-box;
    /* A6: the picker is the page's primary navigation on a phone — it keeps the full touch floor. */
    min-block-size: var(--k-touch);
}

/* ---- LEFT: the available-template list card. ------------------------------- */
.kl-tpl-listcard[b-leafuad94h] {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-4);
    /* The list scrolls within the card on tall sets without pushing the editor down. */
    max-block-size: calc(100vh - 12rem);
    overflow-y: auto;
    /* The selected-row teal fill must not bleed past the card's rounded corners. */
    overflow-x: hidden;
}

.kl-tpl-listcard-title[b-leafuad94h] {
    font-family: var(--k-font-display);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--k-text-muted);
    margin: var(--k-space-1) var(--k-space-2) var(--k-space-3);
}

.kl-tpl-rows[b-leafuad94h] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
}

/* OWNER 2026-09-11 — "the highlight box just sorrounds the content not 'select' the box".
   MEASURED on the live host at 1400: li.kl-tpl-row was 318x94.5 and button.kl-tpl-select inside it
   was 284x68.5 — the pointer target and the focus/selected ring were 34px narrower and 26px shorter
   than the card a reader sees, so a click near the card edge did nothing and the ring outlined the
   content instead of the card.
   WHERE THE INSET CAME FROM. Not this sheet. The SHARED design-system family rule
   `.kl-shell-main :where([class^="kl-"], [class*=" kl-"])[class$="-row"]` paints EVERY kl-*-row as a
   card: display:flex, padding var(--k-space-3) var(--k-space-4), a 1px border and a surface. That is
   right for a row holding several children; this row holds exactly ONE child and that child IS the
   control, so the card's padding belongs INSIDE the button rather than around it.
   WHAT CHANGED. The li keeps the family's surface, border and radius — it is still a member of that
   family and still reads like every other row on every other page — and gives up only its padding,
   which moves onto the button below. The button then fills the card's whole interior: one control,
   one box, one focus ring.
   NO role="button" IS ADDED to the li (the /notifications precedent, 2026-09-08): an li carrying that
   role announces as activatable while Enter and Space do nothing on it. Here nothing needs to be
   faked — the real <button> already covers the card, so it remains the pointer target, the keyboard
   target and the assistive-technology control, all on the same box. */
.kl-tpl-row[b-leafuad94h] {
    padding: 0;
    align-items: stretch;
    border-radius: var(--k-radius-md);
}

/* The whole CARD is the tap target (≥48px via the stacked content + the padding this rule now owns).
   It reads as a quiet list item until hovered/selected — restrained, not a button slab. */
.kl-tpl-select[b-leafuad94h] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
    inline-size: 100%;
    min-block-size: var(--k-touch);
    /* The padding the .kl-tpl-row family rule used to hold. Same ink, one box further in. */
    padding: var(--k-space-3) var(--k-space-4);
    background: transparent;
    border: 1px solid transparent;
    /* One pixel tighter than the card, so the fill and the focus ring trace the INSIDE of the card's
       own 1px border instead of bleeding a hair past its corners. */
    border-radius: calc(var(--k-radius-md) - 1px);
    text-align: start;
    cursor: pointer;
    color: var(--k-text);
    transition: background var(--k-dur-1) var(--k-ease), border-color var(--k-dur-1) var(--k-ease);
}

.kl-tpl-select:hover[b-leafuad94h] {
    background: var(--k-surface-2);
}

/* SELECTED row: a calm teal-tint fill + a teal edge (navy-ink text stays legible in
   every mode). This is the page's clearest "this is the open template" signal. */
.kl-tpl-row[data-selected="true"] > .kl-tpl-select[b-leafuad94h] {
    background: color-mix(in srgb, var(--k-teal-500) 16%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-teal-500) 55%, transparent);
}

.kl-tpl-row[data-selected="true"] > .kl-tpl-select:hover[b-leafuad94h] {
    background: color-mix(in srgb, var(--k-teal-500) 22%, var(--k-surface));
}

.kl-tpl-row-main[b-leafuad94h] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    min-inline-size: 0;
}

.kl-tpl-row-name[b-leafuad94h] {
    font-weight: 700;
    font-size: 15px;
    color: var(--k-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* OWNER 2026-09-11 — "there is also too much info being crammed into that content … the name of the
   trainnig day may be long and thats a badge too. We either need to give another row for badges and
   content to show or handle them better."
   THE SECOND ROUTE HE OFFERED, TAKEN. One row used to carry the type chip, the group chip, the scope
   chip AND the owner line inside 258px of usable width; a real template-group name ("Monday narcotics
   — vehicle + open area, second shift") pushed the owner line off the row entirely.
   Badges now own their OWN row, directly under the one-line title (§A10 keeps the title to one line;
   the owner ruling of 2026-09-08 puts badges together near the top of a phone card, and doing it at
   every width means one arrangement to reason about instead of two). The owner/scope prose keeps the
   third row to itself, where it can no longer be crushed by a chip. */
.kl-tpl-row-badges[b-leafuad94h] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-1) var(--k-space-2);
    min-inline-size: 0;
}

.kl-tpl-row-meta[b-leafuad94h] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    min-inline-size: 0;
}

.kl-tpl-row-owner[b-leafuad94h] {
    font-size: 12px;
    color: var(--k-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kl-tpl-default[b-leafuad94h] {
    flex: 0 0 auto;
}

/* The record-type chip is a neutral category token (distinct from the status colours). */
.kl-tpl-typechip[b-leafuad94h] {
    flex: 0 0 auto;
    background: var(--k-surface-2);
    border-color: var(--k-border);
    color: var(--k-text-muted);
    text-transform: none;
}

/* ---- RIGHT: the editor card. ---------------------------------------------- */
.kl-tpl-editorcard[b-leafuad94h] {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-lg);
    box-shadow: var(--k-elev-1);
    padding: var(--k-space-6);
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    min-inline-size: 0;
}

.kl-tpl-editor-head[b-leafuad94h] {
    display: flex;
    align-items: flex-end;
    gap: var(--k-space-3);
}

.kl-tpl-namefield[b-leafuad94h] {
    flex: 1 1 auto;
    margin-block-end: 0;
    min-inline-size: 0;
}

/* The overflow-menu anchor: position:relative so the foundation's position:absolute
   menu hangs off it. The card has NO overflow:hidden, so the menu is clip-clean. */
.kl-tpl-more[b-leafuad94h] {
    position: relative;
    flex: 0 0 auto;
}

.kl-tpl-more-menu[b-leafuad94h] {
    inset-block-start: calc(var(--k-touch) + var(--k-space-1));
    inset-inline-end: 0;
}

/* A6: the shared -menu-item family already holds the 48px floor (UI-GUAR-036); this page-local rule used to pin
   40px and won the tie, so every item in this menu was 8px under the floor. Found while moving Set as my default
   and Save as new into the menu (2026-09-12). */
.kl-tpl-menu-item[b-leafuad94h] {
    display: flex;
    align-items: center;
    inline-size: 100%;
    min-block-size: var(--k-touch);
    padding: 0 var(--k-space-3);
    background: transparent;
    border: 0;
    border-radius: var(--k-radius-sm);
    font: inherit;
    font-size: 14px;
    color: var(--k-text);
    text-align: start;
    cursor: pointer;
}

.kl-tpl-menu-item:hover:not(:disabled)[b-leafuad94h] {
    background: var(--k-surface-2);
}

.kl-tpl-menu-item:disabled[b-leafuad94h] {
    color: var(--k-text-muted);
    cursor: not-allowed;
}

.kl-tpl-menu-delete[b-leafuad94h] {
    color: var(--k-critical);
}

.kl-tpl-menu-delete:hover[b-leafuad94h] {
    background: color-mix(in srgb, var(--k-critical) 10%, transparent);
}

/* Provenance line under the name — human owner + type, never a raw id. */
.kl-tpl-provenance[b-leafuad94h] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    margin: 0;
    font-size: 13px;
    color: var(--k-text-muted);
}

.kl-tpl-provenance-owner[b-leafuad94h] {
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The editor's top command bar (.kl-tpl-editor-actions) is GONE since the layout rethink of 2026-09-12: its create
   actions live in the create card in the left column and its two manage actions live in the title-bar menu. The
   editor's only action bar is now the commit pair in the footer (see .kl-tpl-editor-footer below). */

.kl-tpl-editor-body[b-leafuad94h] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-6);
}

/* The section boundaries (one hairline + one padding, identical at every boundary) are declared at the END of
   this file, after the fieldsets' own `border: 0` resets - see the design-pass block there. */

/* ---- Chip sets (terrain / distractions). ---------------------------------- */
.kl-tpl-chipset[b-leafuad94h] {
    margin: 0;
    padding: 0;
    border: 0;
    min-inline-size: 0;
}

/* DESIGN PASS 2026-09-12 - a SECTION head, not a field label. Measured before: legend 13px/600/muted and
   .kf-label 13px/600/muted, byte-identical, so 'What this template makes' and 'Base type' carried the same
   weight and the editor read as one flat run of fourteen labels. The legend now takes the display face at 15px,
   full ink and a hairline above (see .kl-tpl-editor-body below), so the eye finds the sections first and the
   fields second. No shared legend primitive exists in the kit (kf-label and kf-hint do; a fieldset legend does
   not), so this stays page-local and is the one typographic rule this page owns. */
.kl-tpl-chipset-legend[b-leafuad94h] {
    padding: 0;
    font-family: var(--k-font-display);
    font-size: 15px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--k-text);
    margin-block-end: var(--k-space-3);
}

.kl-tpl-chips[b-leafuad94h] {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin: 0 0 var(--k-space-2);
    padding: 0;
}

/* A prefill chip is a calm neutral token (the names, never the ids). */
.kl-tpl-chip[b-leafuad94h] {
    background: var(--k-surface-2);
    border-color: var(--k-border);
    color: var(--k-text);
    text-transform: none;
    font-weight: 600;
}

/* The EMPTY chip (owner 2026-07-25: "the none set should be a badge just like the selected items show").
   It is a REAL member of .kl-tpl-chips, so it inherits the whole box the foundation .kl-chip already defines —
   same padding, same radius, same 12px/1.5 line box — and the chip row therefore owns this block's height in BOTH
   states. That is the point: the old <p> above the list was a different box with its own typography and margins, so
   picking the first value collapsed the page under the user.
   Distinct from a real selection WITHOUT a new colour: no fill, a DASHED --k-border edge and muted text read as an
   absence rather than as a terrain literally named "None". The dashed edge carries the distinction as shape, so it
   never rests on colour alone; the meaning itself rides in the text (plus the visually-hidden tail in the markup).
   Non-interactive by design — see the .razor comment — hence no cursor, no hover, and no --k-touch floor.

   NAMED "--unset", NOT "--empty", AND THAT IS LOAD-BEARING. The foundation State kit (§5h) matches
   `.kl-shell-main [class$="-empty"]` on the whole class ATTRIBUTE, so ANY element whose class list ends in
   `-empty` silently becomes a centred full-page empty-state block with `padding: var(--k-space-12) var(--k-space-6)`.
   MEASURED: that is what the old `<p class="kl-tpl-chipset-empty">` was — 48px of padding above and below a
   one-line sentence, and the actual source of the owner's "takes up a lot of vertical space". A first pass at this
   fix named the modifier `--empty` and inherited the exact same 48px trap (a 116px chip). Do not rename it back. */
.kl-tpl-chip--unset[b-leafuad94h] {
    background: transparent;
    border-style: dashed;
    border-color: var(--k-border);
    color: var(--k-text-muted);
    font-weight: 500;
    font-style: italic;
}

/* The add control is the TONAL secondary (kl-btn--secondary): a real, bordered press that grows the draft, one
   tier below the page's single teal primary.
   RENAMED from .kl-tpl-chip-add on 2026-09-12, AND THAT IS LOAD-BEARING. The class attribute ended in "-add", and
   the design system's `[class$="-add"]` family (0,2,0) paints any such button as a FILLED TEAL PRIMARY, beating
   the declared kl-btn--ghost (0,1,0). Measured at 1400: all three Add buttons rgb(16,181,168) - three teal fills
   on a page whose ruling is exactly one. The same trap hit Save template through "-save" (now .kl-tpl-savetemplate).
   Req_UIGUAR003_TemplatesR11Tests.NoButton_EndsInARepaintingSuffixFamily keeps both from coming back. */
.kl-tpl-adder[b-leafuad94h] {
    flex: 0 0 auto;
    font-size: 13px;
}

/* The pick-then-add row (2026-07-02): a real-vocabulary select beside the anchored add button. */
.kl-tpl-chip-addrow[b-leafuad94h] {
    display: flex;
    /* DESIGN PASS 2026-09-12 - the row WRAPS. .kl-btn carries min-inline-size: var(--k-touch), so in a non-wrapping
       flex row the button shrank to 48px at 320 and its label spilled past its own border (measured: "Add
       distraction" 130px of text in a 100px box). Wrapping puts the button under the picker instead. */
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
    margin-block-start: var(--k-space-2);
}
.kl-tpl-chip-pick[b-leafuad94h] {
    /* Grows to the same 16rem it had, and no wider; can shrink to 10rem before the button wraps under it. */
    flex: 1 1 10rem;
    max-inline-size: 16rem;
    min-inline-size: 10rem;
    /* border-box, as .kl-tpl-listpicker-select above: .kf-select is content-box, so a 10rem basis was really ~190px
       and the distraction row still wrapped at 375. */
    box-sizing: border-box;
}

/* The per-chip remove ✕ (additions were irreversible before 2026-07-02) — a small inline glyph button
   that never balloons the chip (the chip stays the row-height owner). */
.kl-tpl-chip-x[b-leafuad94h] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-inline-start: var(--k-space-1);
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--k-text-muted);
    font-size: 11px;
    line-height: 1;
    cursor: pointer;
}
.kl-tpl-chip-x:hover[b-leafuad94h] { color: var(--k-critical); }
html.dark .kl-tpl-chip-x:hover[b-leafuad94h] { color: #f6ab9d; }
.kl-tpl-chip-x:focus-visible[b-leafuad94h] { outline: 2px solid var(--k-accent); outline-offset: 1px; }

.kl-tpl-notesfield[b-leafuad94h] {
    margin-block-end: 0;
}

/* ---- Footer: the commit pair. ---------------------------------------------
   A BLOCK wrapper around the shared <CommandBar> (which keeps the editor's action-bar identity). On a block-level
   child of a block parent .kl-head-actions' margin-inline-start:auto resolves to zero, so the bar is full width;
   the pair is then anchored inline-end INSIDE the bar, as every commit pair in this product is (owner 2026-08-09,
   CommitPairOrderGuardTests). ::deep is required: a child component's root never carries this sheet's scope
   attribute, so a plain descendant selector would compile and match nothing. */
.kl-tpl-editor-footer[b-leafuad94h] {
    display: block;
    padding-block-start: var(--k-space-4);
    margin-block-start: var(--k-space-2);
    border-block-start: 1px solid var(--k-border);
}

.kl-tpl-editor-footer[b-leafuad94h]  .kl-cmdbar {
    justify-content: flex-end;
}

/* ---- Placeholder editor pane (no draft selected). ------------------------- */
.kl-tpl-editor-placeholder[b-leafuad94h] {
    justify-content: center;
    min-block-size: 18rem;
}

/* ---- States: list-empty / loading. ---------------------------------------- */
.kl-tpl-empty[b-leafuad94h] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--k-space-3);
    text-align: center;
    padding: var(--k-space-8) var(--k-space-4);
    color: var(--k-text-muted);
}

.kl-tpl-empty-icon[b-leafuad94h] {
    font-size: 28px;
    opacity: .55;
    color: var(--k-text-muted);
}

.kl-tpl-empty-message[b-leafuad94h] {
    margin: 0;
    font-weight: 600;
    color: var(--k-text);
}

.kl-tpl-empty-hint[b-leafuad94h] {
    margin: 0;
    font-size: 13px;
    color: var(--k-text-muted);
    max-inline-size: 22rem;
}

.kl-tpl-loading[b-leafuad94h] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--k-space-2);
    padding: var(--k-space-12) var(--k-space-6);
    color: var(--k-text-muted);
}

.kl-tpl-loading-icon[b-leafuad94h] {
    font-size: 20px;
    opacity: .7;
    animation: kl-tpl-spin-b-leafuad94h 1.1s linear infinite;
}

@keyframes kl-tpl-spin-b-leafuad94h {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .kl-tpl-loading-icon[b-leafuad94h] { animation: none; }
}

/* ---- Delete dialog: the foundation kl-dialog card only. --------------------
   UI-GUAR-033: overlay/scrim retired — <KlOverlay> now supplies the fixed scrim +
   centering. The bespoke .kl-tpl-dialog-scrim (and the panel's position:relative,
   which only existed to anchor inside that scrim) are gone; the panel is a plain
   card the overlay centers. Only the dialog text rhythm is kept below. -------- */
.kl-tpl-dialog-title[b-leafuad94h] {
    font-family: var(--k-font-display);
    font-size: 18px;
    font-weight: 700;
    margin: 0;
    padding-block-start: var(--k-space-6);
    color: var(--k-text);
}

.kl-tpl-dialog-body[b-leafuad94h] {
    margin: var(--k-space-2) 0 0;
    font-size: 14px;
    color: var(--k-text-muted);
}

/* ---- DARK / OUTDOOR deliberate edges. -------------------------------------
   The foundation flips the bg/surface/border tokens per mode (so the canvas/token
   gate holds). Here we only RAISE the card edge + the type chip so the panes read
   as distinct surfaces in the dark/outdoor POV — no new colour, just var() weight. */
html.dark .kl-tpl-listcard[b-leafuad94h],
html.dark .kl-tpl-createcard[b-leafuad94h],
html.dark .kl-tpl-editorcard[b-leafuad94h] {
    border-color: var(--k-border);
    box-shadow: var(--k-elev-2);
}

html.dark .kl-tpl-typechip[b-leafuad94h],
html.dark .kl-tpl-chip[b-leafuad94h] {
    background: var(--k-surface-3);
    border-color: var(--k-outline);
    color: var(--k-text);
}

/* The empty chip must stay QUIET in dark too: the raised-chip rule above out-specifies the flat
   .kl-tpl-chip--unset base, so without this the absence would come back as a solid, full-contrast pill
   indistinguishable from a real selection. Only the fill/edge/ink change — the box, and therefore the row
   height, is identical to a real chip in every mode. */
html.dark .kl-tpl-chip--unset[b-leafuad94h] {
    background: transparent;
    border-color: var(--k-border);
    color: var(--k-text-muted);
}

/* Dark selected row: a stronger teal tint so the open template still reads clearly. */
html.dark .kl-tpl-row[data-selected="true"] > .kl-tpl-select[b-leafuad94h] {
    background: color-mix(in srgb, var(--k-teal-500) 26%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-teal-400) 60%, transparent);
}

/* Outdoor (glove-grade high contrast): heavier card borders + bolder chip edge. */
html[data-outdoor="true"] .kl-tpl-listcard[b-leafuad94h],
html[data-outdoor="true"] .kl-tpl-createcard[b-leafuad94h],
html[data-outdoor="true"] .kl-tpl-editorcard[b-leafuad94h] {
    border-width: 2px;
}

html[data-outdoor="true"] .kl-tpl-typechip[b-leafuad94h],
html[data-outdoor="true"] .kl-tpl-chip[b-leafuad94h] {
    border-color: var(--k-outline);
    color: var(--k-text);
}

/* Outdoor keeps the glove-grade --k-outline edge (legibility in sun is non-negotiable) but keeps the DASHED
   stroke, which is what carries "absence" as shape rather than as contrast. */
html[data-outdoor="true"] .kl-tpl-chip--unset[b-leafuad94h] {
    background: transparent;
    border-style: dashed;
}

html[data-outdoor="true"] .kl-tpl-row[data-selected="true"] > .kl-tpl-select[b-leafuad94h] {
    border-width: 2px;
    border-color: var(--k-accent);
}

/* ── WHAT THIS TEMPLATE MAKES (the REQUIRED activity taxonomy + the optional subtype) ─────────────
   The base type and the activity type are one functional pair and share ONE row, the same idiom the
   training-day name/order row below uses (B2). The subtype sits on its own line: it is optional and
   scoped to the record type, so pairing it with a required field would misread as a third required
   one. Vertical cost is one row plus one field — the fieldset reuses .kl-tpl-chipset-legend's type
   scale so this block and the two chipsets below read as one column, not three treatments. */
.kl-tpl-taxonomy[b-leafuad94h] {
    margin: 0;
    padding: 0;
    border: 0;
    min-inline-size: 0;
}

.kl-tpl-taxonomyrow[b-leafuad94h] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--k-space-3);
    margin-block-end: var(--k-space-3);
}

/* Both pickers hold long vocabulary labels ("Narcotics detection — vehicle exterior"), so they share
   the slack evenly and wrap to a stack rather than truncating. */
.kl-tpl-basefield[b-leafuad94h],
.kl-tpl-activityfield[b-leafuad94h] {
    flex: 1 1 14rem;
    min-inline-size: 0;
    margin-block-end: 0;
}

.kl-tpl-subtypefield[b-leafuad94h] {
    margin-block-end: var(--k-space-2);
}

/* The required marker rides the label, muted rather than alarm-red: nothing has gone wrong yet. */
.kl-tpl-req[b-leafuad94h] {
    color: var(--k-text-muted);
    margin-inline-start: 2px;
}

/* The refusal sentences (the save gate and the use gate) ride the SHARED .kf-hint (13px, muted, margin 0) since
   2026-09-12 - they state a precondition in the same voice as every other helper line on this page, and the
   page no longer owns a copy of that voice (A1). Rendered only while the rule is unmet. */

/* A write that was actually REFUSED — this one IS a failure, so it takes the danger colour. */
.kl-tpl-savefailed[b-leafuad94h] {
    margin: var(--k-space-2) 0 0;
    color: #b3261e;
    line-height: 1.4;
}

/* ── TRAINING DAY (legacy Kanine6 GroupCode parity) ───────────────────────────────────────────────
   The day NAME + the member's order share ONE row (B2: related things belong on a row), and the row
   degrades to a stack only when it genuinely cannot fit. Vertical space is spent deliberately (B1):
   the pair costs one row, not two, and the hint below is a single quiet line rather than a card.
   Touch targets are untouched — the inputs inherit .kf-input's height (A6). */
.kl-tpl-grouprow[b-leafuad94h] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--k-space-3);
    margin-block-end: var(--k-space-2);
}

/* The name takes the slack; the order box stays as narrow as a small integer needs. */
.kl-tpl-groupnamefield[b-leafuad94h] {
    flex: 1 1 16rem;
    min-inline-size: 0;
    margin-block-end: 0;
}

.kl-tpl-groupsortfield[b-leafuad94h] {
    flex: 0 0 7.5rem;
    margin-block-end: 0;
}

/* The hint line and the "Run training day" action share ONE row (B2). The hint takes the slack; the action
   keeps its full 48px target (A6) and never shrinks. Below the field breakpoint they wrap, which is accepted
   degradation — the action stays visible either way. */
.kl-tpl-grouphintrow[b-leafuad94h] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
}

/* Voice comes from the shared .kf-hint (13px muted) - before 2026-09-12 this line inherited the 16px body size
   and was the largest text in the editor, louder than the labels above it. Only layout is declared here. */
.kl-tpl-grouphint[b-leafuad94h] {
    flex: 1 1 18rem;
    min-inline-size: 0;
}

/* The list-row template-group chip: visually distinct from the record-type chip beside it, but the
   same pill scale so the badge row keeps its height.
   §B4 (badge proportionality) — a template group is named by a person and the name can be long, so
   the chip is CAPPED and the cap is deliberately below the card's own width: a badge that ran the
   full card would out-weigh the title it labels. `max-inline-size` on a flex chip cannot ellipsize
   the text by itself (the text node is not the overflow container), so the name rides in its own
   span below and this rule only bounds the pill. The untruncated name stays reachable on the chip's
   title attribute and in the a11y tree via the visually-hidden "Template group:" prefix. */
.kl-tpl-groupchip[b-leafuad94h] {
    background: color-mix(in srgb, var(--k-teal-500) 14%, var(--k-surface-2));
    border-color: color-mix(in srgb, var(--k-teal-500) 34%, transparent);
    color: var(--k-text);
    /* 11rem since the list column widened to 24rem (2026-09-12): a 28-character group name now fits, and the
       pill is still under a third of the card's interior (B4). */
    max-inline-size: 11rem;
    min-inline-size: 0;
}

/* The truncating half. It is the flex ITEM, so `overflow` has a box to act on. */
.kl-tpl-groupchip-name[b-leafuad94h] {
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* "Run training day · N activities" keeps its promise on ONE line — a count that wrapped away from the verb would
   be a button making half a claim.

   SUPERSEDED 2026-09-10: this rule used to read "sits beside Use template as the tonal secondary — one teal primary
   per screen stays with Use template". It does not any more. On a template filed into a day of two or more, the day
   run IS the one teal primary and the single-template create is the tonal secondary beside the day hint (owner
   report 2026-09-10 — he pressed the teal one and got one activity out of a two-template day). The "one filled
   primary per screen" rule is unchanged; which control holds it is what moved. */
.kl-tpl-usegroup[b-leafuad94h] {
    white-space: nowrap;
}

html.dark .kl-tpl-groupchip[b-leafuad94h] {
    background: color-mix(in srgb, var(--k-teal-400) 20%, var(--k-surface-3));
    border-color: color-mix(in srgb, var(--k-teal-400) 48%, transparent);
}

html[data-outdoor="true"] .kl-tpl-groupchip[b-leafuad94h] {
    border-width: 2px;
    border-color: var(--k-outline);
}

/* ---- PHONE: the list card → picker SWAP (owner request 2026-07-25) ---------------------------------------
   Deliberately AFTER `.kl-tpl-listpicker { display: none }` near the top: `@media` contributes no specificity,
   so a swap declared before that base rule would lose to it and the picker would never appear.
   `display:none` on the card rather than a visually-hidden class: this is a SWAP, not a duplication, so the
   same navigation must never be announced twice.
   The card is hidden ONLY when it is marked collapsible — i.e. only when there are templates and therefore a
   picker standing in for it. With zero templates the card IS the empty state (message + New template) and must
   survive on a phone, which is exactly what a blanket `.kl-tpl-listcard { display: none }` would have destroyed.
   640px is the SAME breakpoint the Lookups rail picker uses, so the two pages collapse together. */
@media (max-width: 640px) {
    .kl-tpl-listcard[data-phone-collapsed="true"][b-leafuad94h] { display: none; }

    .kl-tpl-listpicker[b-leafuad94h] {
        display: flex;
        flex-direction: column;
        gap: var(--k-space-2);
        inline-size: 100%;
        max-inline-size: 100%;
        min-inline-size: 0;
        box-sizing: border-box;
    }
}

/* ── REC-032 SCOPE CHIP (owner ask 2026-07-31) ────────────────────────────────────────────────────
   Two states, both NAMED and both visually distinct — "Private" is not the absence of "Agency".
   Colour is never the only signal: the chip carries its own word, so the meaning survives a
   greyscale print, a colour-blind reader and the outdoor palette. Sits on the existing meta row,
   so it costs no vertical space (B1). */
.kl-tpl-scopechip[b-leafuad94h] {
    font-size: 12px;
    letter-spacing: .01em;
}

/* Shared: the same teal family the training-day chip uses, because both mean "this reaches beyond
   the row you are looking at". */
.kl-tpl-scopechip[data-scope="shared"][b-leafuad94h] {
    background: color-mix(in srgb, var(--k-teal-500) 14%, var(--k-surface-2));
    border-color: color-mix(in srgb, var(--k-teal-500) 34%, transparent);
    color: var(--k-text);
}

/* Private: deliberately quiet. A private draft is the NORMAL state of a new template, so it must
   not read as a warning — muted surface, muted text, no accent. */
.kl-tpl-scopechip[data-scope="private"][b-leafuad94h] {
    background: var(--k-surface-2);
    border-color: var(--k-border);
    color: var(--k-text-muted);
}

/* The "new training day" name box appears UNDER its picker, so it needs the gap the picker's
   sibling fields get for free. */
.kl-tpl-groupnew[b-leafuad94h] {
    margin-block-start: var(--k-space-2);
}

/* ---- PLANNED FINDS (owner 2026-09-11) --------------------------------------------------------
   A plan is not a chip: it has a substance, a description and, on a training template, three
   placement values. So the list is rows, not a chip wrap - but the row reuses the chipset's
   legend, its empty-state chip and its remove control, so the panel still reads as one family
   with Default terrain and Default distractions directly above it. */
.kl-tpl-planset[b-leafuad94h] {
    /* The rows carry their own separation; the chip-wrap gap would double it. */
    row-gap: var(--k-space-2);
}

/* Voice from the shared .kf-hint; the page adds only the gap to the list below. */
.kl-tpl-planhint[b-leafuad94h] {
    margin: 0 0 var(--k-space-2);
}

.kl-tpl-planlist[b-leafuad94h] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--k-space-2);
}

.kl-tpl-planrow[b-leafuad94h] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
    /* Full width, and it MUST be able to shrink: without min-inline-size the number and text
       inputs inside set a flex base the row cannot go below, and the editor pane overflows
       horizontally at every phone width. */
    flex: 1 1 100%;
    min-inline-size: 0;
    padding: var(--k-space-3);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
}

.kl-tpl-planrow-head[b-leafuad94h] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-2);
    min-inline-size: 0;
}

/* The substance pill. Same teal family as the group and scope chips - all three mean "this value
   came from a governed vocabulary", not "this value is a warning". */
.kl-tpl-planchip[b-leafuad94h] {
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    background: color-mix(in srgb, var(--k-teal-500) 14%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-teal-500) 34%, transparent);
    color: var(--k-text);
}

/* A6 - a real 44px+ target, not a 20px glyph. It is the only destructive control in this panel. */
.kl-tpl-plan-remove[b-leafuad94h] {
    flex: 0 0 auto;
    min-inline-size: var(--k-touch);
    min-block-size: var(--k-touch);
}

.kl-tpl-planrow-fields[b-leafuad94h] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    min-inline-size: 0;
}

/* The description is the one field that wants the room; the three placement fields sit beside it
   and fold under it when they no longer fit. Every one of them can shrink to zero basis, so the
   row wraps instead of pushing the editor pane wider than the viewport. */
.kl-tpl-plan-descfield[b-leafuad94h] {
    flex: 3 1 14rem;
    min-inline-size: 0;
}

.kl-tpl-plan-amountfield[b-leafuad94h],
.kl-tpl-plan-bakefield[b-leafuad94h],
.kl-tpl-plan-heightfield[b-leafuad94h],
/* The pinned aid (RULING 4). It sits with the placement fields because it is the same kind of thing: a
   TRAINING-only detail of one hide. A wider basis than its siblings because an aid label carries a container
   AND a substance ("Tin - Cocaine") where a bake time carries one short word. */
.kl-tpl-plan-aidfield[b-leafuad94h] {
    flex: 1 1 8rem;
    min-inline-size: 0;
}

.kl-tpl-plan-aidfield[b-leafuad94h] {
    flex-basis: 12rem;
}

/* ---- PLANNED PEOPLE AND VEHICLES (owner 2026-09-11, ruled built 2026-09-12) ----
   The list reuses .kl-tpl-planlist / .kl-tpl-planrow verbatim, so a planned involvement and a planned find are
   the same object on screen. Only the two members a find row has no equivalent for are declared here.

   CLASS-SUFFIX CHECK, done deliberately (this trap has produced seven defects in this campaign): none of the
   names below ends in a shared family suffix. `-planrole` and `-plannote` end in "role"/"note" with no hyphen
   before them, so neither joins the [class$="-note"] family; `-kindfield` / `-searchfield` / `-pickfield` /
   `-rolefield` / `-notefield` end in "field" with no hyphen, exactly as the four plan fields above already do,
   so none joins [class$="-field"]; `-addrow` is not `-add`; and `-entity-find` is not a family at all. The
   buttons keep their kl-btn class, which is where their 44px floor comes from. */

/* The role, beside the name. Quiet: it qualifies the involvement, it is not the involvement. */
.kl-tpl-planrole[b-leafuad94h] {
    flex: 0 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 13px;
    color: var(--k-text-muted);
}

/* The author's own qualifier, under the head row. Same voice as .kf-hint, no extra top gap (the row's own
   column gap already separates it). */
.kl-tpl-plannote[b-leafuad94h] {
    margin: 0;
}

/* The composer. Centred like .kl-tpl-plan-addrow and for the same measured reason: a kf-field's family rule
   carries margin-block-end 16px, so an end-aligned row would meet the bottom of the field's MARGIN box and sit
   the button 16px low. Every child can shrink to a zero basis, so the row wraps rather than widening the pane. */
.kl-tpl-entity-addrow[b-leafuad94h] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--k-space-2);
    min-inline-size: 0;
}

.kl-tpl-entity-kindfield[b-leafuad94h],
.kl-tpl-entity-rolefield[b-leafuad94h] {
    flex: 1 1 9rem;
    min-inline-size: 0;
    margin-block-end: 0;
}

.kl-tpl-entity-searchfield[b-leafuad94h],
.kl-tpl-entity-pickfield[b-leafuad94h],
.kl-tpl-entity-notefield[b-leafuad94h] {
    flex: 2 1 12rem;
    min-inline-size: 0;
    margin-block-end: 0;
}

/* A6 - the search button is a real target and never shrinks below one. */
.kl-tpl-entity-find[b-leafuad94h] {
    flex: 0 0 auto;
    min-block-size: var(--k-touch);
}

/* ONE ROW THAT ALIGNS (owner 2026-09-12: "Add planned find" centred 16px below its box). The box was wrapped in a
   kf-field — whose shared family rule carries margin-block-end 16px — and this row aligned flex-end, so the button
   met the bottom of the field's MARGIN box, 16px under the control. The wrapper is now a plain flex child with no
   margin and the row centres, exactly as the terrain and distraction rows already did; nothing is nudged. */
.kl-tpl-plan-addrow[b-leafuad94h] {
    align-items: center;
}

.kl-tpl-plan-pick[b-leafuad94h] {
    /* 10rem basis (2026-09-12): with the add row now wrapping, 14rem pushed the button under the box at 393 and 375
       where it used to fit; 10rem keeps one line down to 375 and wraps only at 320. */
    flex: 1 1 10rem;
    min-inline-size: 0;
}

html.dark .kl-tpl-planchip[b-leafuad94h] {
    background: color-mix(in srgb, var(--k-teal-400) 20%, var(--k-surface-3));
    border-color: color-mix(in srgb, var(--k-teal-400) 48%, transparent);
}

html[data-outdoor="true"] .kl-tpl-planrow[b-leafuad94h],
html[data-outdoor="true"] .kl-tpl-planchip[b-leafuad94h] {
    border-width: 2px;
    border-color: var(--k-outline);
}

/* ---- DESIGN PASS 2026-09-12: two layout bands, placed AFTER the base .kl-tpl-listcard / .kl-tpl-rows rules on
   purpose. @media adds no specificity, so a band declared above those base rules loses to them on source order
   (measured: the two-column band was inert at 768 until it moved here). ---- */

/* DESIGN PASS 2026-09-12 - the list TRAVELS with the reader at two-pane widths. The editor is a long form
   (1,260px at 1400x1000) beside a list that is 770px tall, so a reader who scrolled down to the planned finds
   lost the list entirely and the empty column under it was the page's most visible feature. Sticky keeps the
   'browsing shapes | editing one' relationship on screen for the whole scroll. It consumes the shared sticky-
   offset contract (--k-sticky-top, kanine-design-system.css P4) so it never slides under a pinned top bar, and
   the card's own overflow-y (declared on .kl-tpl-listcard) keeps a long list scrollable inside it. Two-pane
   widths only: below 56rem the list is above the editor and sticking it would cover the form. */
/* LAYOUT RETHINK 2026-09-12: the sticky unit is the whole left COLUMN (picker + list + create card), not the list
   card alone, so the create card travels with the reader too. The column is capped to the viewport and is a flex
   column, so the LIST is the item that gives way — flex:1 with min-block-size:0 lets it shrink below its content and
   its own overflow-y (declared on .kl-tpl-listcard) scrolls the rows inside it — while the create card keeps its
   size. That is what puts the create actions on screen for the whole length of the form: the column's bottom edge
   never leaves the viewport, and the create card is its last child.
   THE BUDGET IS 12rem, NOT --k-space-12, AND THAT IS MEASURED. A sticky element's max-height is resolved from its
   own top, and on ARRIVAL that top is the page header's foot (y=165 at 1400x900), not the pinned offset of 24px.
   With a 48px budget the column ran to y=1017 in a 900px viewport and the create card's primary sat at y=953 —
   below the fold on the one screen the reader arrives at. 12rem (192px) covers the header on arrival with room to
   spare, and it is the same budget .kl-tpl-listcard has carried for its own scroll since the two-pane was built, so
   there is one number for "how much of the viewport the column may take", not two. */
@media (min-width: 56.0625rem) {
    .kl-tpl-side[b-leafuad94h] {
        position: sticky;
        inset-block-start: calc(var(--k-sticky-top) + var(--k-space-6));
        max-block-size: calc(100vh - var(--k-sticky-top) - 12rem);
    }

    .kl-tpl-listcard[b-leafuad94h] {
        flex: 1 1 auto;
        min-block-size: 0;
        max-block-size: none;
    }

    .kl-tpl-createcard[b-leafuad94h] {
        flex: 0 0 auto;
    }
}

/* DESIGN PASS 2026-09-12 - the one-column band (641px to 56rem: tablets, half-screen windows). Here the list
   sits ABOVE the editor, and six 100px cards stacked full-width put the editor 700px down the page before a
   reader saw a single field. Two card columns halve that while every card keeps at least the 316px width it
   has beside the editor at desktop, so nothing truncates harder than it already did. The <li> is still the
   -row family member and the <button> still fills it: only the <ul>'s layout changes. Below 641px the card is
   replaced by the picker, so this band never reaches a phone. */
@media (min-width: 40.0625rem) and (max-width: 56rem) {
    .kl-tpl-rows[b-leafuad94h] {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--k-space-2);
    }
}


/* DESIGN PASS 2026-09-12 - one rhythm for the editor's sections. Before, the gap between blocks was the sum of
   whatever bottom margin each block happened to carry (taxonomy 16px, group row 8px, hint row 16px, chips 8px),
   so no two section boundaries were the same height. Every boundary is now the SAME hairline and padding.
   It is a BOTTOM rule on the section that ends, not a top rule on the one that starts, because three of the
   sections are <fieldset>s and a fieldset draws its top border through the vertical middle of its <legend> -
   measured on the first cut, "Default terrain ---" rendered as a struck-through heading. A bottom border is
   drawn normally. The group hint row closes the group section (its two fields sit above it), so it carries the
   rule and .kl-tpl-grouprow does not; the notes field is last and carries none.
   Placed here, after .kl-tpl-chipset and .kl-tpl-taxonomy reset `border: 0`, so this wins on source order. */
.kl-tpl-editor-body > .kl-tpl-taxonomy[b-leafuad94h],
.kl-tpl-editor-body > .kl-tpl-grouphintrow[b-leafuad94h],
.kl-tpl-editor-body > .kl-tpl-chipset[b-leafuad94h] {
    border-block-end: 1px solid var(--k-border);
    padding-block-end: var(--k-space-4);
}

/* ---- OWNER RULING 2026-09-12: the template group OWNS the record type + subtype ----------------
   A grouped template shows both READ-ONLY and carries the route to changing them at group level.
   Every control below keeps the full A6 touch floor in BOTH dimensions and every box WRAPS rather
   than scrolls, so 320 / 375 / 393 / 430 produce no horizontal overflow (measured, all four).
   The inherited value is styled as INK, not as a disabled input: a disabled input says "you may not
   type here yet", which is a different fact from "this belongs to the group". */
.kl-tpl-subtype--inherited[b-leafuad94h] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--k-space-1);
}

.kl-tpl-inheritedvalue[b-leafuad94h] {
    margin: 0;
    font-weight: 600;
    line-height: 1.4;
    color: var(--k-text);
    /* A long subtype name breaks inside the word rather than widening the pane. */
    overflow-wrap: anywhere;
}

.kl-tpl-groupretype[b-leafuad94h],
.kl-tpl-groupjoinbtn[b-leafuad94h] {
    min-block-size: var(--k-touch);
    min-inline-size: var(--k-touch);
}

.kl-tpl-groupretyperow[b-leafuad94h],
.kl-tpl-groupjoinask-actions[b-leafuad94h] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    margin-block-start: var(--k-space-2);
}

/* The ASK. role="alert", so it is announced; the border and tint are the same quiet in-editor
   treatment the other notices use, never a modal - a modal would make an ordinary, reversible edit
   feel like a hazard. */
.kl-tpl-groupjoinask[b-leafuad94h] {
    margin-block: var(--k-space-2);
    padding: var(--k-space-2) var(--k-space-3);
    border: 1px solid var(--k-border);
    border-inline-start-width: 3px;
    border-radius: 6px;
    background: var(--k-surface-2);
}

.kl-tpl-groupjoinask-text[b-leafuad94h] {
    margin: 0;
    line-height: 1.45;
    color: var(--k-text);
    overflow-wrap: anywhere;
}
/* _content/Kanine.Web/Components/Pages/TenantSettings.razor.rz.scp.css */
/* Scoped layout for the Agency-settings page: a sticky in-page nav RAIL (left) + the sections column (right), the
   rail's grouping + real active state, and the page's own "one address fills the rest" affordances. These layout
   primitives are page-local (each settings-style page defines its own scoped equivalent; OrgUnits is the precedent).
   DARK-MODE-safe BY CONSTRUCTION: only flipping tokens (--k-surface-2 / --k-border / --k-text / --k-text-muted /
   --k-accent), NEVER --k-space-5 / --k-space-7 (undefined) or the phantom Material-3 names that don't flip. */

.kl-split[b-qnq2effl5m] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-6);
}
/* ⚠ The ≤900px overrides for this page live at the BOTTOM of this file, not here. See the block at the end and the
   note with it: @media adds NO specificity, so an override written above the rule it means to beat simply loses to
   source order. That is not a style preference — it is the bug that made twelve controls on this page unreachable
   on a phone. */

/* ── Page header ────────────────────────────────────────────────────────────────────────────────────────────── */
/* Title + one-line explainer on the left, the save controls on the right; they stack before they collide. */
.kl-settings-topbar[b-qnq2effl5m] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--k-space-3) var(--k-space-6);
}
.kl-settings-title[b-qnq2effl5m] { min-inline-size: 0; }
.kl-settings-title h1[b-qnq2effl5m] { margin-block-end: var(--k-space-2); }

/* The explainer under a heading — page-level and per-section. One measure (~68ch) so a wide monitor doesn't
   stretch it into an unreadable single line; the cards themselves are free to run full width. */
.kl-settings-lede[b-qnq2effl5m] {
    margin: 0 0 var(--k-space-4);
    max-inline-size: 68ch;
    color: var(--k-text-muted);
    font-size: 14px;
    line-height: 1.55;
}
.kl-settings-title .kl-settings-lede[b-qnq2effl5m] { margin-block-end: 0; }

/* The unsaved marker sits with the save controls, not floating: it explains what the button beside it will do. */
.kl-settings-dirty[b-qnq2effl5m] { align-self: center; }

/* ── The section rail ───────────────────────────────────────────────────────────────────────────────────────── */
.kl-settings-nav[b-qnq2effl5m] {
    position: sticky;
    top: var(--k-space-4);
    flex: 0 0 15rem;
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-3) var(--k-space-2);
    /* A sticky rail taller than the viewport pins its top and hides its tail until the page's very end. With twelve
       links (2026-09-10) the rail measured 940px in a 900px window, so the last two links were unreachable while
       stuck. The cap keeps the rail inside the viewport on any screen; the rail scrolls within itself if it must. */
    max-block-size: calc(100dvh - (var(--k-space-4) * 2));
    overflow-y: auto;
}
.kl-settings-nav ul[b-qnq2effl5m] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* Group label. Encodes who the group is ABOUT (your agency / people / the record trail) — the one structural
   device on this page, and it earns its place: eight flat labels made an admin read all eight to find one. */
.kl-settings-nav__eyebrow[b-qnq2effl5m] {
    margin: var(--k-space-4) 0 var(--k-space-1);
    padding-inline: var(--k-space-3);
    color: var(--k-text-muted);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.kl-settings-nav__eyebrow:first-child[b-qnq2effl5m] { margin-block-start: 0; }

.kl-settings-nav__item[b-qnq2effl5m] {
    /* UI-GUAR-036 (R2-25): the in-page settings nav links are ≥44 CSS-px touch targets (were ~36). */
    display: flex;
    align-items: center;
    min-block-size: var(--k-touch);
    /* Block padding 0 (was --k-space-2): with min-block-size already at the 48px floor, 8px of padding above and
       below made every link a 64px row and twelve of them a 940px rail. The hit area is still 48px (A6 holds), and
       a long localised label still grows the row because the floor is a minimum, not a height. */
    padding: 0 var(--k-space-3);
    border-radius: var(--k-radius-sm);
    border-left: 3px solid transparent;
    color: var(--k-text-muted);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    transition: background var(--k-dur-2) var(--k-ease), color var(--k-dur-2) var(--k-ease),
                border-color var(--k-dur-2) var(--k-ease);
}
.kl-settings-nav__item:hover[b-qnq2effl5m],
.kl-settings-nav__item:focus-visible[b-qnq2effl5m] {
    color: var(--k-text);
    background: color-mix(in srgb, var(--k-text-muted) 8%, var(--k-surface));
}
/* A REAL active state (2026-07-22): kanine-section-spy.js moves this class as sections pass reading position.
   (The 2026-07-02 note stands — the class it replaced was hardcoded on one item and never moved.) */
.kl-settings-nav__item--active[b-qnq2effl5m] {
    color: var(--k-text);
    border-left-color: var(--k-accent);
    background: color-mix(in srgb, var(--k-accent) 10%, var(--k-surface));
}
/* ── The phone section picker (≤900px) ──────────────────────────────────────────────────────────────────────────
   The collapsed form of the rail. Hidden here and TURNED ON in the ≤900px block at the bottom of this file — the
   `display` pair is the one declaration whose outcome depends on source order, so it is the one that must be
   written base-first, override-last (see the note on that block). Everything below is unconditional: it only
   describes a control that desktop never shows.

   Named with BEM `__` segments on purpose. The shared sheet carries 117 `[class$="-…"]` suffix rules (trap T7 —
   `-field` once rendered this page's address input 288px tall, and `-banner` cost the Home disclosure 8px of dead
   space); a `__picker` / `__sections` / `__picker-text` ending matches none of them. */
.kl-settings-nav__picker[b-qnq2effl5m] { display: none; }
.kl-settings-nav__picker-chevron[b-qnq2effl5m] { transition: transform var(--k-dur-2) var(--k-ease); }

@media (prefers-reduced-motion: reduce) {
    .kl-settings-nav__item[b-qnq2effl5m],
    .kl-settings-nav__picker-chevron[b-qnq2effl5m] { transition: none; }
}

/* The quiet region placeholder while the settings hydrate (a slow read is NOT a failure). */
.kl-settings-loading[b-qnq2effl5m] {
    margin: var(--k-space-4) 0 0;
    color: var(--k-text-muted);
    font-size: 14px;
}

.kl-settings-main[b-qnq2effl5m] {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-6);
}

/* ── Address entry + autofill ───────────────────────────────────────────────────────────────────────────────── */
/* The address field and its lookup button read as one control: type, press, done.
   ⚠ flex-direction and margin-block-end are RE-DECLARED here on purpose (owner report 2026-07-24: "the agency
   address entry box is massive"). The shared design system carries
       .kf-field, .kl-shell-main [class$="-field"], .kl-shell-main [class$="-field-wide"] {
           display:flex; flex-direction:column; gap:var(--kf-field-gap); margin-block-end:var(--k-space-4); … }
   (kanine-design-system.css:272-276). That attribute selector matches on the class STRING ENDING, so this
   wrapper — named "kl-settings-inline-field" — is swept up by the label-over-control field family even though it
   is the one *-field in the app that is deliberately a ROW. The inherited flex-direction:column then re-read the
   `flex: 1 1 18rem` basis below on the BLOCK axis, so a single-line <input> rendered 288px (18rem) tall with the
   lookup button stacked under it. This is a SIZING defect only — the control is, and stays, a one-line <input>;
   nothing about the stored address shape changes. The shared selector is the real bug and is reported separately
   (it is under concurrent edit and must not be touched from here); the ancestor qualifier below simply out-
   specifies it (0,3,0 vs 0,2,0) so this page is correct whatever the link order. */
.kl-shell-main .kl-settings-inline-field[b-qnq2effl5m] {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--k-space-3);
    align-items: center;
    /* The row is a child INSIDE .kf-field, which already owns the field rhythm — the swept-in field margin was
       stacking a second one under the control. */
    margin-block-end: 0;
}
/* Row basis: the input takes the remaining width beside the button and wraps below 18rem. Block size comes from
   .kf-input's own min-block-size (48px ≥ the 44px WCAG 2.5.8 floor) — never clamped here. */
.kl-shell-main .kl-settings-inline-field .kf-input[b-qnq2effl5m] { flex: 1 1 18rem; min-inline-size: 0; }

/* The receipt for an address lookup: every field it filled, named in plain language, with one Undo. Accent-tinted
   rather than success-green — this is work waiting to be saved, not work that has been saved. */
.kl-settings-autofill[b-qnq2effl5m] {
    margin-block-start: var(--k-space-3);
    padding: var(--k-space-3) var(--k-space-4);
    border: 1px solid color-mix(in srgb, var(--k-accent) 35%, var(--k-border));
    border-left-width: 3px;
    border-radius: var(--k-radius-md);
    background: color-mix(in srgb, var(--k-accent) 6%, var(--k-surface));
}
.kl-settings-autofill__head[b-qnq2effl5m] {
    margin: 0 0 var(--k-space-2);
    color: var(--k-text);
    font-size: 14px;
    font-weight: 600;
}
.kl-settings-autofill__list[b-qnq2effl5m] {
    margin: 0;
    padding-inline-start: var(--k-space-4);
    color: var(--k-text);
    font-size: 14px;
    line-height: 1.7;
}
.kl-settings-autofill__foot[b-qnq2effl5m] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-2);
    margin-block-start: var(--k-space-2);
}
.kl-settings-autofill__foot .kf-hint[b-qnq2effl5m] { margin: 0; }

/* ── Collapsed detail ───────────────────────────────────────────────────────────────────────────────────────── */
/* The hand-entry coordinate fields. Present and reachable, but folded away: the address above fills all three, so
   for most agencies this never needs opening. */
.kl-settings-advanced[b-qnq2effl5m] {
    margin-block-start: var(--k-space-4);
    border-block-start: 1px solid var(--k-border);
    padding-block-start: var(--k-space-3);
}
/* ONE row, one affordance (owner ruling 2026-09-11). It used to hold a bold title AND a muted hint, which wrapped
   to a second line at narrow widths and read as a heading with a subtitle. `flex-wrap` went with the hint: the label
   is one flex item now, so it wraps INSIDE itself and the chevron stays on the row. */
.kl-settings-advanced__summary[b-qnq2effl5m] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    min-block-size: var(--k-touch);
    color: var(--k-text);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    /* `display: flex` on a <summary> already suppresses the native marker in Chromium — say so explicitly, so the
       chevron below is the ONE indicator in every engine rather than a second one beside a triangle. */
    list-style: none;
}
.kl-settings-advanced__summary[b-qnq2effl5m]::-webkit-details-marker { display: none; }
.kl-settings-advanced__summary:focus-visible[b-qnq2effl5m] { outline: 2px solid var(--k-accent); outline-offset: 2px; }
.kl-settings-advanced__label[b-qnq2effl5m] { min-inline-size: 0; }
.kl-settings-advanced__chevron[b-qnq2effl5m] {
    margin-inline-start: auto;
    color: var(--k-text-muted);
    transition: transform var(--k-dur-2) var(--k-ease);
}
.kl-settings-advanced[open] .kl-settings-advanced__chevron[b-qnq2effl5m] { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
    .kl-settings-advanced__chevron[b-qnq2effl5m] { transition: none; }
}
.kl-settings-advanced[open] .kl-settings-advanced__summary[b-qnq2effl5m] { margin-block-end: var(--k-space-3); }

/* ── Pointer cards (Sign-in & security, Identity provider, License) ─────────────────────────────────────────── */
/* The links out to the page that really manages a thing. The foundation right-aligns anything whose last class
   ends in "-actions"; under body copy these read as a next step, so the compound selector wins them back to the
   start edge (0,3,0 beats the foundation's 0,2,0 — no order dependency). */
.kl-settings-main .kl-settings-pointer-actions[b-qnq2effl5m] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: var(--k-space-3);
    margin-block-start: var(--k-space-4);
}

/* The trailing "what this page can't change" line under a pointer card. Quieter and smaller than the lead
   paragraph — an honest footnote, not the headline. */
.kl-settings-pointer-note[b-qnq2effl5m] {
    margin-block-start: var(--k-space-4);
    margin-block-end: 0;
    max-inline-size: 68ch;
    color: var(--k-text-muted);
    font-size: 13px;
}

/* ── WX-KEY-001: the agency weather-service key (self-host / air-gapped only) ───────────────────────────────── */
/* The status line ("Current status · Configured"). Was `kl-weatherkey-row`, renamed 2026-09-10 (trap T7): with the
   attribute ending in "-row" it was swept into the shared `[class$="-row"]` family and drew a padded, bordered box
   around two words, which read as a disabled input. Ending in "-line" matches no family, so the row layout now
   comes from `.kl-settings-inline-field` alone and only the rhythm below is local. */
.kl-settings-main .kl-weatherkey-line[b-qnq2effl5m] {
    margin-block-end: var(--k-space-3);
}

/* Save + Remove are the trailing edge of the KEY INPUT'S OWN ROW (owner ruling 2026-07-25 — a single control never
   owns a band on its own). `.kl-weatherkey-actions`, the strip that used to hold them under the input, is RETIRED
   with the markup that carried it; the buttons are now children of `.kl-settings-inline-field`, which already lays
   an input + its button out as one row (and gives the input `flex: 1 1 18rem`, so the buttons keep their content
   width and the input absorbs the rest). Nothing needed here beyond the field's own margin: the row IS the field's
   last line, and `.kf-field`'s gap supplies the space above it. */
.kl-settings-main .kl-weatherkey-entry[b-qnq2effl5m] {
    /* The `.kl-settings-inline-field` base centres its items; the buttons and the input are the same 48px tall, so
       this only matters if a validation message ever lands inline. Declared for intent, not to change today's box. */
    align-items: center;
}

/* ── Card rhythm and hierarchy (look-and-feel pass, 2026-09-10) ─────────────────────────────────────────────── */
/* The column's own gap (--k-space-6) IS the rhythm between cards. The shared card family also carries a 16px
   bottom margin, and a flex gap never collapses with a margin, so every seam was paying 40px. Twelve seams, 192px. */
.kl-settings-main > .kl-card[b-qnq2effl5m] { margin-block-end: 0; }

/* Card titles sit one step above the helper text. This page reached 18px on its own when the shared
   -section-title family was still 16px — the SAME size as the (then unstyled) hints beneath it. §5a is 18px
   for every head in the product since 2026-09-15, so the page copy is deleted and this page keeps the size it
   already had. */

/* The sub-heading inside a card ("When reminders go out", "Agency letterhead"). Written ONCE here, reaching the child
   components with ::deep: two children carried identical scoped copies of this rule and three had none, so
   "Completion requirements" rendered as a browser-default h3 with 19px margins. A shared-sheet rule was considered and
   NOT written — DogDetail's scoped copy is a different shape (flex, 0.95rem, a 16px top margin) and would have been
   out-specified by it. (0,2,1) here beats a child's scoped (0,1,1) on every declaration. */
.kl-settings-main[b-qnq2effl5m]  .kl-section-subtitle {
    display: block;
    font-family: var(--k-font-display);
    font-size: 14px;
    font-weight: 700;
    line-height: 1.3;
    margin: 0 0 var(--k-space-2);
    color: var(--k-text);
}

/* The two-button choice rows (dev support, email). Replaces an inline style. Ends in "-choice": no shared family
   keys on that suffix (checked against the 117 [class$="…"] rules, trap T7). */
.kl-settings-choice[b-qnq2effl5m] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-3);
}

/* The weather-key block sits under the map-point disclosure inside the same card. The disclosure draws a rule above
   itself; this block did not, so the two read as one run. Ends in "-weatherkey": no shared family. */
.kl-settings-weatherkey[b-qnq2effl5m] {
    margin-block-start: var(--k-space-4);
    border-block-start: 1px solid var(--k-border);
    padding-block-start: var(--k-space-4);
}

/* ── The toggle rows, written ONCE for all three child sections (::deep) ─────────────────────────────────────────
   Reminders, Completing a record and Report letterhead all render the same control: a bordered row with a checkbox
   and its words on the left and, on two of them, a small badge on the right. Before 2026-09-10 the rules lived in
   TWO of the three children's scoped sheets and Records had none — so on Records the row fell through to the shared
   `-row` family, its label to the `-label` family (13px, bold, muted: it looked like a field caption) and its badge,
   whose class attribute ends in "k-mono", to nothing at all (16px mono body text). Same control, three renderings,
   one screen. (0,3,0) here out-specifies every shared suffix family at (0,2,0). */
.kl-settings-main[b-qnq2effl5m]  .kl-toggle-list {
    list-style: none;
    margin: var(--k-space-2) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--k-space-2);
}
.kl-settings-main[b-qnq2effl5m]  .kl-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
    /* border-box, so the 48px floor INCLUDES the padding and border: measured content-box first, and every row
       came out 66px. 48 is still up from the 44px these rows were before (A6: never down). */
    box-sizing: border-box;
    min-block-size: var(--k-touch);
    margin: 0;
    padding: var(--k-space-2) var(--k-space-3);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-sm);
    background: var(--k-surface-2);
}
/* Report letterhead's rows are bare <label>s with no list around them: they space themselves. */
.kl-settings-main[b-qnq2effl5m]  label.kl-toggle-row {
    cursor: pointer;
    margin-block-start: var(--k-space-2);
}
.kl-settings-main[b-qnq2effl5m]  .kl-toggle-label {
    display: inline-flex;
    align-items: center;
    /* The label is the hit target on the list rows (the checkbox is inside it). Stretched to the row's height so
       the whole 48px band toggles, not just the text line. */
    align-self: stretch;
    gap: var(--k-space-3);
    box-sizing: border-box;
    font-size: 14px;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--k-text);
    cursor: pointer;
}
/* ── §A6 — THE HIT TARGET IS THE <label>, NOT THE ROW (fixed 2026-09-11) ────────────────────────────────────────
   `align-self: stretch` above stretches the label into the row's CONTENT box, and the row's own
   `padding: var(--k-space-2) var(--k-space-3)` plus its 1px border sit OUTSIDE that box. So the comment above was
   the intent and not the result: on a 48px row the label measured 30px tall, and the 9px band above and below it
   was dead — a finger landing there toggled nothing. MEASURED on the live host before this change, at 1400 and at
   768: `records-require-deployment-case-number` 475.7x30, `records-allow-self-supervisor` 456.7x30,
   `feedback-enabled` 371x30, the four Reminders leads 111-154 x 30. §A6 floor is var(--k-touch) = 48px.

   THE FIX MOVES THE PADDING, IT DOES NOT ADD HEIGHT. The block padding comes OFF the <li> and goes ON the <label>,
   so the label now fills the whole band and the row's painted height is unchanged wherever the label already
   wrapped past 48px (every phone width). Only a single-line row grows, by the 2px of border the label cannot
   occupy: 48px -> 50px.

   WHY `li.` AND `label.` AND NOT THE BARE CLASSES. Report letterhead spells the same control the other way round —
   `<label class="kl-toggle-row">` with a `<span class="kl-toggle-label">` inside — so THERE the label already IS
   the 48px row and is already conformant. That, not a cascade fight, is the whole reason two of the page's toggles
   measured 48px and the other seven measured 30px: same class names, different element carrying them. Keying these
   two rules to the element keeps the letterhead rows exactly as they are.
   Both selectors are (0,3,1) here, out-specifying the (0,3,0) base rules above. */
.kl-settings-main[b-qnq2effl5m]  li.kl-toggle-row { padding-block: 0; }
.kl-settings-main[b-qnq2effl5m]  label.kl-toggle-label {
    min-block-size: var(--k-touch);
    padding-block: var(--k-space-2);
}

/* The checkbox never shrinks beside a long label: measured at 393px, a flex-shrink of 1 squeezed the 18px box to
   13px on the two Completing-a-record rows. The words wrap instead. */
.kl-settings-main[b-qnq2effl5m]  .kl-toggle-label > .kf-checkbox { flex: 0 0 auto; }
.kl-settings-main[b-qnq2effl5m]  .kl-toggle-badge {
    padding: 2px var(--k-space-2);
    border-radius: var(--k-radius-sm);
    background: var(--k-surface-3);
    color: var(--k-text-muted);
    font-size: 13px;
    white-space: nowrap;
}

/* ── Narrow layout (≤900px) — MUST BE LAST IN THIS FILE ─────────────────────────────────────────────────────────
   SEV-1 fix, 2026-07-24. This block used to sit at the top, immediately after `.kl-split`. `@media` contributes
   NOTHING to specificity, so `@media(max-width:900px){ .kl-settings-nav{position:static} }` written ABOVE the base
   `.kl-settings-nav{position:sticky}` lost the cascade on source order — at every width, including 393px.

   What that cost: the rail computed `position:sticky` at 708px tall in an 852px viewport, so it pinned itself over
   the whole form. A live sweep of 18 scroll offsets found `document.elementFromPoint` returning
   `a.kl-settings-nav__item` at the centre of TWELVE controls — the agency address input, unit system, temperature
   unit, the time-zone select, the weather-service key input, "Use this address", "Test the key" and four reminder
   lead checkboxes. Every one of them was in the DOM, focusable, and completely untouchable on a phone. This is the
   page the setup checklist sends an admin to in order to set the agency address and time zone.

   The fix is ORDER, deliberately not specificity: the intent was always "static below 900px", and the right way to
   express it is to declare it after the rule it overrides. Raising specificity would win the same fight while
   leaving the trap armed for the next override someone adds. Keep this block last. */
@media (max-width: 900px) {
    /* align-items:stretch (overriding the desktop flex-start) so the settings-main column spans 100% — otherwise it
       shrink-wraps its form grid (~732px) and forces page overflow (the live sweep measured documentElement 798>320). */
    .kl-split[b-qnq2effl5m] { flex-direction: column; align-items: stretch; }
    .kl-settings-nav[b-qnq2effl5m] { position: static; flex-basis: auto; align-self: stretch; }
    .kl-settings-main[b-qnq2effl5m] { inline-size: 100%; max-inline-size: 100%; min-inline-size: 0; }

    /* ── The section picker ───────────────────────────────────────────────────────────────────────────────────
       In flow and 708px tall, the rail cost a phone user a whole screen before the first setting: MEASURED at
       393x852, nav y=266 h=708, first form control (the agency address) y=1183 — 1.39 screens down, on the page
       the setup checklist sends an admin to in order to type that address. Collapsed to one row it is ~74px, so
       the address arrives on the first screen. Nothing is deleted and nothing shrinks: all nine links keep their
       elements, hrefs, data-testids and their 64px hit area, one tap away.

       Deliberately IN FLOW, not an overlay. A rail that paints over this form is exactly the severity-1 that was
       fixed hours ago (position:sticky at 708px made twelve controls untouchable at every scroll offset); an
       expanded picker pushes the form down instead, and the page re-anchors after a pick. */
    .kl-settings-nav__picker[b-qnq2effl5m] {
        display: flex;
        align-items: center;
        gap: var(--k-space-3);
        inline-size: 100%;
        /* A6/WCAG 2.5.8 — --k-touch (48px) is a FLOOR, not a height: the padding keeps a long localised section
           name growing the row rather than clipping it. */
        min-block-size: var(--k-touch);
        padding: var(--k-space-2) var(--k-space-3);
        margin: 0;
        background: none;
        border: 0;
        border-radius: var(--k-radius-sm);
        font: inherit;
        text-align: start;
        cursor: pointer;
    }
    .kl-settings-nav__picker:focus-visible[b-qnq2effl5m] { outline: 2px solid var(--k-accent); outline-offset: 2px; }
    .kl-settings-nav__picker-text[b-qnq2effl5m] {
        flex: 0 0 auto;
        color: var(--k-text-muted);
        font-size: 11px;
        font-weight: 700;
        letter-spacing: 0.08em;
        text-transform: uppercase;
    }
    /* Where you ARE — the whole reason a collapsed rail is not just a menu button. kanine-section-spy.js keeps
       this in step with the active link as sections pass reading position. */
    .kl-settings-nav__picker-current[b-qnq2effl5m] {
        flex: 1 1 auto;
        min-inline-size: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        color: var(--k-text);
        font-size: 14px;
        font-weight: 600;
    }
    .kl-settings-nav__picker-chevron[b-qnq2effl5m] {
        flex: 0 0 auto;
        color: var(--k-text-muted);
        font-size: 13px;
    }
    .kl-settings-nav__picker[aria-expanded="true"] .kl-settings-nav__picker-chevron[b-qnq2effl5m] { transform: rotate(90deg); }

    /* Collapsed: genuinely hidden, which is the correct semantic for aria-expanded="false" — content promised
       hidden must not stay reachable by keyboard or screen reader. */
    .kl-settings-nav[data-expanded="false"] .kl-settings-nav__sections[b-qnq2effl5m] { display: none; }
    /* Open, the list sits under the row it belongs to rather than pretending to be a separate card. */
    .kl-settings-nav[data-expanded="true"] .kl-settings-nav__sections[b-qnq2effl5m] { margin-block-start: var(--k-space-2); }
}

/* ── Phone (≤640px) — MUST STAY AFTER the ≤900px block above, for the same source-order reason it documents ──
   The weather-key row (input + Save [+ Remove]) is a wrapping flex row, and flex decides LINE BREAKS from each
   item's flex BASIS, not from the size it could shrink to. At 390px the card leaves 310px and the base
   `.kl-settings-inline-field .kf-input` basis is 18rem (288px), so 288 + 12 + 85 overflowed the line and the Save
   button wrapped BELOW the input — re-creating, on the phone, the exact band the desk fix had just removed
   (MEASURED: the field went 480px → 484px at 390 before this rule, and → 424px after).

   Only the BASIS moves. `flex-grow: 1` (inherited from the base rule) still fills the line, so the input renders
   ~213px wide here — it is not being shrunk to a smaller control, it is being told to start smaller and grow. The
   48px min-block-size of `.kf-input` and the buttons' ≥44px targets are untouched. */
@media (max-width: 640px) {
    .kl-settings-main .kl-weatherkey-entry .kf-input[b-qnq2effl5m] { flex-basis: 7rem; }
}
/* _content/Kanine.Web/Components/Pages/TenantSettingsSections/TenantSettingsCobranding.razor.rz.scp.css */
/* RPT-028 — Tenant-settings #cobranding section styling (component-scoped). Dark-mode-safe tokens only
   (--k-text/--k-text-muted/--k-surface/--k-surface-2/--k-border/--k-accent) — never phantom Material-3 names. */

/* .kl-section-subtitle is styled ONCE by the parent page (TenantSettings.razor.css, `::deep`), which reaches every
   child section. The identical copy that lived here was one of two; three sibling sections had none. */

/* The toggle rows (.kl-toggle-row / -label) are styled once by the parent page with ::deep — the same rule set
   Reminders and Completing a record render with. The copy that lived here was retired 2026-09-10. */

/* The DEFERRED agency-seal drop-zone: a visually-distinct disabled affordance (object store unprovisioned). */
.kl-dropzone[b-h0isn0m93h] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--k-space-1);
    text-align: center;
    padding: var(--k-space-4);
    border: 2px dashed var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
}

/* No `opacity` here: it multiplied into the title and the hint and cut them to 3.7:1 (light) and 4.05:1 (dark).
   The dashed border, the surface-2 fill, the muted ink and the not-allowed cursor already mark it as inactive. */
.kl-dropzone--disabled[b-h0isn0m93h] {
    cursor: not-allowed;
}

.kl-dropzone-title[b-h0isn0m93h] {
    font-weight: 600;
    font-size: 14px;
    color: var(--k-text-muted);
}
/* _content/Kanine.Web/Components/Pages/TenantSettingsSections/TenantSettingsLicense.razor.rz.scp.css */
/* IAM-050 — scoped styles for the Tenant-settings "License & seats" child section. The card box itself comes from the
   foundation [class$="-card"] suffix selector (kl-license ends in "-license", NOT "-card", so the wrapping element
   carries BOTH `kl-card` and `kl-license`; `kl-card` supplies the box). Everything below is the section's own layout.
   DARK-MODE: only the flipping semantic tokens are used (--k-text/--k-text-muted/--k-surface-2/--k-border/--k-accent +
   the --k-success/caution/critical status hues mixed onto --k-surface); NO --k-ink-* / --k-on-surface* / --k-surface-variant
   (phantom/non-flipping), NO --k-space-5 (undefined). */

.kl-license-head[b-dnd5rnjnmb] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--k-space-3);
    flex-wrap: wrap;
}
.kl-license-readonly-chip[b-dnd5rnjnmb] {
    flex: 0 1 auto;
    min-width: 0;
}
.kl-license-intro[b-dnd5rnjnmb] {
    color: var(--k-text-muted);
    margin-block: var(--k-space-2) var(--k-space-4);
    max-inline-size: 64ch;
}

/* Three equal cardlets, responsive. minmax 13rem (was 15rem): at the page's 718px card width, 15rem fitted only two
   columns, so the third cardlet dropped to a second row beside an empty cell — measured 2026-09-10, the License card
   was 1,326px tall for three small read-only groups. 3 × 13rem + 2 gaps = 656px, so all three share one row on a
   desk and still stack one-up on a phone. */
.kl-license-grid[b-dnd5rnjnmb] {
    display: grid;
    gap: var(--k-space-4);
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.kl-license-cardlet[b-dnd5rnjnmb] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    background: var(--k-surface-2);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-6);
}
.kl-license-cardlet-title[b-dnd5rnjnmb] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    font-family: var(--k-font-display);
    font-size: 14px;
    font-weight: 700;
    line-height: 1.25;
    margin: 0;
    color: var(--k-text);
}

/* A quiet "Derived" marker chip on the projector-owned cards. Uses ONLY flipping tokens (the bare foundation .kl-chip
   base hard-codes a fixed light gray that does NOT flip → a bright pill on the dark canvas, an R11 design-skeptic
   BLOCKER). A muted neutral tint legible in light + dark + outdoor. */
.kl-license-derived-chip[b-dnd5rnjnmb] {
    font-size: 10px;
    letter-spacing: .04em;
    text-transform: uppercase;
    padding: 1px 8px;
    color: var(--k-text-muted);
    background: color-mix(in srgb, var(--k-text-muted) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-text-muted) 30%, var(--k-surface));
}

/* The read-only license-type select reads as disabled (muted, not-allowed) but legible in all modes. */
.kl-license-select:disabled[b-dnd5rnjnmb] {
    color: var(--k-text);
    background: var(--k-surface);
    border-color: var(--k-border);
    opacity: 1;            /* don't wash the value out — it is load-bearing hydrated data */
    cursor: not-allowed;
}

/* Small read-only figures (seats / expiry). */
.kl-license-figure-sm[b-dnd5rnjnmb] {
    font-size: 16px;
    color: var(--k-text);
    margin: 0;
    font-variant-numeric: tabular-nums;
}

/* The headline seat figure (47 / 50 seats). */
.kl-license-figure[b-dnd5rnjnmb] {
    display: flex;
    align-items: baseline;
    gap: var(--k-space-2);
    margin: 0;
}
.kl-license-figure-num[b-dnd5rnjnmb] {
    font-family: var(--k-font-display);
    font-size: clamp(28px, 3vw, 36px);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--k-text);
    font-variant-numeric: tabular-nums;
}
.kl-license-figure-denom[b-dnd5rnjnmb] {
    font-size: 14px;
    color: var(--k-text-muted);
}

/* The DERIVED seat-usage meter. The track is a subtle fill; the bar colour tracks the seat status (data-attr on the
   track). Default (ok) = accent teal; soft-warning = caution; full = critical. Dark-mode keeps the SAME saturated hues
   (they are status fills, already legible on dark). */
.kl-license-meter[b-dnd5rnjnmb] {
    block-size: 8px;
    inline-size: 100%;
    border-radius: var(--k-radius-full);
    background: color-mix(in srgb, var(--k-border) 60%, var(--k-surface));
    overflow: hidden;
}
.kl-license-meter-fill[b-dnd5rnjnmb] {
    block-size: 100%;
    border-radius: inherit;
    background: var(--k-accent);
    transition: width var(--k-dur-3) var(--k-ease);
}
.kl-license-meter[data-seat-status="soft-warning"] .kl-license-meter-fill[b-dnd5rnjnmb] {
    background: var(--k-caution);
}
.kl-license-meter[data-seat-status="full"] .kl-license-meter-fill[b-dnd5rnjnmb] {
    background: var(--k-critical);
}

.kl-license-seat-chip[b-dnd5rnjnmb],
.kl-license-state-chip[b-dnd5rnjnmb] {
    align-self: flex-start;
    max-inline-size: 100%;
    /* wrap rather than overhang the cardlet on a long label / narrow column (R11 clip guard). */
    white-space: normal;
    text-align: start;
}

/* §A6 (2026-09-11) — this is a NAVIGATION link that stands on its own line, not a fragment of running prose, so
   the inline-text-link exemption does not cover it. MEASURED on the live host before this change: 214.3x19.5 at
   375/393/430 and 178x39 at 1400 (two lines) — under the var(--k-touch) floor at every width.
   IT STAYS A TEXT LINK. The License card is READ-ONLY in v1 (IAM-051, locked decision 5): it holds no button at
   all, and giving it the page's `.kl-btn kl-btn--ghost` out-link idiom (used on the Security and Retention cards,
   which DO act) would make the one card that cannot act look like it can. `inline-flex` + the floor buys the hit
   area without changing a single painted pixel of the link itself. */
.kl-license-manage[b-dnd5rnjnmb] {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    box-sizing: border-box;
    min-block-size: var(--k-touch);
    font-size: 13px;
    font-weight: 600;
    color: var(--k-accent);
    text-decoration: none;
}
.kl-license-manage:hover[b-dnd5rnjnmb],
.kl-license-manage:focus-visible[b-dnd5rnjnmb] {
    text-decoration: underline;
}

/* Token block sits below a hairline divider. */
.kl-license-token[b-dnd5rnjnmb] {
    margin-block-start: var(--k-space-2);
    padding-block-start: var(--k-space-3);
    border-block-start: 1px solid var(--k-border);
    display: flex;
    flex-direction: column;
    gap: var(--k-space-1);
}
.kl-license-token p[b-dnd5rnjnmb] {
    margin: 0;
}

.kl-license-deferred[b-dnd5rnjnmb] {
    margin-block-start: var(--k-space-4);
}

/* (Retired 2026-09-10: the local `.kl-license .kl-muted, .kl-license .kf-hint { color }` workaround. The foundation
   now carries both — `.kl-shell-main .kl-muted` since 2026-07-24 and `.kl-shell-main .kf-hint` since 2026-09-10 — so
   the copy here would only have been a second thing to keep in step.) */
/* _content/Kanine.Web/Components/Pages/TenantSettingsSections/TenantSettingsReminders.razor.rz.scp.css */
/* OPS-024 — Tenant-settings #reminders section styling (component-scoped). Dark-mode-safe tokens only
   (--k-text/--k-text-muted/--k-surface/--k-surface-2/--k-border/--k-accent) — never phantom Material-3 names. */

/* .kl-section-subtitle is styled ONCE by the parent page (TenantSettings.razor.css, `::deep`), which reaches every
   child section. The identical copy that lived here was one of two; three sibling sections had none. */

/* The toggle rows (.kl-toggle-list / -row / -label / -badge) are ALSO styled once by the parent page with ::deep,
   so this section, Completing a record (which had no sheet) and Report letterhead render the control identically.
   The copy that lived here was retired 2026-09-10. This file is kept so the component's scope attribute still
   exists for any future local rule. */
/* _content/Kanine.Web/Components/Pages/TenantSettingsSections/TenantSettingsRetention.razor.rz.scp.css */
/* SEC-DLC-001 / SEC-DLC-006 — scoped styles for the tenant-settings Retention & disposition section.
   Reuses the global kl-/kf- design-system primitives (kl-card family, kl-banner, kl-chip, kf-select, kf-input,
   kf-textarea, kl-btn, kl-dialog) and adds ONLY the component-local classes.

   THE REDESIGN (owner ask, 2026-07-30). This was a five-column table of bare dropdowns; a records manager was being
   asked to read "1 / case_closure / anonymize" across three adjacent selects. It is now one STACKED CARD per record
   kind, headed by an icon and a sentence about consequences, with the controls as labelled fields beneath. The old
   local copies of .kl-banner / .kf-hint / .kl-empty are gone: the foundation (kanine-design-system.css §5g/§5h)
   defines the whole family, and a second copy here would be a second thing to keep in step.

   DARK-MODE legible by construction: every colour is a design token that flips (--k-text / --k-text-muted /
   --k-surface* / --k-border / --k-accent / --k-success / --k-caution / --k-critical) — never the phantom Material-3
   tokens (--k-on-surface* / --k-ink-*) that do not flip, never an undefined space (--k-space-5).

   TOUCH: every control on a card is a kf-select / kf-input, which the foundation already floors at --k-touch
   (48px). The card itself is not an interactive target and declares no hover, so there is no hover state that could
   fall through to a generic rule — the .kl-btn--seal failure mode (a filled button whose hover repainted the
   background while keeping white text, vanishing at ~1.1:1) cannot recur here. The two buttons this section adds
   are --ghost and --seal, both of which declare their own hover in the foundation, in both themes. */

.kl-retention[b-xr59dyhu1d] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-4);
    color: var(--k-text);
}

/* ── The disposition ENGINE panel (the switch, the dry run, and what the last passes did). ──────────────────────
   Class ends in "-panel" so the foundation's card family (§5a suffix match) supplies the surface, border, radius
   and elevation; only the interior rhythm is local. A left-rule in the accent (a SHAPE cue, never a status-hued
   surface fill — UI-GUAR-027) marks it as the section's control surface rather than one more schedule. */
.kl-retention-engine-panel[b-xr59dyhu1d] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    box-shadow: inset 3px 0 0 0 var(--k-accent);
}

.kl-retention-engine-head[b-xr59dyhu1d] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-3);
    flex-wrap: wrap;
}

.kl-retention-engine-icon[b-xr59dyhu1d] {
    font-size: 1.35rem;
    line-height: 1;
    color: var(--k-accent);
    flex: 0 0 auto;
    margin-top: 2px;
}

.kl-retention-engine-headings[b-xr59dyhu1d] {
    flex: 1 1 16rem;
    min-width: 0;
}

.kl-retention-engine-title[b-xr59dyhu1d] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 1rem;
    font-weight: 700;
    color: var(--k-text);
}

.kl-retention-engine-lede[b-xr59dyhu1d] {
    margin: 2px 0 0;
    font-size: 0.82rem;
    color: var(--k-text-muted);
}

.kl-retention-engine-state-line[b-xr59dyhu1d] {
    margin: 0;
    font-size: 0.88rem;
    color: var(--k-text);
    max-width: 68ch;
}

.kl-retention-engine-actions[b-xr59dyhu1d] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-3);
}

/* ── The dry-run report + the run history (same list rhythm; both are read-only recitals). ── */
.kl-retention-preview[b-xr59dyhu1d],
.kl-retention-history[b-xr59dyhu1d] {
    padding: var(--k-space-3) var(--k-space-4);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
    color: var(--k-text);
}

.kl-retention-preview-title[b-xr59dyhu1d] {
    margin: 0 0 4px;
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--k-text);
}

.kl-retention-preview-list[b-xr59dyhu1d] {
    list-style: none;
    margin: var(--k-space-2) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.kl-retention-preview-list > li[b-xr59dyhu1d] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-2);
    font-size: 0.82rem;
}

.kl-retention-preview-kind[b-xr59dyhu1d] {
    font-weight: 600;
    color: var(--k-text);
    flex: 0 0 10rem;
}

.kl-retention-preview-detail[b-xr59dyhu1d] {
    color: var(--k-text-muted);
    flex: 1 1 16rem;
}

/* ── The eight stacked schedule cards. ──────────────────────────────────────────────────────────────────────── */
.kl-retention-cards[b-xr59dyhu1d] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
}

/* Class ends in "-card", so the foundation's card family styles the surface. The local rules are the interior. */
.kl-retention-kind-card[b-xr59dyhu1d] {
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
    margin-block-end: 0;   /* the list owns the rhythm; the card must not add a second gap */
}

/* A sensitive category is marked by a caution LEFT-RULE — a SHAPE cue, not a status-hued surface fill
   (UI-GUAR-027 / R2-16: no dark SURFACE may carry a status hue). The load-bearing signal is still the chip.
   The rule is DATA: it is drawn only when row.IsSensitive, so it is what distinguishes use-of-force, notifications,
   traffic-data and suspects from the other four kinds. It must never be deleted to fix a layout problem.
   AN INSET SHADOW PAINTS INSIDE THE PADDING BOX, so it needs padding to sit in. The card gets that padding from the
   foundation's card family, which is keyed on the class ATTRIBUTE ending in "-card" — which is why the markup writes
   this modifier BEFORE the base class. See the note in TenantSettingsRetention.razor. */
.kl-retention-kind-card--sensitive[b-xr59dyhu1d] {
    box-shadow: var(--k-elev-1), inset 3px 0 0 0 color-mix(in srgb, var(--k-caution) 55%, transparent);
}

.kl-retention-kind-head[b-xr59dyhu1d] {
    display: flex;
    align-items: flex-start;
    gap: var(--k-space-3);
    flex-wrap: wrap;
}

.kl-retention-kind-icon[b-xr59dyhu1d] {
    font-size: 1.5rem;
    line-height: 1;
    color: var(--k-accent);
    flex: 0 0 auto;
    margin-top: 2px;
}

.kl-retention-kind-headings[b-xr59dyhu1d] {
    flex: 1 1 14rem;
    min-width: 0;
}

.kl-retention-kind-title[b-xr59dyhu1d] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 1rem;
    font-weight: 700;
}

.kl-retention-kind-scope[b-xr59dyhu1d] {
    margin: 2px 0 0;
    font-size: 0.8rem;
    color: var(--k-text-muted);
}

.kl-retention-kind-chips[b-xr59dyhu1d] {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: flex-start;
}

/* The headline sentence — the whole reason the cards exist. Sized up and set in the display face so it reads as the
   card's statement rather than as one more line of small print. */
.kl-retention-sentence[b-xr59dyhu1d] {
    margin: 0;
    font-family: var(--k-font-display);
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.45;
    color: var(--k-text);
    max-width: 56ch;
}

.kl-retention-cat[b-xr59dyhu1d] {
    font-weight: 600;
    color: var(--k-text);
}

/* ── The controls: labelled fields that wrap into a single row on a wide card and stack on a phone. ── */
.kl-retention-controls[b-xr59dyhu1d] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--k-space-3) var(--k-space-4);
    padding-top: var(--k-space-3);
    border-top: 1px solid var(--k-border);
}

/* Basis 8rem (was 10rem). Flex decides LINE BREAKS from each item's basis, and 4 × 10rem + 3 gaps = 688px did not fit
   the 670px card body at the page's desk width, so "Disposal" wrapped onto a row of its own under every one of the
   eight cards (measured 2026-09-10: +~70px per card). 4 × 8rem + 3 gaps = 560px fits; flex-grow still fills the
   line, so nothing renders narrower than before. The ≤640px block below still stacks them one per row. */
.kl-retention-field[b-xr59dyhu1d] {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1 1 8rem;
    min-width: 0;
}

.kl-retention-field .kf-label[b-xr59dyhu1d] {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

.kl-retention-effect[b-xr59dyhu1d] {
    margin: 0;
    max-width: 72ch;
}

/* The recorded-basis marker under a sensitive purge-off select. */
.kl-retention-basis[b-xr59dyhu1d] {
    display: inline-flex;
    align-items: center;
    margin-top: 4px;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--k-caution);
}

/* ── Period input: a narrow number field + a unit suffix on one line. ── */
.kf-inline[b-xr59dyhu1d] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.kf-input--num[b-xr59dyhu1d] {
    width: 5.5rem;
}

.kf-suffix[b-xr59dyhu1d] {
    font-size: 0.78rem;
    color: var(--k-text-muted);
}

/* ── Chips: the compliant-default (ok) + sensitive (warn) markers. ── */
.kl-chip--ok[b-xr59dyhu1d] {
    color: var(--k-success);
    background: color-mix(in srgb, var(--k-success) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-success) 35%, var(--k-surface));
}

.kl-chip--warn[b-xr59dyhu1d] {
    color: var(--k-caution);
    background: color-mix(in srgb, var(--k-caution) 12%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-caution) 35%, var(--k-surface));
}

/* Dark-mode pill contrast (R11 design-skeptic BLOCKER, mirrors the foundation remap at kanine-design-system.css:516):
   the fixed status hues above are near-invisible on the dark surface (green-on-dark-green ≈ 4.2:1, below AA). Re-map to
   LIGHT text on a more-saturated fill so the load-bearing "compliant default" / sensitive markers stay clearly legible. */
html.dark .kl-chip--ok[b-xr59dyhu1d] {
    color: #9ce6c1;
    background: color-mix(in srgb, var(--k-success) 30%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-success) 55%, var(--k-surface));
}
html.dark .kl-chip--warn[b-xr59dyhu1d] {
    color: #f4c884;
    background: color-mix(in srgb, var(--k-caution) 32%, var(--k-surface));
    border-color: color-mix(in srgb, var(--k-caution) 55%, var(--k-surface));
}

/* SEC-DLC-001 registration of the FEEDBACK data class — an informational, NON-editable schedule card (review M7).
   Feedback retention is a fixed two-clock policy enforced in code (the Phase-C sweep), inexpressible in the matrix's
   (years x trigger x action) vocabulary, so it is registered as a described schedule rather than a fake editable row.
   A left-rule (a SHAPE cue, not a status-hued surface fill) marks it as system-fixed; every colour is a design token
   that flips for dark, so no html.dark override is needed. */
.kl-retention-fixed[b-xr59dyhu1d] {
    padding: var(--k-space-3) var(--k-space-4);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
    color: var(--k-text);
    box-shadow: inset 3px 0 0 0 var(--k-accent);
}

.kl-retention-fixed .kf-hint[b-xr59dyhu1d] {
    margin-top: 4px;
}

/* The A13 route out to the one knob this block describes (the unresolved-report limit, edited on
   /tenant-settings#feedback). It is a next step under body copy, not a header action, so it keeps the start edge. */
.kl-retention-fixed > .kl-btn[b-xr59dyhu1d] {
    margin-block-start: var(--k-space-3);
}

/* ── THE KEY to the marks each card wears (owner ask 2026-09-14). ──────────────────────────────────────────────
   It was a bare row of three wide chips under a hairline, built from the same component the eight cards above
   wear, so it read as three more rows of data. The frame is what tells a reader this block is documentation:
   a DASHED edge (the only one on the screen) around a RECESSED surface (nothing else here is recessed), under an
   uppercase heading. The chips inside are unchanged samples, and each carries exactly the words a card wears.

   Colour is never the carrier: the dashed edge and the heading both survive a monochrome print and neither is
   status-hued, so §UI-GUAR-027 is untouched. Every value is a design token that flips for dark. */
.kl-retention-legend[b-xr59dyhu1d] {
    padding: var(--k-space-3) var(--k-space-4);
    /* --k-outline (gray-500), not --k-border (gray-300): the dash IS the signal, and at 1px a gray-300 dash on
       gray-100 reads as a hairline rather than as a dashed edge. Both tokens flip for dark. */
    border: 1px dashed var(--k-outline);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
}

.kl-retention-legend-heading[b-xr59dyhu1d] {
    display: flex;
    align-items: center;
    gap: var(--k-space-2);
    margin: 0 0 var(--k-space-3);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--k-text-muted);
}

.kl-retention-legend-keys[b-xr59dyhu1d] {
    display: grid;
    gap: var(--k-space-2);
    margin: 0;
}

/* Term and description on one line where the measure allows it, and stacked where it does not. `flex-wrap` plus a
   basis on the description is the whole mechanism, so no width is hard-coded and no media query is needed. */
.kl-retention-legend-key[b-xr59dyhu1d] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--k-space-1) var(--k-space-3);
}

.kl-retention-legend-key > dt[b-xr59dyhu1d] {
    flex: 0 0 auto;
    margin: 0;
}

/* The UA gives <dd> a 40px inline start margin. Clearing it is not cosmetic: it would indent every description
   away from its own mark and re-open the gap this block exists to close. */
.kl-retention-legend-key > dd[b-xr59dyhu1d] {
    flex: 1 1 18rem;
    margin: 0;
    color: var(--k-text-muted);
    font-size: 14px;
}

/* ── The seal action bar. ── */
.kl-retention-actionbar[b-xr59dyhu1d] {
    display: flex;
    align-items: center;
    gap: var(--k-space-4);
    padding-top: var(--k-space-4);
    border-top: 1px solid var(--k-border);
    flex-wrap: wrap;
}

.kl-readonly-note[b-xr59dyhu1d] {
    color: var(--k-text-muted);
    font-size: 0.82rem;
    margin: 0;
    flex: 1 1 18rem;
}

/* ── The two dialogs (legal-basis override, disposition switch) — panel + furniture. ── */
/* UI-GUAR-033: overlay/scrim retired — <KlOverlay> now supplies the fixed scrim + centering. */
.kl-dialog--danger[b-xr59dyhu1d] {
    max-width: 32rem;
    width: 100%;
    background: var(--k-surface);
    color: var(--k-text);
    border: 1px solid var(--k-border);
    border-top: 4px solid var(--k-critical);
    border-radius: var(--k-radius-md);
    padding: var(--k-space-4);
    display: flex;
    flex-direction: column;
    gap: var(--k-space-3);
}

.kl-dialog-title[b-xr59dyhu1d] {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--k-text);
}

.kl-dialog-lede[b-xr59dyhu1d] {
    margin: 0;
    font-size: 0.88rem;
    color: var(--k-text-muted);
}

.kf-required[b-xr59dyhu1d] {
    color: var(--k-critical);
}

/* ── Phone: the controls stop competing for one line and become a readable stack. ── */
@media (max-width: 640px) {
    .kl-retention-controls[b-xr59dyhu1d] {
        flex-direction: column;
    }

    .kl-retention-field[b-xr59dyhu1d] {
        flex: 1 1 auto;
    }

    .kl-retention-preview-kind[b-xr59dyhu1d] {
        flex: 1 1 100%;
    }
}

/* ── OWNER RULING 2026-09-14: the PER-ITEM disposition ledger ───────────────────────────────────
   Same recital box as the dry-run report and the run history above it, so the three read-only
   blocks in this panel read as one rhythm. The table is real tabular data (five columns a court
   reads across a row), so it uses the house .kl-data-table rather than the list shape.

   Class attribute endings were cleared against the foundation families: `-ledger`, `-scroll`,
   `-table`, `-when`, `-detail`, `-unavailable`, `-loading`, `-empty`, `-denied`, `-row` and
   `-chip`. `-loading`, `-empty`, `-denied`, `-row` and `-chip` ARE families and are joined
   DELIBERATELY on exactly the elements those families are written for — a muted <p> state line,
   a table row, and a chip span — which is how the shared EntityHistoryPanel already spells the
   same four states. `-table` is a family too, and joining it is what keeps a real table a table
   under the design system's §5n table-structural guard. */
.kl-retention-ledger[b-xr59dyhu1d] {
    padding: var(--k-space-3) var(--k-space-4);
    border: 1px solid var(--k-border);
    border-radius: var(--k-radius-md);
    background: var(--k-surface-2);
    color: var(--k-text);
}

/* A8 — five court-facing columns are wide at 393px. The box scrolls, the PAGE never does. A DIV
   is used rather than a media query on the table because the design system re-asserts
   `.kl-shell-main table { display:table !important }` (§5n) and !important beats a media query. */
.kl-retention-ledger-scroll[b-xr59dyhu1d] {
    max-width: 100%;
    overflow-x: auto;
    margin-block-start: var(--k-space-2);
}

.kl-retention-ledger-table[b-xr59dyhu1d] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
}

.kl-retention-ledger-table th[b-xr59dyhu1d] {
    text-align: left;
    font-weight: 600;
    white-space: nowrap;
    padding: 0.375rem 0.75rem 0.375rem 0;
    border-bottom: 1px solid var(--k-border);
}

.kl-retention-ledger-table td[b-xr59dyhu1d] {
    padding: 0.375rem 0.75rem 0.375rem 0;
    border-bottom: 1px solid color-mix(in srgb, var(--k-border) 55%, transparent);
    vertical-align: top;
}

.kl-retention-ledger-id[b-xr59dyhu1d] {
    margin-inline-start: var(--k-space-2);
    color: var(--k-text-muted);
}

/* The cause column is the one that can be long. It wraps: truncating the recorded reason a purge
   was refused would hide the very thing the column exists to show. */
.kl-retention-ledger-detail[b-xr59dyhu1d] {
    max-width: 24rem;
    white-space: normal;
    overflow-wrap: anywhere;
}

/* The four outcome weights, matching the shared history panel's tones so a refusal carries the
   same visual weight wherever a reader meets one. */
.kl-retention-ledger-chip[b-xr59dyhu1d] {
    display: inline-block;
    white-space: nowrap;
}

/* `.kl-chip` is compounded in on purpose. The element ends in `-chip`, so in dark mode the foundation's neutral
   chip remap reaches it at (0,3,14), which outranked a (0,3,0) tone rule and painted every outcome the same grey.
   (0,4,0) wins that. The colours are the house status tints (kanine-design-system.css §1), per mode. */
.kl-chip.kl-retention-ledger-chip[data-tone="denied"][b-xr59dyhu1d] {
    background: var(--k-critical-bg);
    color: var(--k-critical-fg);
}

.kl-chip.kl-retention-ledger-chip[data-tone="export"][b-xr59dyhu1d] {
    background: var(--k-caution-bg);
    color: var(--k-caution-fg);
}

.kl-chip.kl-retention-ledger-chip[data-tone="edit"][b-xr59dyhu1d] {
    background: var(--k-surface-3);
    color: var(--k-text-muted);
}

.kl-retention-ledger-unavailable[b-xr59dyhu1d],
.kl-retention-ledger-empty[b-xr59dyhu1d],
.kl-retention-ledger-loading[b-xr59dyhu1d],
.kl-retention-ledger-denied-who[b-xr59dyhu1d] {
    margin: var(--k-space-2) 0 0;
    font-size: 0.82rem;
}

.kl-retention-ledger-denied[b-xr59dyhu1d] {
    margin: var(--k-space-2) 0 0;
    font-size: 0.82rem;
    font-weight: 600;
}
