/* ============================================================================
   Contract-Management — single global stylesheet (no scoped CSS).
   Font: Inter. Palette:
     #546A76 Blue Slate · #88A0A8 Cool Steel · #B4CEB3 Celadon
     #DBD3C9 Dust Grey  · #FAD4D8 Petal Frost
   Shell: white topbar + dark left sidebar + light content (admin-console style).
   ========================================================================== */

/* Cascade layers (T7.1 / D2, 2026-07-14 CSS assessment): declared once, in priority order —
   a layer declared later always beats an earlier one, REGARDLESS of selector specificity. This
   is what let the 13 pre-existing no-descending-specificity findings get fixed by moving a
   handful of single-purpose "override a base component in one specific place" rules into the
   final `utilities` layer, instead of reordering lines. Every rule below lives in one of these six
   layers except :root (see the `tokens` layer, which holds nothing else and never competes with
   anything, so its position is purely documentation). */
@layer reset, base, tokens, layout, components, utilities;

@layer tokens {
:root {
    /* Brand palette */
    --cm-blue-slate:  #546A76;
    --cm-cool-steel:  #88A0A8;
    --cm-celadon:     #B4CEB3;
    --cm-dust-grey:   #DBD3C9;
    --cm-petal-frost: #FAD4D8;

    /* Derived tokens */
    --cm-blue-slate-dark: #3f515b;
    --cm-text:        #2b343a;
    --cm-text-muted:  #5f6b72;
    --cm-bg:          #eef2f2;
    --cm-surface:     #ffffff;
    --cm-border:      #e1e5e3;
    --cm-tint:        #e9eef0;   /* subtle selected/hover fill */
    --cm-danger:      #b3404a;
    /* Hover-darken sibling for --cm-danger, mirrors the --cm-blue-slate-dark convention
       (T4.1, 2026-07-14 CSS assessment — cm-button--danger). */
    --cm-danger-dark: #98363f;

    /* Dark sidebar */
    --cm-sidebar-bg:     #1f3231;
    --cm-sidebar-hover:  #2a4140;
    --cm-sidebar-active: #2f4746;
    --cm-sidebar-text:   #b8c7c4;

    /* Alias: same value as --cm-sidebar-bg, distinct semantic role (dark ink-on-pastel
       badge text, not the dark sidebar surface) — see A1 in the 2026-07-14 CSS assessment. */
    --cm-steel-ink: #1f3231;

    /* Semantic status layer (A2, 2026-07-14 CSS assessment) — the palette previously had
       no success/warn/focus/scrim tokens, so every status surface hand-rolled its own hex. */
    --cm-success:     #2f7d4f;
    /* The two ambers in the app (#9a6a00 plain text, #7a5500 badge/lamp ink) were 32 units
       of unintentional drift on the same "needs review / expires soon" role — collapsed here
       onto one value. */
    --cm-warn:      #7a5500;   /* plain-text warn (e.g. days-until-expiry copy) */
    --cm-warn-ink:  #7a5500;   /* ink paired with --cm-warn-bg inside a pastel badge/lamp */
    --cm-warn-bg:   #f3e2c2;
    --cm-danger-tint: rgba(179, 64, 74, .08);   /* one opacity for all danger-tinted row/panel fills */
    --cm-focus-ring:  0 0 0 3px rgba(136,160,168,.25);
    --cm-scrim:       rgba(43,52,58,.45);   /* modal/dialog backdrop */
    --cm-shadow-hover: 0 2px 6px rgba(43,52,58,.08), 0 10px 28px rgba(43,52,58,.08);
    --cm-text-inverse: #fff;   /* text on a colored/dark fill, e.g. buttons, badges, sidebar */
    --cm-font-mono:   ui-monospace, "SFMono-Regular", Menlo, monospace;

    /* Ink-on-pastel pairs: each ink is always used together with its matching brand pastel
       (--cm-celadon / --cm-dust-grey / --cm-petal-frost) as the badge/alert background. */
    --cm-celadon-ink: #2f4a32;
    --cm-dust-ink:    #5a5347;
    /* #8a3a45 and #7c2e39 were a 14-unit drift on the same role (ink on --cm-petal-frost);
       collapsed onto one value. */
    --cm-petal-ink:    #8a3a45;
    --cm-petal-border: #e6b9bf;

    /* Green-tint surface family (A3, 2026-07-14 CSS assessment): #e7efee/#eef4f3/#f5f8f7 were
       three near-identical off-white teal tints (a ~7-unit RGB drift with no design intent) —
       collapsed onto two tokens. --cm-tint (existing, L24) stays the darker "subtle selected/
       hover fill" used on the cockpit's sticky header/rowhead — those stay opaque and untouched. */
    --cm-tint-cool:   #e7efee;
    --cm-surface-alt: #f5f8f7;
    --cm-tint-hover:  #dde9e7;   /* cockpit sortable-column-header hover, one shade below --cm-tint */

    --cm-radius:    .55rem;
    --cm-radius-sm: .4rem;
    --cm-shadow:    0 1px 2px rgba(43,52,58,.05), 0 4px 14px rgba(43,52,58,.05);
    --cm-font:      "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

    /* Type scale (T3.3 / A7, 2026-07-14 CSS assessment): 23 distinct font sizes collapsed onto
       9 steps, each within .05rem of its nearest neighbor - the .75-.82rem band (6 values) all
       land on --cm-fs-78. Deliberate literal holdouts that exceed the .05rem sanctioned shift
       (not tokenized, see T3.3 note in the remediation report): .cm-bell__badge (.65rem),
       .cm-metric__value/.cm-about__sectiontitle (1.4rem), .cm-kpi__num (1.7rem), the About-page
       hero title's clamp() (decorative, deferral #3), and the body 15px base (deferral #11 -
       do not touch). */
    --cm-fs-72:  .72rem;
    --cm-fs-78:  .78rem;
    --cm-fs-85:  .85rem;
    --cm-fs-90:  .9rem;
    --cm-fs-100: 1rem;
    --cm-fs-110: 1.1rem;
    --cm-fs-120: 1.2rem;
    --cm-fs-160: 1.6rem;
    --cm-fs-200: 2rem;

    /* Spacing scale (T3.4 / A8, 2026-07-14 CSS assessment). --cm-space-page is the one
       page-level outer-breathing-room value actually in use (.cm-panel's centering margin,
       .cm-explorer__welcome's padding) - both were already 3rem, so this is documentation, not
       a value change; .cm-login__card's 2.5rem is component padding, not this "page margin"
       role, and is left as its own literal. --cm-pad-control is a deliberate escape hatch (not
       one of the 8 scale steps): the .55-.65rem control-padding cluster snaps here instead of
       onto --cm-space-3/4 wherever landing on the scale would visibly resize a button/input.
       --cm-stack is the ONE section rhythm value, replacing five different gap values
       (1/1.1/1.25/1.6/2rem) that all served the same "separate this block from the page
       content above it" role - including the former .cm-mt ad hoc patch, which now resolves
       to this token instead of its own private 1rem. */
    --cm-space-1: .15rem;
    --cm-space-2: .3rem;
    --cm-space-3: .5rem;
    --cm-space-4: .75rem;
    --cm-space-5: 1rem;
    --cm-space-6: 1.25rem;
    --cm-space-7: 1.5rem;
    --cm-space-8: 2rem;
    --cm-space-page: 3rem;
    --cm-pad-control: .6rem;
    --cm-stack: 1.25rem;

    /* Control sizing (2026-07-15): ONE size for every button and every input, app-wide —
       the former .5rem/1rem buttons and --cm-pad-control-tall inputs read as consumer-app
       chunky in a data-dense line-of-business tool. Change these four tokens, never a rule. */
    --cm-btn-pad-y:   .35rem;
    --cm-btn-pad-x:   .8rem;
    --cm-control-pad-y: .4rem;
    --cm-control-pad-x: .6rem;
    --cm-control-fs:  var(--cm-fs-90);
}
}

/* --- Reset ------------------------------------------------------------------ */
@layer reset {
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
}

/* --- Base (bare element defaults) -------------------------------------------- */
@layer base {
body {
    font-family: var(--cm-font);
    font-size: 15px;
    line-height: 1.55;
    color: var(--cm-text);
    background: var(--cm-bg);
    -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { line-height: 1.25; margin: 0 0 .5rem; font-weight: 600; letter-spacing: -.01em; }
h1 { font-size: var(--cm-fs-160); }
h2 { font-size: var(--cm-fs-120); }
p  { margin: 0 0 .75rem; }
a  { color: var(--cm-blue-slate); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--cm-cool-steel); outline-offset: 2px; }
}

/* --- Layout (app shell chrome: topbar, sidebar, main, admin shell) ----------- */
@layer layout {
/* Locked app shell: the shell is exactly one viewport tall; the CONTENT scrolls inside
   .cm-main while topbar and sidebar stay put (the sidebar must be full-height at all
   times, never growing/scrolling with the page). 100dvh guards mobile browser chrome. */
.cm-shell { display: flex; flex-direction: column; height: 100vh; height: 100dvh; }

/* Topbar retired (2026-07-15, Clockopus-style shell): brand, notifications, user and sign-out
   all live in the sidebar now — the content pane gets the full viewport height. */
.cm-sidebar__brand { display: flex; align-items: center; gap: var(--cm-space-3); font-weight: 700;
    font-size: var(--cm-fs-110); color: var(--cm-text-inverse);
    padding: var(--cm-space-2) .85rem var(--cm-space-4); margin-bottom: var(--cm-space-3);
    border-bottom: 1px solid rgba(255,255,255,.08); }
.cm-sidebar__brand:hover { color: var(--cm-text-inverse); text-decoration: none; }
.cm-sidebar__brand img { width: 48px; height: 48px; display: block; }
.cm-sidebar__brandtext { display: flex; flex-direction: column; line-height: 1.15; }
.cm-sidebar__badge { display: inline-block; margin-left: var(--cm-space-2); background: var(--cm-danger);
    color: var(--cm-text-inverse); font-size: var(--cm-fs-72); font-weight: 700; line-height: 1;
    padding: .15rem .4rem; border-radius: 999px; vertical-align: text-top; }
.cm-sidebar__user { display: flex; align-items: center; gap: var(--cm-space-3);
    padding: var(--cm-space-4) .85rem; margin-bottom: var(--cm-space-2);
    border-bottom: 1px solid rgba(255,255,255,.08); }
.cm-sidebar__avatar { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 36px; height: 36px; border-radius: var(--cm-radius); background: var(--cm-celadon);
    color: var(--cm-celadon-ink); font-weight: 700; font-size: var(--cm-fs-85); letter-spacing: .02em; }
.cm-sidebar__usertext { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.cm-sidebar__username { color: var(--cm-text-inverse); font-weight: 600; font-size: var(--cm-fs-90);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-sidebar__usermeta { color: var(--cm-sidebar-text); font-size: var(--cm-fs-72);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-sidebar__signout { display: inline-flex; flex-shrink: 0; padding: var(--cm-space-2);
    color: var(--cm-sidebar-text); border-radius: var(--cm-radius-sm); }
.cm-sidebar__signout:hover { color: var(--cm-text-inverse); background: rgba(255,255,255,.08); text-decoration: none; }

.cm-search__snippet { color: var(--cm-text-muted); font-size: var(--cm-fs-85); line-height: 1.4; }
.cm-search__snippet mark { background: var(--cm-celadon); color: inherit; padding: 0 .1em; border-radius: 2px; }
.cm-pager { display: flex; align-items: center; gap: .75rem; margin-top: var(--cm-stack); }
.cm-pager__info { color: var(--cm-text-muted); font-size: var(--cm-fs-85); }
/* T6.5 / C5: CSS-drawn chevrons replace the "← Previous"/"Next →" text-glyph arrows — same
   border-triangle technique as .cm-collapse__summary::before (components layer). */
.cm-pager__prev::before, .cm-pager__next::after {
    content: ""; display: inline-block; width: .4rem; height: .4rem;
    border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
}
.cm-pager__prev::before { transform: rotate(135deg); margin-right: .4rem; }
.cm-pager__next::after { transform: rotate(-45deg); margin-left: .4rem; }

.cm-body { display: flex; flex: 1; align-items: stretch; min-height: 0; }

/* Dark left sidebar */
.cm-sidebar { width: 232px; flex: none; background: var(--cm-sidebar-bg);
    padding: 1.1rem var(--cm-space-3); display: flex; flex-direction: column; gap: .15rem;
    overflow-y: auto; }
.cm-sidebar .cm-sidebar__link {
    display: flex; align-items: flex-start; gap: .7rem; padding: var(--cm-pad-control) .85rem;
    border-radius: var(--cm-radius-sm); color: var(--cm-sidebar-text); font-weight: 500;
}
.cm-sidebar .cm-sidebar__link:hover { background: var(--cm-sidebar-hover); color: var(--cm-text-inverse); text-decoration: none; }
.cm-sidebar .cm-sidebar__link.active { background: var(--cm-sidebar-active); color: var(--cm-text-inverse); }
.cm-sidebar .cm-icon { width: 18px; height: 18px; flex: none; }
.cm-sidebar__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cm-sidebar__desc { font-size: var(--cm-fs-72); color: var(--cm-sidebar-text); opacity: .75; line-height: 1.3; white-space: normal; font-weight: 400; }

/* sidebar footer (About / vendor link / build version) — pinned to the bottom */
.cm-sidebar__footer { margin-top: auto; padding-top: var(--cm-space-3); display: flex; flex-direction: column;
    gap: .15rem; border-top: 1px solid rgba(255,255,255,.08); }
/* Single About line (Clockopus-style, 2026-07-15): "About Contract-Management (version)" — the
   About nav entry, vendor link and separate version line collapsed into one footer row; the
   vendor link lives on the About page itself. */
.cm-sidebar__about { display: block; padding: .3rem .85rem .1rem; font-size: var(--cm-fs-78); color: var(--cm-sidebar-text); }
.cm-sidebar__about:hover { color: var(--cm-text-inverse); text-decoration: underline; }
.cm-sidebar__aboutversion { color: rgba(184,199,196,.6); }

.cm-main { flex: 1; min-width: 0; padding: 1.75rem 2.25rem; overflow-y: auto; }
/* FocusOnNavigate (Routes.razor) programmatically focuses the page h1 after every navigation
   for screen readers — keep the focus, drop the visual ring: a heading is not interactive,
   the browser outline reads as a stray frame around the title. This must win over both the
   base-layer :focus-visible rule AND components-layer .cm-toolbar h1 — it does, because `layout`
   is declared after `base`; `.cm-toolbar h1` only ever sets margin, never outline, so the two
   never actually compete despite historically tripping the no-descending-specificity linter. */
.cm-main h1:focus, .cm-main h1:focus-visible { outline: none; }

/* --- Administration shell (two-pane: sub-nav + content) -------------------- */
.cm-admin__head { display: flex; align-items: center; gap: .9rem;
    padding-bottom: 1.1rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--cm-border); }
.cm-admin__icon { display: inline-flex; align-items: center; justify-content: center;
    width: 2.6rem; height: 2.6rem; flex: none; border-radius: 50%;
    background: var(--cm-tint); color: var(--cm-blue-slate); }
.cm-admin__icon svg { width: 1.35rem; height: 1.35rem; }
.cm-admin__title { font-size: var(--cm-fs-160); font-weight: 600; letter-spacing: -.01em; margin: 0; }
.cm-admin__subtitle { color: var(--cm-text-muted); margin: .15rem 0 0; }

.cm-admin__body { display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 2rem; align-items: start; }
.cm-admin__nav { position: sticky; top: 1.75rem; display: flex; flex-direction: column; gap: 1.25rem; }
.cm-admin__group { display: flex; flex-direction: column; gap: .15rem; }
.cm-admin__group-label { font-size: var(--cm-fs-72); font-weight: 600; text-transform: uppercase;
    letter-spacing: .06em; color: var(--cm-text-muted); padding: 0 .7rem; margin-bottom: .3rem; }
.cm-admin__link { display: block; padding: .45rem .7rem; border-radius: var(--cm-radius-sm);
    color: var(--cm-text); font-weight: 500; text-decoration: none; box-shadow: inset 3px 0 0 transparent; }
.cm-admin__link:hover { background: var(--cm-tint); text-decoration: none; }
.cm-admin__link.active { background: var(--cm-tint); color: var(--cm-blue-slate-dark);
    font-weight: 600; box-shadow: inset 3px 0 0 var(--cm-blue-slate); }
.cm-admin__content { min-width: 0; }
}

/* --- Components (widgets: cards, buttons, tables, forms, badges, dialog, ...) */
@layer components {
/* --- Surfaces -------------------------------------------------------------- */
/* Shared card-like surface base (T3.2 / A6, merge-candidate #3): .cm-card, .cm-login__card,
   .cm-explorer__tree, .cm-kpi, .cm-about__fact, .cm-about__card all declared the identical
   background/border/radius/shadow four-up - grouped here once; each selector's own rule
   (at its topical location) keeps only its padding and other unique layout declarations. */
.cm-card, .cm-login__card, .cm-explorer__tree, .cm-kpi, .cm-about__fact, .cm-about__card {
    background: var(--cm-surface); border: 1px solid var(--cm-border);
    border-radius: var(--cm-radius); box-shadow: var(--cm-shadow);
}
.cm-card { padding: 1.25rem 1.5rem; margin-bottom: 1.1rem; }
.cm-cards .cm-card { margin-bottom: 0; }   /* grid uses gap for spacing */

/* Header rule (T5.6 / B8): wrap the h1 in .cm-toolbar ONLY when the page has header-level
   actions (a button/link beside the title) - a bare h1 with nothing to align against gets no
   wrapper. This was previously a 9/9 split (toolbar-with-nothing-to-toolbar vs plain h1) with two
   different h1-to-lead spacings; now one rule, one rhythm. */
.cm-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    margin-bottom: 1rem; flex-wrap: wrap; }
.cm-toolbar h1 { margin: 0; }
/* Group for a toolbar with more than one header-level action (first user: Dossier types'
   Import-from-JSON beside + New template) — keeps space-between pinning h1 left, buttons right. */
.cm-toolbar__actions { display: flex; align-items: center; gap: var(--cm-space-3); }
.cm-empty { color: var(--cm-text-muted); padding: .5rem 0; }
.cm-section__title { margin-top: var(--cm-stack); color: var(--cm-text); font-size: var(--cm-fs-110); }
.cm-lead { color: var(--cm-text-muted); margin: -.25rem 0 1.25rem; }

/* --- Dashboard stat cards (clickable, clean) ------------------------------ */
.cm-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 1rem; margin: var(--cm-stack) 0 var(--cm-stack); }
.cm-stat { display: flex; flex-direction: column; gap: .3rem; }
.cm-stat__label { color: var(--cm-text-muted); font-size: var(--cm-fs-78); text-transform: uppercase; letter-spacing: .04em; }
.cm-stat__value { font-size: var(--cm-fs-200); font-weight: 600; line-height: 1.1; color: var(--cm-blue-slate); }
.cm-stat__hint { color: var(--cm-text-muted); font-size: var(--cm-fs-78); }
a.cm-card { text-decoration: none; color: inherit;
    transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease; }
a.cm-card:hover { text-decoration: none; border-color: var(--cm-cool-steel);
    box-shadow: var(--cm-shadow-hover); transform: translateY(-2px); }

/* Task-first home tiles */
.cm-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: .9rem; margin-bottom: var(--cm-stack); }
.cm-tile { display: flex; flex-direction: column; gap: .5rem; text-decoration: none; color: var(--cm-text); }
.cm-tile__title { font-weight: 600; font-size: var(--cm-fs-110); }
.cm-tile__hint { color: var(--cm-text-muted); font-size: var(--cm-fs-90); }
.cm-actionrow { display: block; text-decoration: none; color: var(--cm-text); margin-bottom: .9rem; }
.cm-statline { color: var(--cm-text-muted); font-size: var(--cm-fs-78); margin-top: var(--cm-stack); }

/* --- Buttons --------------------------------------------------------------- */
.cm-button { display: inline-flex; align-items: center; gap: .4rem; padding: var(--cm-btn-pad-y) var(--cm-btn-pad-x);
    border: 1px solid transparent; border-radius: var(--cm-radius-sm); background: var(--cm-blue-slate);
    color: var(--cm-text-inverse); font: inherit; font-size: var(--cm-control-fs); font-weight: 500; cursor: pointer; transition: background .12s ease; }
.cm-button:hover { background: var(--cm-blue-slate-dark); text-decoration: none; color: var(--cm-text-inverse); }
/* Button variant policy (T5.3 / B5): ghost = secondary action, soft = tertiary action (see
   .cm-button--soft below), danger = destructive action. .cm-button--secondary retired (its one
   use point is now ghost - it was never a distinct semantic, just an unused third grey). */
.cm-button--ghost { background: transparent; color: var(--cm-blue-slate); border-color: var(--cm-border); }
.cm-button--ghost:hover { background: var(--cm-tint-cool); color: var(--cm-blue-slate); }
.cm-button--danger { background: var(--cm-danger); color: var(--cm-text-inverse); }
.cm-button--danger:hover { background: var(--cm-danger-dark); color: var(--cm-text-inverse); }
.cm-button--sm { padding: .25rem var(--cm-space-4); font-size: var(--cm-fs-78); }
/* .cm-linkbutton (T5.3 / B5, renamed from the modifier-only .cm-button--link): a standalone
   text-link-styled button/anchor that is NEVER combined with the .cm-button base class - it is
   its own block, not a .cm-button modifier. That "modifier that must not combine with its base"
   shape is exactly what produced the five broken ghost buttons fixed in T2.1/B1. */
.cm-linkbutton { background: transparent; color: var(--cm-blue-slate); padding: 0; border: none;
    font: inherit; font-weight: 500; cursor: pointer; text-decoration: underline;
    text-underline-offset: 2px; text-decoration-color: var(--cm-cool-steel); }
.cm-linkbutton:hover { color: var(--cm-blue-slate-dark); text-decoration-color: currentColor; }
.cm-linkbutton:disabled { color: var(--cm-text-muted); cursor: default; text-decoration: none; }

/* --- Model list (AI providers) -------------------------------------------- */
/* Bare flex-column list reset (T3.2 / A6, merge-candidate #5): .cm-modellist, .cm-runlog__list,
   .cm-chat-sessions__list and .cm-completeness__list all reset an unbulleted list to a vertical
   flex stack identically - grouped once; each keeps its own gap + any other unique declaration. */
.cm-modellist, .cm-runlog__list, .cm-chat-sessions__list, .cm-completeness__list {
    list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column;
}
.cm-modellist__item { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: .5rem .25rem; border-bottom: 1px solid var(--cm-border); }
.cm-modellist__item:last-child { border-bottom: none; }
.cm-modellist__name { min-width: 0; }

/* --- Tables ---------------------------------------------------------------- */
.cm-table { width: 100%; border-collapse: collapse; background: var(--cm-surface);
    border: 1px solid var(--cm-border); border-radius: var(--cm-radius); overflow: hidden; }
.cm-table th, .cm-table td { text-align: left; padding: var(--cm-space-4) .9rem; border-bottom: 1px solid var(--cm-border); }
.cm-table thead th { background: var(--cm-tint-cool); color: var(--cm-blue-slate-dark); font-weight: 600; font-size: var(--cm-fs-78);
    text-transform: uppercase; letter-spacing: .03em; }
.cm-table tbody tr:last-child td { border-bottom: none; }
.cm-table tbody tr:hover { background: var(--cm-surface-alt); }
/* current row for a master/detail table (e.g. Settings > Groups' group list) — reuses
   --cm-tint, the shared "subtle selected/hover fill" token */
.cm-table tbody tr.cm-table__row--selected { background: var(--cm-tint); }

/* --- Lists ------------------------------------------------------------------
   Generic unbulleted list of items each ending in an inline action (e.g. group
   members with a trailing Remove button). Deliberately plain — cm-filesteps__files
   is the file-staging-specific sibling of this shape. */
.cm-list { list-style: none; padding: 0; margin: .5rem 0 0; display: grid; gap: .4rem; }
.cm-list li { display: flex; align-items: center; gap: .5rem; }

/* --- Forms ----------------------------------------------------------------- */
.cm-form { display: flex; flex-direction: column; gap: var(--cm-space-4); max-width: 34rem; }
.cm-form__field { display: flex; flex-direction: column; gap: var(--cm-space-1); }
.cm-form__field > label { font-size: var(--cm-fs-85); color: var(--cm-text-muted); }
/* Checkbox group with per-option explanations (first user: the template editor's Add-field
   dialog). Each option is a bordered, clickable row — bare native checkboxes floating in the
   form read as an afterthought; the row makes the whole option one obvious touch target. */
.cm-checkgroup { border: 0; padding: 0; margin: var(--cm-space-5) 0; display: flex; flex-direction: column; gap: var(--cm-space-3); }
.cm-checkgroup__item { display: flex; align-items: flex-start; gap: var(--cm-space-4); cursor: pointer;
    padding: var(--cm-space-4); border: 1px solid var(--cm-border); border-radius: var(--cm-radius-sm);
    background: var(--cm-surface); transition: background .12s ease, border-color .12s ease; }
.cm-checkgroup__item:hover { background: var(--cm-surface-alt); border-color: var(--cm-blue-slate); }
.cm-checkgroup__item:has(input:checked) { background: var(--cm-tint-cool); border-color: var(--cm-blue-slate); }
.cm-checkgroup__item input { width: 1.05rem; height: 1.05rem; margin: var(--cm-space-1) 0 0; flex-shrink: 0; cursor: pointer; }
.cm-checkgroup__desc { display: block; color: var(--cm-text-muted); font-size: var(--cm-fs-85); font-weight: 400; margin-top: var(--cm-space-1); }
.cm-form__field label { font-weight: 500; font-size: var(--cm-fs-90); color: var(--cm-text-muted); }
.cm-input { padding: var(--cm-control-pad-y) var(--cm-control-pad-x); border: 1px solid var(--cm-border); border-radius: var(--cm-radius-sm);
    font: inherit; font-size: var(--cm-control-fs); background: var(--cm-surface); color: var(--cm-text); }
.cm-input:focus { border-color: var(--cm-cool-steel); outline: none; box-shadow: var(--cm-focus-ring); }
.cm-input--full { width: 100%; }
.cm-input--xs { width: 5rem; }
/* T5.5 / B7: checkboxes are native/unstyled everywhere in the app with no focus/brand treatment -
   one accent-color rule closes that gap without a bespoke checkbox component. */
input[type="checkbox"] { accent-color: var(--cm-blue-slate); }

/* compact "Template & extraction" bar: inline select & buttons on one row */
.cm-tplbar { display: flex; flex-direction: column; gap: .75rem; }
.cm-tplbar__row { display: flex; align-items: center; gap: var(--cm-space-3); flex-wrap: wrap; }
.cm-tplbar__row .cm-input { flex: 1 1 14rem; min-width: 12rem; }

/* two equal-width columns (e.g. Template & extraction | Upload) */
.cm-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.4rem; align-items: start; }
.cm-2col .cm-card { margin-bottom: 0; }
.cm-filters { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--cm-space-3) 1rem; width: 100%; margin-bottom: 1.1rem; }
/* Merged toolbar action slot (Cockpit redesign): spans the filters row's full width and right-aligns
   its buttons — the existing .cm-filters row IS the toolbar, this is not a new one-off container. */
.cm-filters__actions { grid-column: 1 / -1; display: flex; align-items: center; justify-content: flex-end;
    gap: var(--cm-space-3); margin-left: auto; flex-wrap: wrap; }
.cm-pre { background: var(--cm-surface-alt); border: 1px solid var(--cm-border); border-radius: var(--cm-radius-sm);
    padding: .75rem; overflow: auto; max-height: 28rem; font-size: var(--cm-fs-78); white-space: pre-wrap; word-break: break-word; }
.cm-docview { width: 100%; height: 70vh; border: 1px solid var(--cm-border); border-radius: var(--cm-radius-sm); background: var(--cm-surface); }

/* --- Cockpit (transposed matrix) ------------------------------------------ */
/* Excel-like frozen panes: scroll both axes; first column + header row stay put. */
/* overflow-x here is what keeps horizontal scroll INSIDE the card — never a page-level scrollbar */
.cm-cockpit { overflow: auto; max-height: 78vh; border: 1px solid var(--cm-border); border-radius: var(--cm-radius); }
.cm-cockpit__table { border: none; min-width: 100%; white-space: nowrap; }
/* #e7efee tokenized to --cm-tint (nearest existing "subtle fill" token) — both rules touched by this redesign. */
.cm-cockpit__table thead th { position: sticky; top: 0; z-index: 2; background: var(--cm-tint); }
.cm-cockpit__rowhead { position: sticky; left: 0; z-index: 1; background: var(--cm-tint); font-weight: 600; max-width: 22rem; }
.cm-cockpit__table thead th.cm-cockpit__rowhead { z-index: 3; }   /* top-left corner above both */
.cm-cockpit__table tbody .cm-cockpit__rowhead { background: var(--cm-surface); }
.cm-cockpit__table .cm-cell--num { text-align: right; font-variant-numeric: tabular-nums; }
.cm-cockpit__sortable { cursor: pointer; user-select: none; }
.cm-cockpit__sortable:hover { background: var(--cm-tint-hover); }
/* T6.5 / C5 (final-review I1): sort direction as CSS-drawn chevrons — same border-triangle
   technique as .cm-pager (no text glyphs). .cm-sort without a direction renders nothing. */
.cm-sort { display: inline-block; margin-left: .3rem; }
.cm-sort--asc::after, .cm-sort--desc::after {
    content: ""; display: inline-block; width: .34rem; height: .34rem;
    border-right: 2px solid var(--cm-text-muted); border-bottom: 2px solid var(--cm-text-muted);
}
.cm-sort--asc::after { transform: rotate(-135deg) translate(-1px, -1px); }
.cm-sort--desc::after { transform: rotate(45deg); }
.cm-cell--draft { color: var(--cm-text-muted); font-style: italic; }
/* Unverified/conflict cell markers (redesign 2026-07-14): verified is the silent default; only these two
   exceptions are marked, quietly, with no layout-shifting pill. */
.cm-cell--unverified { border-bottom: 2px dotted var(--cm-warn-ink); }
.cm-cell__conflict { margin-left: .35rem; color: var(--cm-danger); cursor: help; }
.cm-resultcount { color: var(--cm-text-muted); font-size: var(--cm-fs-90); margin: 1.25rem 0 .75rem; }

/* --- Collapsible section (native details/summary) ------------------------- */
.cm-collapse { margin-top: var(--cm-stack); }
.cm-collapse__summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: .5rem;
    font-size: var(--cm-fs-110); font-weight: 600; color: var(--cm-text); letter-spacing: -.01em;
    padding: .35rem 0; user-select: none; }
.cm-collapse__summary::-webkit-details-marker { display: none; }
.cm-collapse__summary::before { content: ""; width: .55rem; height: .55rem; flex: none;
    border-right: 2px solid var(--cm-cool-steel); border-bottom: 2px solid var(--cm-cool-steel);
    transform: rotate(-45deg); transition: transform .15s ease; margin-left: .15rem; }
.cm-collapse[open] > .cm-collapse__summary::before { transform: rotate(45deg); }
.cm-collapse__summary:hover { color: var(--cm-blue-slate); }
.cm-collapse > *:not(summary):first-of-type { margin-top: var(--cm-space-3); }

/* --- File drop zone -------------------------------------------------------- */
.cm-dropzone { position: relative; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: .45rem; text-align: center; padding: 2.4rem 1.5rem;
    border: 2px dashed var(--cm-cool-steel); border-radius: var(--cm-radius); background: var(--cm-surface-alt);
    color: var(--cm-text-muted); cursor: pointer; transition: border-color .12s ease, background .12s ease; }
.cm-dropzone:hover { border-color: var(--cm-blue-slate); background: var(--cm-tint-cool); }
.cm-dropzone--over { border-color: var(--cm-blue-slate); background: var(--cm-tint-cool);
    box-shadow: var(--cm-focus-ring); }
.cm-dropzone--busy { opacity: .6; pointer-events: none; }
/* native file input covers the zone so browser drag-drop works without JS */
.cm-dropzone__input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.cm-dropzone__input:disabled { cursor: default; }
/* Icon stroke-weight convention (T6.5 / C5, 2026-07-14 CSS assessment): every inline-SVG icon in the
   app uses stroke-width 2 at 16-20px (sidebar/topbar/bell/admin icons, small chrome icons) or
   stroke-width 1.5 at >=32px (dropzone icons, Explorer/Assistant empty-state icons) - the three
   previously-undocumented weights (2 / 1.6 / 1.5) collapse onto this one rule. Applied on the <svg>
   itself (these are hand-inlined markup, not a shared component), not here in CSS, but documented
   once, centrally, so new icons follow it instead of picking a fourth weight. */
.cm-dropzone__icon { width: 34px; height: 34px; color: var(--cm-cool-steel); margin-bottom: .15rem; }
.cm-dropzone__title { font-weight: 600; font-size: var(--cm-fs-100); color: var(--cm-text); }
.cm-dropzone__hint { font-size: var(--cm-fs-85); }

/* Guided filing (/file) */
.cm-filesteps { margin-bottom: 1rem; }
.cm-filesteps__files { list-style: none; padding: 0; margin: .75rem 0 0; display: grid; gap: .5rem; }
.cm-filesteps__size { color: var(--cm-text-muted); font-size: var(--cm-fs-78); }
.cm-filesteps__suggest { list-style: none; padding: 0; margin: .5rem 0 0; display: flex; flex-wrap: wrap; gap: .5rem; }
/* Inline "+ Create partner …" button needs air to the search box beside/above it. */
.cm-filesteps__create { margin: var(--cm-space-3) 0 0 var(--cm-space-3); }
.cm-filesteps__choice { display: block; margin: .25rem 0; }

/* --- Explorer ---------------------------------------------------------------
   Hover/active reuse --cm-tint (documented above as "subtle selected/hover
   fill") and the --cm-admin__link.active pattern (blue-slate accent bar) —
   the dark --cm-sidebar-hover/--cm-sidebar-active tokens are tuned for the
   dark --cm-sidebar-bg and would be illegible on this light content surface. */
.cm-explorer { display: grid; grid-template-columns: minmax(230px, 320px) 1fr; gap: 1.25rem; align-items: start; }
.cm-explorer__tree { display: flex; flex-direction: column; gap: .1rem;
    padding: var(--cm-space-3) var(--cm-space-3); position: sticky; top: 1.75rem; }
.cm-explorer__children { margin-left: .7rem; padding-left: var(--cm-space-3); border-left: 1px solid var(--cm-border);
    display: flex; flex-direction: column; gap: .1rem; }
.cm-explorer__node { display: flex; align-items: center; gap: .5rem; width: 100%; text-align: left;
    padding: .38rem var(--cm-space-3); border: 0; background: none; border-radius: var(--cm-radius-sm);
    cursor: pointer; color: var(--cm-text); font-size: var(--cm-fs-90); line-height: 1.3; }
.cm-explorer__node:hover { background: var(--cm-tint); }
.cm-explorer__node--active { background: var(--cm-tint); color: var(--cm-blue-slate-dark); font-weight: 600; box-shadow: inset 3px 0 0 var(--cm-blue-slate); }
.cm-explorer__node--vault { font-weight: 600; font-size: var(--cm-fs-100); }
.cm-explorer__node .cm-icon { width: 16px; height: 16px; flex: none; color: var(--cm-cool-steel); }
.cm-explorer__node--active .cm-icon { color: var(--cm-blue-slate); }
.cm-explorer__label { flex: 1; min-width: 0; }
.cm-explorer__count { flex: none; background: var(--cm-tint); color: var(--cm-text-muted); font-size: var(--cm-fs-72);
    font-weight: 600; line-height: 1; padding: .18rem .45rem; border-radius: 999px; font-variant-numeric: tabular-nums; }
.cm-explorer__node--active .cm-explorer__count { background: var(--cm-surface); }
.cm-explorer__emptyhint { padding: .3rem var(--cm-space-3); margin: 0; }

/* Explorer "nothing selected" welcome panel — a finished teaching state, not a bare stub. */
.cm-explorer__welcome { display: flex; flex-direction: column; align-items: center;
    text-align: center; padding: var(--cm-space-page) 2rem; gap: .35rem; }
.cm-explorer__welcome h2 { margin: 0; color: var(--cm-text); }
.cm-explorer__welcomeicon { width: 40px; height: 40px; color: var(--cm-text-muted); opacity: .7; margin-bottom: .4rem; }
.cm-explorer__welcomelead { margin: 0; color: var(--cm-text-muted); }
/* Explorer content panel (2026-07-15 UX feedback, 2nd round): partner/dossier panels use the
   same .cm-detail label-over-value grid as the document header, with the child lists as tables. */
.cm-explorer__doctable { margin-top: var(--cm-space-5); }
.cm-completeness__table { margin-top: var(--cm-space-3); }
.cm-explorer__welcomelist { margin: .8rem 0 0; padding: 0; list-style: none; display: flex;
    flex-direction: column; gap: .35rem; color: var(--cm-text-muted); font-size: var(--cm-fs-90); max-width: 34rem; }
/* Explorer's collapse rules moved into the single 900px breakpoint (utilities layer, T3.5 / A9) */

/* --- Badges / lamps (shared pill component, T3.1 / A5, 2026-07-14 CSS assessment) ----------
   .cm-badge and .cm-lamp were declaration-identical (merge-candidate #1) — merged into one
   pill base; both class names stay valid so existing razor markup (cm-lamp--*) is untouched.
   The color-pair modifiers below collapse five duplicate bg/ink declarations onto the Stage-1
   semantic ink tokens (merge-candidate #2). A few group in controls that are not badges/lamps
   themselves but happen to share the exact same pair byte-for-byte (some pills' own
   layout-only rule stays in the topbar section above; cm-alert--ok stays semantically a
   message variant) — grouped here purely because the declared value is identical, same
   precedent as the pre-existing --warn/--amber pairing. */
.cm-badge, .cm-lamp { display: inline-block; padding: .15rem var(--cm-space-3); border-radius: 999px; font-size: var(--cm-fs-78); font-weight: 600;
    white-space: nowrap; /* a pill must never wrap mid-word ("auto-/confirmed") */ }
/* A badge trailing text needs breathing room ("P10Y[verified]", "Facts[4 to review]" read as one
   token) — cover the two places a pill directly follows inline text: table cells and headings. */
td .cm-badge, h1 .cm-badge, h2 .cm-badge, h3 .cm-badge { margin-left: var(--cm-space-2); }
/* Dedicated status column of the dossier facts table: pills align in their own column, so no
   text-trailing indent — cancel it and keep only the gap between two pills (conflict + verify). */
td.cm-factstatus .cm-badge { margin-left: 0; }
td.cm-factstatus .cm-badge + .cm-badge { margin-left: var(--cm-space-2); }

/* celadon / celadon-ink — affirmative: active, manual-sourced, ok, on-time, role pill */
.cm-badge--active, .cm-badge--manual, .cm-alert--ok, .cm-lamp--green {
    background: var(--cm-celadon); color: var(--cm-celadon-ink);
}
/* dust-grey / dust-ink — neutral: inactive, contract-sourced, and (T6.2 / C2, 2026-07-14 CSS
   assessment) --soft, which used to sit on petal-frost pink alongside the true danger pair below —
   pink is now danger-family ONLY, so every non-danger "soft" badge (kind/status/amendment labels)
   moved here onto the same neutral dust pair as --inactive/--contract. */
.cm-badge--inactive, .cm-badge--contract, .cm-badge--soft { background: var(--cm-dust-grey); color: var(--cm-dust-ink); }
/* petal-frost / danger — conflict + overdue/red time states */
.cm-badge--conflict, .cm-lamp--overdue, .cm-lamp--red { background: var(--cm-petal-frost); color: var(--cm-danger); }
/* cool-steel / steel-ink — derived value, dossier type */
.cm-badge--derived, .cm-badge--type { background: var(--cm-cool-steel); color: var(--cm-steel-ink); }
/* warn-bg / warn-ink — needs review / expires soon (already shared pre-merge) */
.cm-badge--warn, .cm-lamp--amber { background: var(--cm-warn-bg); color: var(--cm-warn-ink); }
/* standalones — no duplicate partner within the badge/lamp family */
.cm-lamp--none { background: var(--cm-dust-grey); color: var(--cm-text-muted); }
.cm-badge--end { background: var(--cm-blue-slate); color: var(--cm-text-inverse); }   /* template's designated end-of-term field marker */

/* --- Detail list ----------------------------------------------------------- */
.cm-detail { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: .75rem 1.5rem; margin: 0; }
.cm-detail dd { margin: .1rem 0 0; }

/* --- Messages -------------------------------------------------------------- */
/* .cm-error retired T5.1/B2: the app's single error/info idiom is now .cm-alert
   .cm-alert--error|--ok everywhere (grep-confirmed zero remaining .cm-error message
   sites; .cm-error-inline below is a distinct structural "required" tag, unrelated). */

/* Inline alert for form/extraction errors: subtle tint + leading icon, wraps a long
   message cleanly inside the box (no raw payload overflow, no coloured card border). */
.cm-alert { display: flex; align-items: flex-start; gap: var(--cm-space-3); margin: var(--cm-stack) 0 var(--cm-space-5);
    padding: .7rem .85rem; border-radius: var(--cm-radius); font-size: var(--cm-fs-90); line-height: 1.45;
    overflow-wrap: anywhere; }
.cm-alert__icon { flex: none; width: 1.15rem; height: 1.15rem; margin-top: .05rem; }
.cm-alert__text { min-width: 0; }
.cm-alert--error { background: var(--cm-danger-tint); color: var(--cm-danger); }

/* --- Login screen ---------------------------------------------------------- */
.cm-login { min-height: 100vh; display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, #dceae8 0%, #e9e3dd 55%, #f5dde1 100%); padding: 1.5rem; }
.cm-login__card { padding: 2.5rem 2.25rem; width: 100%; max-width: 24rem; text-align: center; }
.cm-login__brand { display: flex; align-items: center; justify-content: center; gap: var(--cm-space-3);
    font-size: var(--cm-fs-120); font-weight: 600; margin-bottom: .4rem; color: var(--cm-blue-slate); }
.cm-login__brand img { width: 32px; height: 32px; }
.cm-login__tagline { color: var(--cm-text-muted); margin-bottom: 1.75rem; }
.cm-login__button { width: 100%; justify-content: center; padding: var(--cm-pad-control) 1rem; }
.cm-login__footer { margin-top: 1.75rem; color: var(--cm-cool-steel); font-size: var(--cm-fs-78); letter-spacing: .02em; }

/* --- Blazor error UI ------------------------------------------------------- */
#blazor-error-ui { display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000;
    padding: .75rem 1.25rem; background: var(--cm-petal-frost); color: var(--cm-petal-ink);
    border-top: 1px solid var(--cm-petal-border); box-shadow: 0 -2px 12px rgba(0,0,0,.08); }
#blazor-error-ui .reload { color: var(--cm-petal-ink); text-decoration: underline; margin-left: .5rem; }
#blazor-error-ui .dismiss { cursor: pointer; float: right; }

/* --- Dialog (CmDialog shared component, T4.1, 2026-07-14 CSS assessment B4; scroll model and
   backdrop padding tokenized in the Stage-4a review follow-up wave) -
   Backdrop + centered card; the ESC/backdrop-mousedown/focus-on-open behavior lives in the
   component's C#, not here. Two sizes: sm (default — confirm dialogs) and md (wider —
   edit-form dialogs added in a later Stage-4 task). Scroll lives on .cm-dialog__body, not the
   card: header and footer stay pinned, only the body scrolls when content overflows the card's
   max-height. Two literals below stay un-tokenized on purpose (same "documented keep" convention
   as .cm-login__card's 2.5rem above): the card's calc() viewport gutter (2.5rem — a viewport-
   relative margin, not a spacing-scale value) and the close button's own tight .2rem/.35rem
   click-target padding (between --cm-space-1/.15rem and --cm-space-2/.3rem; landing on either
   token would visibly resize the control). */
.cm-dialog__backdrop { position: fixed; inset: 0; z-index: 1000; background: var(--cm-scrim);
    display: flex; align-items: center; justify-content: center; padding: var(--cm-space-6); }
.cm-dialog { background: var(--cm-surface); border-radius: var(--cm-radius); box-shadow: var(--cm-shadow-hover);
    width: 100%; max-height: calc(100vh - 2.5rem); display: flex; flex-direction: column; }
.cm-dialog--sm { max-width: 26rem; }
.cm-dialog--md { max-width: 38rem; }
.cm-dialog--lg { max-width: 54rem; }
/* Section rhythm inside busy dialogs (first user: cockpit Edit columns) — an h3 that starts a
   new section needs clear air above it, and a primary button ending a section needs air below. */
.cm-dialog__section-title { margin: var(--cm-space-7) 0 var(--cm-space-4); padding-top: var(--cm-space-5);
    border-top: 1px solid var(--cm-border); font-size: var(--cm-fs-110); }
.cm-dialog__section-end { margin-top: var(--cm-space-4); }
.cm-table__actions { text-align: right; }
/* Move-to-vault control on the document header: an inline row capped at a sensible width —
   the bare .cm-input select otherwise spans the whole detail grid (full-page Move button). */
.cm-movevault__row { max-width: 28rem; }
.cm-dialog:focus { outline: none; }
.cm-dialog__header { display: flex; align-items: center; justify-content: space-between; gap: var(--cm-space-3);
    padding: var(--cm-space-6) var(--cm-space-6) 0; }
.cm-dialog__title { margin: 0; font-size: var(--cm-fs-110); }
.cm-dialog__close { flex: none; border: 0; background: transparent; color: var(--cm-text-muted);
    font-size: var(--cm-fs-110); line-height: 1; cursor: pointer; padding: .2rem .35rem; border-radius: var(--cm-radius-sm); }
.cm-dialog__close:hover { background: var(--cm-tint); color: var(--cm-text); }
.cm-dialog__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--cm-space-5) var(--cm-space-6); }
.cm-dialog__footer { display: flex; justify-content: flex-end; gap: var(--cm-space-3);
    padding: 0 var(--cm-space-6) var(--cm-space-6); }

/* --- Reconnect modal (Blazor Server) ---------------------------------------
   Ported from the .NET template's ReconnectModal.razor.css (T1.4, 2026-07-14 CSS
   assessment A4): the markup is a native <dialog id="components-reconnect-modal">
   (ReconnectModal.razor:3) — blazor.web.js toggles state CLASSES on that same element
   (components-reconnect-show/-retrying/-paused/-resume-failed/-failed) and calls
   showModal()/close() on it. The two rules this replaced (`.components-reconnect-modal`,
   `.components-reconnect-modal > div`) were CLASS selectors that never matched anything
   — the dialog never rendered styled. Colors/radius/backdrop use our tokens; the template's
   own accent blue (#6b9ed2) and rejoin-spinner blue (#0087ff) are replaced with our brand
   primary/cool-steel so the dialog matches the rest of the app. */
.components-reconnect-first-attempt-visible,
.components-reconnect-repeated-attempt-visible,
.components-reconnect-failed-visible,
.components-pause-visible,
.components-resume-failed-visible,
.components-rejoining-animation {
    display: none;
}
/* shape rule kept ahead of the higher-specificity #components-reconnect-modal.state selectors
   below so no-descending-specificity doesn't flag a same-selector reorder */
.components-rejoining-animation { position: relative; width: 80px; height: 80px; }

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible,
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation,
#components-reconnect-modal.components-reconnect-paused .components-pause-visible,
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible,
#components-reconnect-modal.components-reconnect-retrying,
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible,
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible {
    display: block;
}

#components-reconnect-modal {
    background-color: var(--cm-surface);
    color: var(--cm-text);
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: var(--cm-radius);
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, .3);
    opacity: 0;
    transition: display .5s allow-discrete, overlay .5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity .5s both;
}
#components-reconnect-modal[open] {
    animation: components-reconnect-modal-slideUp 1.5s cubic-bezier(.05, .89, .25, 1.02) .3s,
               components-reconnect-modal-fadeInOpacity .5s ease-in-out .3s;
    animation-fill-mode: both;
}
#components-reconnect-modal::backdrop {
    background-color: var(--cm-scrim);
    animation: components-reconnect-modal-fadeInOpacity .5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp {
    0%   { transform: translateY(30px) scale(.95); }
    100% { transform: translateY(0); }
}
@keyframes components-reconnect-modal-fadeInOpacity {
    0%   { opacity: 0; }
    100% { opacity: 1; }
}
@keyframes components-reconnect-modal-fadeOutOpacity {
    0%   { opacity: 1; }
    100% { opacity: 0; }
}

.components-reconnect-container { display: flex; flex-direction: column; align-items: center; gap: 1rem; }
#components-reconnect-modal p { margin: 0; text-align: center; }
#components-reconnect-modal button { border: 0; background-color: var(--cm-blue-slate);
    color: var(--cm-text-inverse); padding: 4px 24px; border-radius: var(--cm-radius-sm);
    font: inherit; font-weight: 500; cursor: pointer; }
#components-reconnect-modal button:hover  { background-color: var(--cm-blue-slate-dark); }
#components-reconnect-modal button:active { background-color: var(--cm-blue-slate); }

.components-rejoining-animation div { position: absolute; border: 3px solid var(--cm-cool-steel);
    opacity: 1; border-radius: 50%; animation: components-rejoining-animation 1.5s cubic-bezier(0, .2, .8, 1) infinite; }
.components-rejoining-animation div:nth-child(2) { animation-delay: -.5s; }
@keyframes components-rejoining-animation {
    0%    { top: 40px; left: 40px; width: 0; height: 0; opacity: 0; }
    4.9%  { top: 40px; left: 40px; width: 0; height: 0; opacity: 0; }
    5%    { top: 40px; left: 40px; width: 0; height: 0; opacity: 1; }
    100%  { top: 0; left: 0; width: 80px; height: 80px; opacity: 0; }
}

/* --- Extraction run log (upload progress) --------------------------------- */
.cm-runlog { margin-top: var(--cm-stack); padding: .9rem 1rem; background: var(--cm-bg);
    border: 1px solid var(--cm-border); border-radius: var(--cm-radius); }
.cm-runlog__head { margin: 0 0 var(--cm-space-3); font-weight: 600; color: var(--cm-text); }
.cm-runlog__list { gap: .45rem; font-variant-numeric: tabular-nums; }
.cm-runlog__item { display: flex; align-items: center; gap: var(--cm-space-3); font-size: var(--cm-fs-90); color: var(--cm-text-muted); }
.cm-runlog__icon { flex: none; width: 1.1rem; height: 1.1rem; display: inline-flex;
    align-items: center; justify-content: center; font-size: var(--cm-fs-85); line-height: 1; }
.cm-runlog__label { color: inherit; }
.cm-runlog__detail { color: var(--cm-text-muted); font-size: var(--cm-fs-78); min-width: 0; }
.cm-runlog__detail::before { content: "— "; }
.cm-runlog__time { margin-left: auto; color: var(--cm-text-muted); font-size: var(--cm-fs-78); font-variant-numeric: tabular-nums; }

/* per-state styling */
.cm-runlog__item--pending { opacity: .55; }
.cm-runlog__item--active  { color: var(--cm-text); font-weight: 500; }
.cm-runlog__item--done    { color: var(--cm-text); }
.cm-runlog__item--done .cm-runlog__icon  { color: var(--cm-success); }
.cm-runlog__item--error   { color: var(--cm-danger); font-weight: 500; }
.cm-runlog__item--error .cm-runlog__icon { color: var(--cm-danger); }

.cm-runlog__dot { width: .55rem; height: .55rem; border-radius: 50%;
    border: 1.5px solid var(--cm-cool-steel); }

.cm-spinner { width: .95rem; height: .95rem; border-radius: 50%;
    border: 2px solid var(--cm-cool-steel); border-top-color: transparent;
    animation: cm-spin .7s linear infinite; }
.cm-spinner--inline { display: inline-block; width: .8rem; height: .8rem; vertical-align: -1px; margin-right: .35rem; }
@keyframes cm-spin { to { transform: rotate(360deg); } }

/* live extraction status (contract detail) */
.cm-live { display: inline-flex; align-items: center; gap: .35rem; margin-left: var(--cm-space-3);
    font-size: var(--cm-fs-78); font-weight: 600; color: var(--cm-cool-steel); vertical-align: middle; }
.cm-extstatus { font-size: var(--cm-fs-85); }
.cm-extstatus--pending, .cm-extstatus--normalizing, .cm-extstatus--extracting { color: var(--cm-text-muted); }
.cm-extstatus--extracted { color: var(--cm-success); font-weight: 600; }
.cm-extstatus--failed { color: var(--cm-danger); font-weight: 600; }

/* --- Extracted-field evidence (grounding quote) --------------------------- */
.cm-evidence { margin-top: .2rem; font-size: var(--cm-fs-78); line-height: 1.35;
    color: var(--cm-text-muted); font-style: italic; max-width: 32rem;
    overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; }
.cm-evidence::before { content: "\201C"; }
.cm-evidence::after  { content: "\201D"; }
.cm-grounding { display: flex; align-items: center; gap: .4rem; margin-top: .25rem; flex-wrap: wrap; }
.cm-page { font-size: var(--cm-fs-78); color: var(--cm-text-muted); white-space: nowrap; }

/* --- Field history timeline (multi-document consolidation) ---------------- */
.cm-history { margin-top: .4rem; }
.cm-history__toggle { font-size: var(--cm-fs-78); color: var(--cm-blue-slate); cursor: pointer;
    list-style: disclosure-closed; user-select: none; }
details[open] > .cm-history__toggle { list-style: disclosure-open; }
.cm-history__rows { display: flex; flex-direction: column; gap: .15rem; padding: .25rem 0 .1rem; }
/* Structured history timeline (2026-07-15): the flat "old → new · doc · date" run-on line was
   unreadable — one row per change, columns Effective | Change | Source document. */
.cm-history__table { margin: var(--cm-space-2) 0 var(--cm-space-2); border-collapse: collapse; font-size: var(--cm-fs-78); }
.cm-history__th { text-align: left; padding: .2rem var(--cm-space-4) .2rem 0; color: var(--cm-text-muted);
    font-weight: 500; border-bottom: 1px solid var(--cm-border); }
.cm-history__td { padding: .25rem var(--cm-space-4) .25rem 0; vertical-align: top; }
.cm-history__date { color: var(--cm-text-muted); white-space: nowrap; }
.cm-history__old { color: var(--cm-text-muted); }
.cm-history__arrow { color: var(--cm-text-muted); padding: 0 .15rem; }
/* Source-document link (field grounding + history): same quiet size as .cm-page, but clickable. */
.cm-srclink { color: var(--cm-blue-slate); text-decoration: none; }
.cm-srclink:hover { text-decoration: underline; }
/* Dossier processing banner (2026-07-15): after filing, the page opened on "Pending/0 facts"
   with the only sign of life below the fold — this banner states, at the top, that extraction
   is running and the page updates itself. Shown only while the poll is active. */
.cm-processing { display: flex; align-items: flex-start; gap: var(--cm-space-4);
    margin: var(--cm-space-5) 0; padding: var(--cm-space-4) var(--cm-space-5);
    background: var(--cm-tint-cool); border: 1px solid var(--cm-border); border-radius: var(--cm-radius);
    color: var(--cm-text); font-size: var(--cm-fs-90); }
.cm-processing__spinner { width: 1rem; height: 1rem; flex-shrink: 0; margin-top: .15rem;
    border: 2px solid var(--cm-border); border-top-color: var(--cm-blue-slate); border-radius: 50%;
    animation: cm-spin .9s linear infinite; }
@keyframes cm-spin { to { transform: rotate(360deg); } }

/* Copy-quote icon button next to the evidence quote. */
.cm-copy { display: inline-flex; align-items: center; justify-content: center; width: 1.5rem; height: 1.5rem;
    margin-left: var(--cm-space-2); padding: 0; border: 0; background: none; color: var(--cm-text-muted);
    cursor: pointer; border-radius: var(--cm-radius-sm); vertical-align: middle; }
.cm-copy:hover { color: var(--cm-blue-slate); background: var(--cm-tint); }
.cm-copy svg { width: .9rem; height: .9rem; }
.cm-history__row { display: flex; gap: .3rem; flex-wrap: wrap; font-size: var(--cm-fs-78);
    color: var(--cm-text-muted); align-items: baseline; }

/* --- Required-field gating (upload review) --------------------------------- */
.cm-req { color: var(--cm-danger); font-weight: 700; margin-left: .15rem; }
.cm-error-inline { display: inline-block; margin-left: .5rem; font-size: var(--cm-fs-78); font-weight: 600; color: var(--cm-danger); }
.cm-panel--warn { border-left: 3px solid var(--cm-danger); background: var(--cm-danger-tint); }
.cm-panel--warn label { display: inline-flex; align-items: center; gap: .4rem; margin-top: .4rem; font-weight: 500; }

/* --- Contracts list: KPIs, clickable rows, expiry highlight --------------- */
.cm-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: .75rem; margin-bottom: var(--cm-stack); }
.cm-kpi { padding: .95rem 1.05rem; display: flex; flex-direction: column; gap: .35rem; }
.cm-kpi__num { font-size: 1.7rem; font-weight: 700; color: var(--cm-text); line-height: 1; letter-spacing: -.01em; }
.cm-kpi__label { font-size: var(--cm-fs-72); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--cm-text-muted); }

.cm-table--rows tbody tr.cm-rowlink { cursor: pointer; }
.cm-table--rows tbody tr.cm-rowlink:hover { background: var(--cm-bg); }

.cm-days--over { color: var(--cm-danger); font-weight: 700; }
.cm-days--soon { color: var(--cm-danger); font-weight: 600; }
.cm-days--warn { color: var(--cm-warn); font-weight: 600; }

/* --- About page (branded) -------------------------------------------------- */
.cm-about { max-width: 1020px; margin: 0 auto; }

.cm-about__hero { position: relative; overflow: hidden; border-radius: calc(var(--cm-radius) * 1.6);
    background:
        radial-gradient(120% 140% at 12% -10%, var(--cm-sidebar-active) 0%, transparent 55%),
        linear-gradient(135deg, #20332f 0%, #1a2a2c 60%, #16221f 100%);
    color: #eef3f1; padding: 3.2rem 3rem 2.8rem; box-shadow: 0 20px 50px rgba(20,32,30,.28); }
.cm-about__halo { position: absolute; inset: auto -8% -55% auto; width: 26rem; height: 26rem; right: -6%;
    background: radial-gradient(circle, rgba(180,206,179,.45) 0%, rgba(180,206,179,0) 68%);
    filter: blur(8px); pointer-events: none; }
.cm-about__hero::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .5;
    background-image: radial-gradient(rgba(255,255,255,.045) 1px, transparent 1px); background-size: 4px 4px; }
.cm-about__heroinner { position: relative; z-index: 1; }
@keyframes cm-about-rise { to { opacity: 1; transform: none; } }

.cm-about__eyebrow { display: inline-block; font-size: var(--cm-fs-72); font-weight: 600; letter-spacing: .22em;
    text-transform: uppercase; color: var(--cm-celadon); margin-bottom: .9rem; }
.cm-about__title { font-weight: 700; font-size: clamp(2.2rem, 5vw, 3.2rem); line-height: 1.04; letter-spacing: -.02em;
    margin: 0 0 .9rem; color: #f6f9f7; }
.cm-about__lede { max-width: 40ch; margin: 0 0 1.5rem; font-size: var(--cm-fs-110); line-height: 1.55; color: #c7d6d1; }
.cm-about__version { display: inline-block; font-family: var(--cm-font-mono);
    font-size: var(--cm-fs-78); color: var(--cm-celadon); border: 1px solid rgba(180,206,179,.4);
    border-radius: 2rem; padding: .3rem .85rem; }

.cm-about__facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem;
    margin: -1.4rem 1.2rem 0; position: relative; z-index: 2; }
.cm-about__fact { padding: .9rem 1.1rem; display: flex; flex-direction: column; gap: .25rem; }
.cm-about__fact-k { font-size: var(--cm-fs-72); letter-spacing: .12em; text-transform: uppercase; color: var(--cm-text-muted); }
.cm-about__fact-v { font-weight: 600; color: var(--cm-text); }

.cm-about__sectiontitle { font-weight: 700; font-size: 1.4rem; letter-spacing: -.01em;
    color: var(--cm-text); margin: 2.4rem 0 1rem; }
.cm-about__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1.1rem; }
.cm-about__card { position: relative; padding: 1.4rem 1.3rem 1.3rem;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.cm-about__card::before { content: ""; position: absolute; left: 0; top: 0; height: 3px; width: 2.6rem;
    border-radius: 0 0 3px 0; background: linear-gradient(90deg, var(--cm-blue-slate), var(--cm-celadon)); }
.cm-about__card:hover { transform: translateY(-3px); box-shadow: var(--cm-shadow-hover); border-color: var(--cm-cool-steel); }
.cm-about__icon { width: 26px; height: 26px; color: var(--cm-blue-slate); margin-bottom: .7rem; }
.cm-about__card h3 { margin: 0 0 .4rem; font-size: var(--cm-fs-100); color: var(--cm-text); }

.cm-about__footer { display: flex; align-items: center; justify-content: center; gap: .5rem; flex-wrap: wrap;
    margin: 2.4rem 0 .5rem; font-size: var(--cm-fs-85); color: var(--cm-text-muted); }
.cm-about__dot { opacity: .5; }

/* --- Eval harness --------------------------------------------------------- */
.cm-metric { display: inline-flex; flex-direction: column; gap: .15rem; margin-right: 1.5rem; }
.cm-metric__value { font-size: 1.4rem; font-weight: 600; color: var(--cm-blue-slate); }
.cm-cell--miss { background: var(--cm-danger-tint); }

/* --- License banner -------------------------------------------------------- */
.cm-licbanner { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
    padding: var(--cm-space-3) 1rem; margin-bottom: 1.1rem; border-radius: var(--cm-radius-sm);
    border: 1px solid var(--cm-border); font-size: var(--cm-fs-90); }
.cm-licbanner a { font-weight: 600; }
.cm-licbanner--warn   { background: var(--cm-dust-grey); color: var(--cm-text); }
.cm-licbanner--danger { background: var(--cm-petal-frost); color: var(--cm-petal-ink); border-color: var(--cm-petal-border); }

/* ---- Fact-graph deal views ---- */
/* .cm-factpage / .cm-factpage__title (ghost scaffold, never had CSS rules) and .cm-factpage__lead
   retired T5.5/B7: Dossiers/DossierDetail now use the app's standard h1/.cm-lead scaffold like
   every other page. .cm-form-grid stays - still used by Cockpit's column-picker checkbox grid
   (a genuinely different grid-of-checkboxes layout, not a form-field scaffold). */
.cm-card__title { font-size: var(--cm-fs-100); font-weight: 600; margin: 0 0 .75rem; color: var(--cm-text); }
.cm-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: .75rem 1rem; margin-bottom: 1rem; }
.cm-inline-create { display: flex; gap: .5rem; align-items: center; }
.cm-inline-create .cm-input { flex: 1 1 auto; min-width: 0; }
/* Search page's query bar reuses the inline row (input grows, button stays natural size —
   the former .cm-filters grid stretched the Search button across the remaining row width). */
.cm-searchbar { margin-bottom: 1.1rem; }
/* A small action beside a card title (Explorer inbox "Refresh") needs a gap to the text. */
.cm-card__title .cm-button { margin-left: var(--cm-space-3); }
.cm-link { color: var(--cm-blue-slate); font-weight: 500; text-decoration: none; }
.cm-link:hover { text-decoration: underline; }
.cm-derived { font-size: var(--cm-fs-110); }
/* T6.2 / C2: "pending" is a calm teaching state (e.g. "Pending — no anchor date yet"), not an
   error — it was sitting on --cm-danger (red) before; muted text matches its actual meaning. */
.cm-pending { color: var(--cm-text-muted); font-weight: 500; }
/* Button variant policy (T5.3 / B5, see the canonical comment at .cm-button--ghost): soft is the
   tertiary action - lower emphasis than ghost, used for calmer secondary actions (Move, Remove,
   Change) that sit beside a primary .cm-button in the same row/card. */
.cm-button--soft { background: var(--cm-dust-grey); color: var(--cm-text); }
/* .cm-alert--ok, .cm-badge--manual/--derived/--contract/--conflict/--end moved to the
   "Badges / lamps" section (T3.1 / A5) — grouped there with their duplicate-pair siblings. */

/* ---- Portfolio cockpit group header ---- */
/* Group header slim strip (redesign 2026-07-14): a small muted label row instead of a full-height band —
   background reuses --cm-tint, the existing "subtle selected/hover fill" token. */
/* .cm-lamp base + modifiers moved to the "Badges / lamps" section (T3.1 / A5) */

/* ---- Assistant (grounded chat) ---- */
/* Session sidebar + main pane, re-homed here from a chronological-append tail location (T3.1 / A5
   "chat to chat" re-home) — this is the outer layout for the whole Assistant page. */
.cm-chat-layout { display: grid; grid-template-columns: 240px 1fr; gap: 0 1.4rem; align-items: stretch; flex: 1; min-height: 0; }
.cm-chat-main { min-width: 0; display: flex; flex-direction: column; min-height: 0; }
.cm-chat-sessions { display: flex; flex-direction: column; gap: var(--cm-space-3); }
.cm-chat-sessions__new { width: 100%; }
.cm-chat-sessions__list { gap: .3rem; max-height: 32rem; overflow-y: auto; }
.cm-chat-sessions__item { width: 100%; text-align: left; background: var(--cm-surface); border: 1px solid var(--cm-border);
    border-radius: var(--cm-radius-sm); padding: .5rem var(--cm-space-4); cursor: pointer; display: flex; flex-direction: column; gap: .15rem; }
.cm-chat-sessions__item:hover { border-color: var(--cm-cool-steel); }
.cm-chat-sessions__item:disabled { cursor: default; opacity: .6; }
.cm-chat-sessions__item--active { background: var(--cm-dust-grey); border-color: var(--cm-blue-slate); }
.cm-chat-sessions__title { font-weight: 500; color: var(--cm-text); }
.cm-chat-sessions__meta { font-size: var(--cm-fs-78); color: var(--cm-text-muted); }

/* Page root (redesign 2026-07-14): h1 + lead stay in normal flow at top; the chat grid below fills the
   REMAINING .cm-main height (the app shell is height-locked — .cm-main itself scrolls, this page's own
   content should not need to). */
.cm-chat-page { display: flex; flex-direction: column; height: 100%; min-height: 0; }
/* One card, flex column: messages scroll internally (flex:1; min-height:0; overflow-y:auto below),
   composer stays pinned at the bottom. */
.cm-chat-canvas { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.cm-chat { display: flex; flex-direction: column; gap: .9rem; flex: 1; min-height: 0; overflow-y: auto; }
.cm-chat__msg { display: flex; flex-direction: column; max-width: 42rem; }
.cm-chat__msg--user { align-items: flex-end; align-self: flex-end; }
.cm-chat__msg--assistant { align-items: flex-start; align-self: flex-start; }
.cm-chat__bubble { border-radius: var(--cm-radius); padding: var(--cm-space-4) .9rem; box-shadow: var(--cm-shadow);
    white-space: pre-wrap; word-break: break-word; }
.cm-chat__msg--user .cm-chat__bubble { background: var(--cm-blue-slate); color: var(--cm-text-inverse); }
.cm-chat__msg--assistant .cm-chat__bubble { background: var(--cm-surface); border: 1px solid var(--cm-border); }
.cm-chat__composer { display: flex; gap: var(--cm-space-3); align-items: flex-start; flex: none;
    border-top: 1px solid var(--cm-border); padding-top: .9rem; margin-top: .9rem; }
.cm-chat__composer .cm-input { flex: 1 1 auto; resize: vertical; }

/* Canvas empty state (redesign 2026-07-14): centered teaching block instead of a lone floating sentence. */
.cm-chat__emptystate { display: flex; flex-direction: column; align-items: center; justify-content: center;
    text-align: center; flex: 1; min-height: 0; gap: .35rem; padding: 2rem 1rem; }
.cm-chat__emptyicon { width: 40px; height: 40px; color: var(--cm-text-muted); opacity: .7; margin-bottom: .4rem; }
.cm-chat__emptylead { margin: 0; color: var(--cm-text-muted); }
.cm-chat__examples { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; margin-top: var(--cm-stack); max-width: 42rem; }
.cm-chat__examplechip { border: none; cursor: pointer; font: inherit; }
.cm-chat__examplechip:hover { background: var(--cm-tint); }

/* ---- Dossier type badge + completeness card / pill (Task 10) ---- */
.cm-typebadge { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cm-space-3); margin: -.3rem 0 1rem; }
.cm-typebadge__editor { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
/* .cm-badge--type moved to the "Badges / lamps" section (T3.1 / A5), grouped with --derived */

.cm-completeness__stat { font-weight: 600; font-size: var(--cm-fs-100); margin: 0 0 var(--cm-space-3); }
.cm-completeness__list { gap: var(--cm-space-3); }
.cm-completeness__row { display: flex; align-items: center; justify-content: space-between; gap: .75rem;
    flex-wrap: wrap; padding: .5rem 0; border-top: 1px solid var(--cm-border); }
.cm-completeness__row:first-child { border-top: 0; padding-top: 0; }
.cm-completeness__field { display: flex; align-items: baseline; gap: .5rem; }
.cm-completeness__label { font-weight: 500; }
.cm-completeness__entry { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.cm-completeness__optional { margin-top: .75rem; font-size: var(--cm-fs-85); color: var(--cm-text-muted); }
.cm-completeness__optional summary { cursor: pointer; }
.cm-completeness__pill { background: var(--cm-dust-grey); color: var(--cm-text); font-variant-numeric: tabular-nums; }

/* ---- Derived-value formula chip + shadowed-snapshot surfacing (Task 9, event anchors) ---- */
.cm-chip { display: inline-flex; flex-direction: column; gap: .35rem; margin-left: .5rem;
    padding: .35rem var(--cm-space-3); border-radius: var(--cm-radius-sm); background: var(--cm-dust-grey);
    font-size: var(--cm-fs-78); color: var(--cm-text-muted); vertical-align: top; }
.cm-chip__formula { font-family: var(--cm-font-mono); color: var(--cm-text); }
.cm-chip__shadow { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
    padding-top: .35rem; border-top: 1px dashed var(--cm-border); color: var(--cm-danger); }
.cm-chip__shadow-actions { display: flex; gap: .5rem; }

/* Condition status segmented control (Open / Met), reusing the chip surface */
.cm-chip--segment { flex-direction: row; display: inline-flex; padding: .15rem; gap: 0; }
.cm-chip__seg { border: 0; background: transparent; padding: .3rem .7rem; border-radius: var(--cm-radius-sm);
    font-size: var(--cm-fs-78); font-weight: 500; color: var(--cm-text-muted); cursor: pointer; }
.cm-chip__seg--active { background: var(--cm-surface); color: var(--cm-text); box-shadow: var(--cm-shadow); }

/* ---- Dossier type field editor: derivation rule sub-row (Task 8, event anchors) ---- */
.cm-fieldrule { display: flex; flex-wrap: wrap; align-items: flex-start; gap: .75rem 1.5rem; }
.cm-fieldrule .cm-form__field { min-width: 12rem; gap: .3rem; }
/* Quiet underline tabs (first user: the partner dialog's Partner/Contacts split — the single
   scrolling form buried the contacts editor below the fold). */
.cm-tabs { display: flex; gap: var(--cm-space-5); border-bottom: 1px solid var(--cm-border); margin-bottom: var(--cm-space-5); }
.cm-tabs__tab { border: 0; background: none; padding: var(--cm-space-2) var(--cm-space-1) var(--cm-space-3);
    margin-bottom: -1px; font: inherit; font-size: var(--cm-control-fs); font-weight: 500; cursor: pointer;
    color: var(--cm-text-muted); border-bottom: 2px solid transparent; }
.cm-tabs__tab:hover { color: var(--cm-blue-slate); }
.cm-tabs__tab--active { color: var(--cm-blue-slate); border-bottom-color: var(--cm-blue-slate); font-weight: 600; }
/* Tab pane with a floor height, so switching tabs never resizes the dialog under the cursor. */
.cm-tabpane { min-height: 21rem; }

/* Contact editor rows in the partner dialog: one bordered card per contact with a labeled 2×2
   field grid — four inputs squeezed into table columns were unusably narrow in an md dialog. */
.cm-contactrow { border: 1px solid var(--cm-border); border-radius: var(--cm-radius-sm);
    padding: var(--cm-space-4); margin-bottom: var(--cm-space-4); }
.cm-contactrow__head { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--cm-space-3); }
.cm-contactrow__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--cm-space-3) var(--cm-space-5); }

/* Two related rule inputs side by side in the field editor (notify lead + fallback). */
.cm-fieldrule__pair { display: flex; gap: var(--cm-space-5); flex-wrap: wrap; margin-bottom: var(--cm-space-4); }
.cm-fieldrule__pair .cm-form__field { flex: 1 1 14rem; }
}

/* --- Utilities (single-purpose helper classes + place-specific overrides) ---- */
@layer utilities {
/* .cm-mt is no longer a private ad hoc patch value (T3.4 / A8) - it now resolves to the
   canonical section rhythm, same as every other selector in this unification. */
.cm-mt { margin-top: var(--cm-stack); }
.cm-panel { max-width: 40rem; margin: var(--cm-space-page) auto; }
.cm-form--wide { max-width: none; }
/* caption/footnote under a table or list (e.g. "X of Y shown") */
.cm-table-note { color: var(--cm-text-muted); font-size: var(--cm-fs-85); margin: .7rem 0 0; }
/* "working…" indicator (e.g. while re-extracting) */
.cm-busy { color: var(--cm-text-muted); font-style: italic; animation: cm-busy-pulse 1.1s ease-in-out infinite; }
@keyframes cm-busy-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

/* .cm-truncate utility (T3.2 / A6, merge-candidate #7): single-line ellipsis truncation,
   byte-identical across .cm-explorer__label, .cm-runlog__detail, .cm-chat-sessions__title -
   grouped once; each keeps its own unique declarations in its topical (components-layer) rule. */
.cm-truncate, .cm-explorer__label, .cm-runlog__detail, .cm-chat-sessions__title {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* .cm-hint did not exist anywhere in app.css — added here as it's used across
   the Explorer content panel for secondary/explanatory text under a heading. */
.cm-hint { color: var(--cm-text-muted); font-size: var(--cm-fs-85); }

/* .cm-microlabel utility (T3.2 / A6, merge-candidate #4): .cm-detail dt, .cm-metric__label and
   .cm-completeness__kind were byte-identical uppercase micro-labels - grouped once here. Near
   siblings (.cm-stat__label, .cm-kpi__label, .cm-admin__group-label, .cm-about__fact-k) keep
   their own slightly different values; those get tokenized onto the type scale in T3.3. */
.cm-microlabel, .cm-detail dt, .cm-metric__label, .cm-completeness__kind {
    color: var(--cm-text-muted); font-size: var(--cm-fs-78); text-transform: uppercase; letter-spacing: .03em;
}

/* --- Place-specific overrides (T7.1 / D2) --------------------------------------
   These selectors are more specific compositions that need to beat a shared components-layer
   base rule in one particular place (a cockpit cell, a missing-row highlight, an about-page
   stagger, a notification row, a field-rule row) — exactly the "descending specificity" shape
   the stylelint gate previously flagged 13 times, because the override sat later in the file at
   EQUAL OR LOWER specificity than the base rule it was overriding. Cascade layers fix this
   category outright: this layer is declared last, so every rule here wins over its components-
   layer base regardless of selector specificity or file order — no line-reordering needed, and
   no risk of a future edit accidentally undoing a fragile specificity ordering. */

/* Compact cockpit table cells (redesign 2026-07-14; densified 2026-07-15 — with a 20-field type
   the old 16rem/roomy-padding cells forced three screens of horizontal scroll, which is the
   opposite of a cockpit): tighter padding, smaller type, narrower cap, and HEADERS may wrap to
   two lines instead of dictating the column width. */
.cm-cockpit__table th, .cm-cockpit__table td { white-space: nowrap; max-width: 11rem; overflow: hidden; text-overflow: ellipsis;
    padding: var(--cm-space-2) var(--cm-space-3); font-size: var(--cm-fs-85); }
/* Headers stay ONE line (wrapping produced ragged multi-height headers) — long labels truncate
   with an ellipsis; the full name is in the tooltip. */
.cm-cockpit__table thead th { font-size: var(--cm-fs-72); }

/* Missing-required-field row highlight overrides the base .cm-table row border-bottom cadence. */
.cm-row--missing > td { background: var(--cm-danger-tint); }

/* About-page hero stagger-in animation overrides .cm-collapse's generic ">*:first-of-type" margin
   reset for the (unrelated, but selector-overlapping) hero children. */
.cm-about__heroinner > * { opacity: 0; transform: translateY(12px); animation: cm-about-rise .6s cubic-bezier(.2,.7,.2,1) forwards; }
.cm-about__heroinner > *:nth-child(1) { animation-delay: .05s; }
.cm-about__heroinner > *:nth-child(2) { animation-delay: .14s; }
.cm-about__heroinner > *:nth-child(3) { animation-delay: .23s; }
.cm-about__heroinner > *:nth-child(4) { animation-delay: .32s; }

/* About-card body copy overrides the reconnect-modal's generic "p" reset (never actually
   co-rendered — same page never shows both — but the selectors overlap enough to trip the linter). */
.cm-about__card p { margin: 0; font-size: var(--cm-fs-90); line-height: 1.5; color: var(--cm-text-muted); }

/* Cockpit group-header row overrides the base .cm-table thead th treatment (it is itself a
   <th>, styled as a slim label strip instead of the column-header banner). */
.cm-cockpit__table .cm-cockpit__group th { background: var(--cm-tint); color: var(--cm-text-muted); font-size: var(--cm-fs-78); max-width: none;
    font-weight: 600; padding: .3rem .75rem; text-align: left; }

/* Unread notification row overrides the base .cm-table row treatment with bold text. */
.cm-notif--unread td { font-weight: 600; }

/* Dossier-type field editor's inline derivation-rule sub-row overrides the base .cm-table row
   background with the shared "subtle fill" tint. */
.cm-fieldrule-row td { background: var(--cm-tint); }

/* --- Responsive --------------------------------------------------------------
   Single breakpoint (T3.5 / A9, 2026-07-14 CSS assessment): the shell-collapse rules moved
   here from their own 820px query (the 80px gap to the explorer's breakpoint encoded no design
   decision) and merged with the Explorer's collapse rules - one 900px breakpoint for the whole
   app. Lives in the utilities layer (last) because its overrides span both the layout layer
   (.cm-body/.cm-sidebar/.cm-main) and the components layer (.cm-2col/
   .cm-admin__body/.cm-admin__nav/.cm-chat-layout/.cm-explorer/.cm-explorer__tree) — a layer
   earlier than components could never win against a components-layer base rule, media query
   or not, so this has to be the last-declared layer to correctly override everything it targets. */
@media (max-width: 900px) {
    .cm-body { flex-direction: column; }
    .cm-sidebar { width: auto; flex-direction: row; flex-wrap: wrap; gap: .25rem; }
    .cm-main { padding: 1.25rem 1.1rem; }
    .cm-2col { grid-template-columns: 1fr; }
    .cm-admin__body { grid-template-columns: 1fr; gap: 1.25rem; }
    .cm-admin__nav { position: static; flex-direction: row; flex-wrap: wrap; gap: .75rem 1.25rem; }
    .cm-chat-layout { grid-template-columns: 1fr; }
    .cm-explorer { grid-template-columns: 1fr; }
    .cm-explorer__tree { position: static; }
}
}
