/* IFRS 9 ECL Copilot — App v3 "The Modern Risk Platform" (FINAL_SPEC.md, binding judge decision: fintech + 5 grafts). Two token layers: the validated dataviz chart/data layer (categorical/status/diverging hues, fixed slot order — see palette.js) and the UI chrome layer below, which replaces the previous styles.css tokens outright. Light is the OS default; dark mirrors via prefers-color-scheme, with [data-theme] overrides reserved for a future manual toggle. */ :root { /* categorical (fixed order — identity, never rank; FINAL_SPEC §1.2) */ --cat-1: #2a78d6; /* blue */ --cat-2: #008300; /* green */ --cat-3: #e87ba4; /* magenta */ --cat-4: #eda100; /* yellow */ --cat-5: #1baf7a; /* aqua */ --cat-6: #eb6834; /* orange */ --cat-7: #4a3aa7; /* violet */ --cat-8: #e34948; /* red */ /* status (reserved — never reused for series identity) */ --status-good: #0ca30c; --status-warning: #fab219; --status-serious: #ec835a; --status-critical: #d03b3b; /* chrome (FINAL_SPEC §1.1) */ --page: #f9f9f7; --panel: #fcfcfb; --panel-2: #ffffff; --border: rgba(11, 11, 11, 0.10); --border-strong: rgba(11, 11, 11, 0.16); --ink: #0b0b0b; --ink-2: #52514e; --ink-3: #898781; --grid: #e1e0d9; --baseline: #c3c2b7; --accent: #2a78d6; --accent-solid: #1c5cab; --accent-on-solid: #ffffff; --accent-text: #1c5cab; --accent-wash: rgba(42, 120, 214, 0.08); --increase: var(--accent); --decrease: #e34948; --level-fill: #52514e; --good: #0ca30c; --good-text: #006300; --critical: #d03b3b; --critical-text: #d03b3b; --warning: #fab219; --serious: #ec835a; --good-wash: rgba(0, 99, 0, 0.10); --critical-wash: rgba(208, 59, 59, 0.10); --shadow-e1: 0 1px 2px rgba(11, 11, 11, .06); --shadow-e2: 0 8px 24px rgba(11, 11, 11, .12); /* back-compat aliases still referenced by a few components */ --surface: var(--panel); --line: var(--border); --ink-muted: var(--ink-2); --axis-muted: var(--ink-3); --warn: var(--decrease); --sans: -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, system-ui, sans-serif; --mono: ui-monospace, "SFMono-Regular", "Cascadia Code", Consolas, "Liberation Mono", Menlo, monospace; --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px; --sp-12: 48px; --sp-16: 64px; --radius-sm: 6px; --radius-md: 10px; --radius-pill: 999px; } @media (prefers-color-scheme: dark) { :root { --cat-1: #3987e5; --cat-2: #008300; --cat-3: #d55181; --cat-4: #c98500; --cat-5: #199e70; --cat-6: #d95926; --cat-7: #9085e9; --cat-8: #e66767; --page: #0d0d0d; --panel: #1a1a19; --panel-2: #232322; --border: rgba(255, 255, 255, 0.10); --border-strong: rgba(255, 255, 255, 0.16); --ink: #ffffff; --ink-2: #c3c2b7; --ink-3: #898781; --grid: #2c2c2a; --baseline: #383835; --accent: #3987e5; --accent-solid: #3987e5; --accent-on-solid: #0b0b0b; --accent-text: #3987e5; --accent-wash: rgba(57, 135, 229, 0.10); --increase: var(--accent); --decrease: #e66767; --level-fill: #c3c2b7; --good: #0ca30c; --good-text: #0ca30c; --critical: #d03b3b; --critical-text: #e66767; --good-wash: rgba(12, 163, 12, 0.14); --critical-wash: rgba(230, 103, 103, 0.14); --shadow-e1: 0 1px 2px rgba(0, 0, 0, .36); --shadow-e2: 0 8px 24px rgba(0, 0, 0, .5); } } /* explicit manual-toggle overrides (win over the media query either way) */ :root[data-theme='dark'] { color-scheme: dark; } :root[data-theme='light'] { color-scheme: light; } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: var(--sans); font-size: 14px; line-height: 1.5; color: var(--ink); background: var(--page); -webkit-font-smoothing: antialiased; } button, input, select { font-family: inherit; color: inherit; } .num { font-variant-numeric: tabular-nums; color: var(--ink); } :focus-visible { outline: none; box-shadow: 0 0 0 2px var(--page), 0 0 0 4px var(--accent); border-radius: var(--radius-sm); } /* -------------------------------------------------------------- app shell */ .app-shell { max-width: 1180px; margin: 0 auto; min-height: 100vh; } .app-header { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: var(--sp-6); flex-wrap: wrap; padding: 14px var(--sp-6); background: var(--page); border-bottom: 1px solid var(--border); } .brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; } .brand-mark { width: 26px; height: 26px; border-radius: 7px; background: var(--accent); color: var(--accent-on-solid); display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; flex-shrink: 0; } .brand-name { font-size: 16px; font-weight: 600; color: var(--ink); white-space: nowrap; } /* Header brand-row link to the static Model Development Document, opened in a new tab (app/ui/src/app.jsx) -- a small pill next to the wordmark, never competing with the primary tab nav for attention. */ .mdd-link { font-size: 11px; font-weight: 700; letter-spacing: 0.04em; color: var(--ink-3); border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 3px 9px; text-decoration: none; white-space: nowrap; } .mdd-link:hover { color: var(--accent-text); border-color: var(--accent); } .grounded-badge { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3); border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 4px 10px; white-space: nowrap; } .grounded-badge .status-dot { background: var(--good); width: 6px; height: 6px; } .header-meta { margin-left: auto; font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; } .tab-nav { display: flex; gap: var(--sp-6); flex-wrap: wrap; border-bottom: 1px solid var(--border); padding: 0 var(--sp-6); background: var(--page); } .tab-btn { border: none; background: transparent; color: var(--ink-2); font-size: 14px; font-weight: 500; padding: 12px 0; margin-bottom: -1px; border-bottom: 2px solid transparent; cursor: pointer; transition: color 0.12s ease, border-color 0.12s ease; } .tab-btn:hover { color: var(--ink); } .tab-btn.active { color: var(--ink); font-weight: 600; border-bottom-color: var(--accent); } .app-main { padding: var(--sp-6) var(--sp-6) 160px; } .tab-body { display: flex; flex-direction: column; gap: 20px; max-width: 1080px; margin: 0 auto; } .tab-intro h1 { font-size: 24px; font-weight: 700; line-height: 1.2; color: var(--ink); margin-bottom: 4px; letter-spacing: -0.01em; } .tab-intro p { color: var(--ink-2); font-size: 14px; max-width: 760px; } /* ----------------------------------------------------------------- tiles */ .tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; } @media (max-width: 900px) { .tiles { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 620px) { .tiles { grid-template-columns: 1fr; } } .tile { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 18px 18px 16px; box-shadow: var(--shadow-e1); display: flex; flex-direction: column; } .tile-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; } .tile-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3); } .tile-value { font-size: 32px; font-weight: 600; line-height: 1.1; letter-spacing: -0.01em; color: var(--ink); font-variant-numeric: normal; margin-top: 6px; } .tile-hint { font-size: 13px; color: var(--ink-2); margin-top: 4px; } .tile-delta { font-size: 12px; font-weight: 600; margin-top: 6px; font-variant-numeric: tabular-nums; border-radius: var(--radius-pill); padding: 2px 8px; display: inline-flex; width: fit-content; gap: 4px; } .tile-delta-good { color: var(--good-text); background: var(--good-wash); } .tile-delta-bad { color: var(--critical-text); background: var(--critical-wash); } /* ----------------------------------------------------------------- panel */ .panel { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 20px; box-shadow: var(--shadow-e1); } .panel h2 { font-size: 16px; font-weight: 600; line-height: 1.35; color: var(--ink); } .panel h3 { font-size: 13px; font-weight: 700; color: var(--ink); margin: 14px 0 6px; } .panel-kicker-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 28px; margin-bottom: 2px; } .exhibit-kicker { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent-text); } .panel-actions { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; } .panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; } .panel-sub { color: var(--ink-2); font-size: 13px; margin: 3px 0 12px; line-height: 1.5; } .panel-source { font-size: 11px; color: var(--ink-3); font-family: var(--mono); margin-top: 10px; } .panel-source code { font-family: var(--mono); } .panel-hr { border-top: 1px solid var(--border); margin: 12px 0; } .chart-caveat { font-size: 12px !important; margin: 10px 0 0 !important; } .chart-legend-row { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12px; color: var(--ink-2); margin-top: 10px; } .preamble { white-space: pre-line; } .chart { width: 100%; height: 300px; } .chart-tall { height: 340px; } .empty-note { color: var(--ink-2); font-size: 13px; padding: 10px 0; list-style: none; } .chip-row { display: flex; flex-wrap: wrap; gap: 8px; } .chip { font: inherit; font-size: 13px; color: var(--ink-2); background: transparent; border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 6px 12px; cursor: pointer; text-align: left; } .chip:hover { color: var(--ink); border-color: var(--accent); } /* -------------------------------------------------------------- controls */ .segmented { display: flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; } .segmented button { border: none; background: var(--panel); color: var(--ink-2); font-size: 12.5px; font-weight: 500; padding: 6px 12px; cursor: pointer; } .segmented button + button { border-left: 1px solid var(--border); } .segmented button.active { background: var(--accent-solid); color: var(--accent-on-solid); } .control-row { display: flex; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; align-items: center; } .control-row label { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-2); } .control-row input[type='number'] { width: 64px; padding: 4px 6px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--panel-2); color: var(--ink); } select { padding: 6px 8px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--panel-2); color: var(--ink); font-size: 13px; } .slider-row { display: grid; grid-template-columns: 88px 1fr 46px; align-items: center; gap: 8px; margin-bottom: 6px; } .slider-label { font-size: 13px; } .slider-value { font-variant-numeric: tabular-nums; font-size: 13px; text-align: right; color: var(--ink-2); } input[type='range'] { width: 100%; accent-color: var(--accent); } /* ---------------------------------------------------------------- buttons */ .btn { font-family: var(--sans); font-size: 14px; font-weight: 600; color: var(--accent-on-solid); background: var(--accent-solid); border: none; border-radius: var(--radius-sm); height: 36px; padding: 0 16px; cursor: pointer; margin-top: 6px; } .btn:hover:not(:disabled) { filter: brightness(1.08); } .btn:disabled { opacity: 0.45; cursor: not-allowed; } .btn-secondary { color: var(--ink); background: transparent; border: 1px solid var(--border); font-weight: 500; } .status { font-size: 13px; margin-top: 8px; } .status-ok { color: var(--good-text); } .status-err { color: var(--critical-text); } .muted { color: var(--ink-2); } /* ------------------------------------------------------------ status dots */ .status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex-shrink: 0; } .status-dot-good { background: var(--good); } .status-dot-warn { background: var(--warning); } .status-dot-crit { background: var(--critical); } .status-dot-muted { background: var(--ink-3); } /* REASONED: a cited interpretation, never a fresh engine number — its own hue (accent blue), distinct from good/warn/crit/muted so it never reads as either "grounded success" or "trouble". */ .status-dot-accent { background: var(--accent); } @media (prefers-reduced-motion: no-preference) { .status-dot-warn.pulse { animation: dot-pulse 1.1s ease-in-out infinite; } } @keyframes dot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } } /* ----------------------------------------------------- AI-explain affordance */ .explain-btn { width: 28px; height: 28px; border-radius: var(--radius-pill); border: none; background: transparent; color: var(--ink-3); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: color 0.12s ease, background 0.12s ease; flex-shrink: 0; } .explain-btn:hover { color: var(--accent); background: var(--panel-2); } .explain-btn[aria-expanded='true'] { color: var(--accent); background: var(--accent-wash); } /* Loading: 2px accent ring; pulse only without prefers-reduced-motion (§7.2) */ .explain-btn.loading { box-shadow: 0 0 0 2px var(--accent); } @media (prefers-reduced-motion: no-preference) { .explain-btn.loading { animation: dot-pulse 1.1s ease-in-out infinite; } } /* Hover/focus tooltip for icon-buttons carrying data-tip (§7.2) — an E2 mini-panel, --text-xs, rendered from the attribute so API strings never reach innerHTML. */ [data-tip] { position: relative; } [data-tip]:hover::after, [data-tip]:focus-visible::after { content: attr(data-tip); position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; background: var(--panel-2); color: var(--ink); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); box-shadow: var(--shadow-e2); font-size: 12px; font-weight: 500; line-height: 1.4; padding: 4px 8px; white-space: nowrap; pointer-events: none; } .icon-btn { width: 28px; height: 28px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--ink-2); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; font-size: 14px; transition: color 0.12s ease, background 0.12s ease; } .icon-btn:hover { color: var(--accent); background: var(--panel-2); } .icon-btn[aria-pressed='true'] { color: var(--accent); background: var(--accent-wash); } .tile-head .explain-btn { margin-top: -2px; } .explain-strip { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); display: flex; gap: 10px; align-items: flex-start; } .explain-avatar { width: 22px; height: 22px; border-radius: var(--radius-pill); background: var(--accent-wash); color: var(--accent); display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .explain-body { flex: 1; min-width: 0; } .explain-status { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3); margin-bottom: 4px; } .explain-text { font-size: 13px; color: var(--ink-2); line-height: 1.55; } /* ---------------------------------------------------------- selection-explain */ .selection-explain { position: fixed; z-index: 50; transform: translateX(-50%); max-width: min(360px, 80vw); } .selection-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--accent-on-solid); background: var(--accent-solid); border: none; border-radius: var(--radius-pill); padding: 7px 12px; cursor: pointer; box-shadow: var(--shadow-e2); white-space: nowrap; } .selection-chip:hover { filter: brightness(1.08); } .explain-strip-floating { background: var(--panel-2); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); box-shadow: var(--shadow-e2); padding: 14px; margin-top: 0; } /* --------------------------------------------------------------- tables */ .searchable-table { display: flex; flex-direction: column; gap: 4px; } .table-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; } .table-search { flex: 1; max-width: 320px; padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--panel-2); color: var(--ink); font-size: 13px; } .table-count { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; } .table-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); } .data-table { border-collapse: collapse; width: 100%; font-size: 13px; } .data-table th, .data-table td { padding: 0 10px; height: 44px; text-align: left; border-top: 1px solid var(--border); white-space: nowrap; } .data-table thead tr th { border-top: none; } .data-table th { background: var(--panel); color: var(--ink-3); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; border-bottom: 1px solid var(--border-strong); position: sticky; top: 0; } .data-table td { color: var(--ink-2); } .data-table .num-cell, .data-table td.num, .data-table th.num { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); } .data-table tbody tr:hover td { background: var(--panel-2); } .data-table .cap { text-transform: capitalize; } .data-table .family-row td { background: var(--panel); font-weight: 700; color: var(--accent-text); text-transform: uppercase; font-size: 10.5px; letter-spacing: 0.05em; white-space: normal; height: auto; padding: 10px; } .data-table .story-row td { white-space: normal; color: var(--ink-3); font-style: italic; font-size: 12px; border-bottom: 2px solid var(--border); height: auto; padding: 6px 10px 12px; } .data-table .hr-up { color: var(--critical-text); font-variant-numeric: tabular-nums; } .data-table .hr-down { color: var(--good-text); font-variant-numeric: tabular-nums; } .data-table .row-adopted td { background: var(--accent-wash); border-left: 2px solid var(--accent); font-weight: 600; } .data-table .row-adopted td:first-child { padding-left: 8px; } /* Scenario-row leading status dot (§5.3): 9px, name stays the label. */ .scenario-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; margin-right: 8px; vertical-align: baseline; } .scenario-dot-good { background: var(--good); } .scenario-dot-muted { background: var(--ink-3); } .scenario-dot-crit { background: var(--critical); } /* Δ-vs-base/adopted pill (§5.3): wash background, readable status text, ▲/▼ inside the same text run — one coherent string for screen readers. */ .delta-pill { display: inline-flex; align-items: center; border-radius: var(--radius-pill); padding: 2px 8px; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; } .delta-pill-good { color: var(--good-text); background: var(--good-wash); } .delta-pill-bad { color: var(--critical-text); background: var(--critical-wash); } .adopted-tag { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent-text); margin-left: 8px; } /* The backtest honesty panel's headline callout (Real Data tab, Exhibit 3): a big number + one sentence, critical-tinted -- the 9.42x GFC miss ratio needs to read before the table does. */ .callout { display: flex; align-items: baseline; gap: 14px; margin-bottom: 14px; padding: 14px 16px; border-radius: var(--radius-md); border: 1px solid var(--border); } .callout-crit { background: var(--critical-wash); border-color: var(--critical); } .callout-figure { font-size: 32px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--critical-text); white-space: nowrap; } .callout-text { font-size: 14px; color: var(--ink-2); line-height: 1.5; } /* Real Data tab's backtest panel is the centerpiece exhibit -- a slightly heavier accent border marks it out from the surrounding panels. */ .freddie-centerpiece { border-color: var(--accent); } .caveat-block { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; } .caveat { font-size: 13px; color: var(--ink-2); background: var(--page); border-left: 3px solid var(--accent); padding: 8px 12px; border-radius: 0 var(--radius-sm) var(--radius-sm) 0; line-height: 1.5; } .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 8px; } /* ---------------------------------------------------------- Requirement 12 macro/FRED interpretation: expandable coefficient rows, FRED badges, the "How to read" intro panel, and the macro-glossary collapsible panel. */ .row-expand-btn { font: inherit; background: transparent; border: none; color: var(--ink-3); cursor: pointer; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-sm); } .row-expand-btn:hover { color: var(--accent-text); background: var(--accent-wash); } .row-expand-caret { font-size: 11px; } .data-table tbody tr.row-open td { background: var(--accent-wash); } .data-table.coef-table tbody tr.coef-row { cursor: pointer; } .interp-row td { white-space: normal; height: auto; padding: 0; border-bottom: 2px solid var(--border); } .interp-body { padding: 12px 14px 14px 40px; background: var(--page); display: flex; flex-direction: column; gap: 6px; } .interp-tags { display: flex; gap: 6px; margin-bottom: 2px; } .interp-line { font-size: 13px; color: var(--ink-2); line-height: 1.5; margin: 0; } .interp-line b { color: var(--ink); } .interp-worked { font-weight: 500; color: var(--ink); background: var(--accent-wash); border-left: 3px solid var(--accent); padding: 6px 10px; border-radius: 0 var(--radius-sm) var(--radius-sm) 0; } .fred-badge { display: inline-flex; align-items: center; font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: var(--accent-text); background: var(--accent-wash); border: 1px solid var(--accent); border-radius: var(--radius-pill); padding: 2px 8px; white-space: nowrap; } .fred-badge-inline { margin-left: 8px; font-size: 9.5px; padding: 1px 6px; vertical-align: middle; } .lag-badge { display: inline-flex; align-items: center; font-size: 10.5px; color: var(--ink-3); background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 2px 8px; white-space: nowrap; } .macro-glossary { margin-top: 0; } .macro-glossary summary { font-weight: 600; } .coherent-shock-note { margin-bottom: 10px; } @media (max-width: 780px) { .two-col { grid-template-columns: 1fr; } } /* ------------------------------------------------------------- exhibits */ .exhibit-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; margin-top: 8px; } .exhibit { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px; background: var(--page); } .exhibit img { width: 100%; height: auto; border-radius: 4px; display: block; background: #fff; } .exhibit-title { font-size: 12.5px; font-weight: 700; color: var(--ink); margin-bottom: 6px; } .exhibit-caption { font-size: 11.5px; color: var(--ink-3); margin-top: 6px; line-height: 1.4; } .exhibit-missing { font-size: 12px; color: var(--critical-text); padding: 20px 0; text-align: center; } /* --------------------------------------------------------------- stages */ .stage-mix { display: flex; flex-direction: column; gap: 10px; } .stage-mix-bar { display: flex; width: 100%; height: 28px; border-radius: var(--radius-sm); overflow: hidden; border: 1px solid var(--border); } .stage-seg { display: flex; align-items: center; justify-content: center; color: #fff; font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; min-width: 2px; border-right: 2px solid var(--panel); } .stage-seg:last-child { border-right: none; } .stage-good, .legend-dot.stage-good { background: var(--status-good); } .stage-warn, .legend-dot.stage-warn { background: var(--status-warning); } .stage-crit, .legend-dot.stage-crit { background: var(--status-critical); } .stage-mix-legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12px; color: var(--ink-2); } .legend-item { display: inline-flex; align-items: center; gap: 6px; } .legend-dot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; } /* --------------------------------------------------------------- policy */ .decision-header { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; background: var(--accent-wash); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 12px; margin: 6px 0 14px; } .decision-tag { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent-text); white-space: nowrap; } .decision-text { font-size: 12.5px; color: var(--ink); } .overlay-note { font-size: 13px; color: var(--ink); line-height: 1.6; margin-bottom: 10px; } /* stage-horizon explainer */ .stage-guide { margin-top: 10px; font-size: 12.5px; color: var(--ink-2); border-top: 1px solid var(--border); padding-top: 8px; } .stage-guide summary { cursor: pointer; font-weight: 600; color: var(--ink); } .stage-guide ul { margin: 8px 0 6px 18px; padding: 0; } .stage-guide li { margin-bottom: 6px; line-height: 1.45; } .stage-guide p { margin: 4px 0 2px; line-height: 1.45; } /* ----------------------------------------------------------- scenario lab */ .scenario-grid { display: grid; grid-template-columns: 340px 1fr; gap: 16px; align-items: start; } .scenario-controls-col, .scenario-result-col { display: flex; flex-direction: column; gap: 14px; } @media (max-width: 900px) { .scenario-grid { grid-template-columns: 1fr; } } .result-card { display: flex; flex-direction: column; gap: 10px; } .result-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } .result-tool { font-family: var(--mono); font-size: 11px; background: var(--page); border: 1px solid var(--border); border-radius: 4px; padding: 2px 6px; color: var(--accent-text); } .result-label { font-size: 12.5px; color: var(--ink-2); } .result-headline { font-size: 13.5px; color: var(--ink); line-height: 1.5; } .result-metrics { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12.5px; color: var(--ink-2); } .result-metrics b { color: var(--ink); font-variant-numeric: tabular-nums; } /* ------------------------------------------------------------ narrative */ .narrative-panel .narrative-text { font-size: 14px; line-height: 1.7; color: var(--ink); max-width: 860px; } /* -------------------------------------------------------- interpretation */ .interpretation { background: var(--page); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; } .interpretation-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; } .interpretation-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-3); } .badge-ground { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; border-radius: 3px; padding: 2px 7px; } .badge-ai { background: var(--accent-wash); color: var(--accent-text); } .badge-engine { background: var(--panel-2); color: var(--ink-3); border: 1px solid var(--border); } .interpretation-text { font-size: 13px; color: var(--ink); line-height: 1.55; } .interpretation-loading { font-size: 12.5px; color: var(--ink-2); display: flex; align-items: center; gap: 8px; } .spinner { width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--border); border-top-color: var(--accent); animation: spin 0.7s linear infinite; display: inline-block; } @media (prefers-reduced-motion: reduce) { .spinner { animation: none; } } @keyframes spin { to { transform: rotate(360deg); } } /* ----------------------------------------------------------- agent trace */ .conn { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3); display: inline-flex; align-items: center; gap: 5px; } .conn-live .status-dot { background: var(--good); } .conn-connecting .status-dot { background: var(--warning); } .conn-reconnecting .status-dot { background: var(--critical); } .trace-list { list-style: none; overflow-y: auto; max-height: 320px; font-size: 12.5px; border-top: 1px solid var(--border); } .trace-row { display: flex; gap: 8px; align-items: baseline; padding: 6px 0; border-bottom: 1px solid var(--border); } .trace-time { font-family: var(--mono); font-size: 11px; color: var(--ink-3); flex-shrink: 0; } .badge { font-size: 10px; font-weight: 700; letter-spacing: 0.04em; border-radius: 3px; padding: 1px 6px; color: #fff; flex-shrink: 0; } .badge-router { background: var(--cat-1); } .badge-tool { background: var(--accent-solid); } .badge-result { background: var(--status-good); } .badge-narration { background: var(--cat-7); } .badge-error { background: var(--status-critical); } .badge-other { background: var(--ink-3); } /* REASONED (Stretch 3): a cited interpretation, not a fresh engine number — its own hue, distinct from badge-tool/badge-error. */ .badge-reasoned { background: var(--cat-5); } .trace-body { min-width: 0; overflow-wrap: anywhere; } .trace-tool { font-family: var(--mono); font-size: 12px; color: var(--accent-text); margin-right: 6px; } .trace-args { font-family: var(--mono); font-size: 11.5px; color: var(--ink-2); margin-right: 6px; } /* -------------------------------------------------------------- copilot */ .copilot-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 16px; align-items: start; } @media (max-width: 900px) { .copilot-grid { grid-template-columns: 1fr; } } .copilot-chat-col .chat-panel-full { min-height: 520px; } .copilot-side-col { display: flex; flex-direction: column; gap: 16px; } .audit-list { list-style: none; display: flex; flex-direction: column; max-height: 320px; overflow-y: auto; } .audit-row { border-bottom: 1px solid var(--border); } .audit-row-head { display: flex; align-items: center; gap: 8px; padding: 7px 2px; cursor: pointer; font-size: 12px; } .audit-time { font-family: var(--mono); font-size: 11px; color: var(--ink-3); flex-shrink: 0; } .audit-question { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); } .audit-toggle { color: var(--ink-3); flex-shrink: 0; } .audit-row-body { padding: 4px 2px 10px 22px; } .audit-answer { font-size: 12.5px; color: var(--ink-2); margin-bottom: 6px; } .audit-trace { font-family: var(--mono); font-size: 11px; background: var(--page); border: 1px solid var(--border); border-radius: 4px; padding: 8px; overflow-x: auto; max-height: 200px; overflow-y: auto; color: var(--ink-2); } /* ------------------------------------------------------------------ chat */ .chat-panel { display: flex; flex-direction: column; } .chat-log { flex: 1; overflow-y: auto; max-height: 340px; display: flex; flex-direction: column; gap: 8px; padding: 4px 0 10px; } .chat-panel-dock .chat-log { max-height: 260px; } .msg { border-radius: var(--radius-sm); padding: 8px 12px; max-width: 92%; font-size: 13.5px; line-height: 1.5; } .msg-user { align-self: flex-end; background: var(--accent-wash); color: var(--ink); } .msg-agent { align-self: flex-start; background: var(--panel-2); border: 1px solid var(--border); color: var(--ink); } .msg-error { align-self: flex-start; background: var(--panel-2); border: 1px solid var(--border); color: var(--ink); } .msg-refusal { align-self: flex-start; background: var(--panel-2); border: 1px solid var(--border); color: var(--ink-2); } .refusal-tag { display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-3); background: var(--panel); border: 1px solid var(--border); border-radius: 3px; padding: 1px 6px; margin-bottom: 4px; } /* REASONED answer bubble: same shape as a grounded bubble, but its own accent-colored tag so it never reads as a fresh engine number. */ .msg-reasoned { border-color: var(--accent); } .reasoned-tag { display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent-text); background: var(--accent-wash); border: 1px solid var(--accent); border-radius: 3px; padding: 1px 6px; margin-bottom: 4px; } .citations { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; } .citations-label { font-size: 11px; color: var(--ink-3); } .citation { font-family: var(--mono); font-size: 10.5px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 3px; padding: 1px 6px; color: var(--accent-text); overflow-wrap: anywhere; display: inline-block; margin-top: 4px; } .chat-form { display: flex; gap: 8px; border-top: 1px solid var(--border); padding-top: 10px; } .chat-form input { flex: 1; font-size: 13.5px; padding: 7px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--panel-2); color: var(--ink); } .chat-form input:focus { outline: 2px solid var(--accent); outline-offset: -1px; } .chat-form .btn { margin-top: 0; height: auto; padding: 7px 14px; } /* ------------------------------------------------------------- mini dock */ .mini-dock { position: fixed; right: 24px; bottom: 20px; z-index: 30; width: min(420px, 100vw - 48px); } .mini-dock-bar { display: flex; align-items: center; gap: 8px; background: var(--panel-2); border: 1px solid var(--border-strong); border-radius: var(--radius-pill); box-shadow: var(--shadow-e2); padding: 6px 6px 6px 14px; cursor: text; } .mini-dock-status { display: inline-flex; align-items: center; gap: 6px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3); flex-shrink: 0; } .mini-dock-bar input { flex: 1; border: none; background: transparent; font-size: 13.5px; color: var(--ink); min-width: 0; } .mini-dock-bar input::placeholder { color: var(--ink-3); } .mini-dock-send { width: 34px; height: 34px; border-radius: var(--radius-pill); border: none; background: var(--accent-solid); color: var(--accent-on-solid); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; } .mini-dock-send:disabled { opacity: 0.45; cursor: not-allowed; } .mini-dock-panel { width: 100%; max-height: 60vh; display: flex; flex-direction: column; background: var(--panel-2); border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: var(--shadow-e2); overflow: hidden; margin-bottom: 10px; } .mini-dock-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; background: var(--panel); border-bottom: 1px solid var(--border); font-size: 13px; font-weight: 600; } .mini-dock-close { border: none; background: transparent; color: var(--ink-3); font-size: 18px; line-height: 1; cursor: pointer; padding: 0 4px; } .mini-dock-panel .chat-panel { border: none; border-radius: 0; box-shadow: none; padding: 12px 14px; overflow-y: auto; } /* Narrow viewports: the dock collapses to a plain icon pill (FINAL_SPEC graft 5) so it never eats the input row on a phone-width screen. */ @media (max-width: 620px) { .mini-dock { right: 14px; bottom: 14px; width: auto; } .mini-dock-bar.collapsed-narrow input, .mini-dock-bar.collapsed-narrow .mini-dock-status { display: none; } .mini-dock-panel { width: min(360px, calc(100vw - 28px)); } } /* ----------------------------------------------------------- responsive */ @media (max-width: 640px) { .app-header { padding: 10px 14px; } .tab-nav { padding: 0 14px; gap: 16px; } .app-main { padding: 14px 14px 160px; } } /* ------------------------------------------- model-at-a-glance / method (dossier-v2 propagation: the ECL-formula index panel, the EAD & EIR method panel, and the Copilot "How grounding works" panel) */ .glance-formula { font-family: var(--mono, ui-monospace, monospace); font-size: 17px; color: var(--ink); text-align: center; padding: 10px 0 14px; letter-spacing: 0.02em; } .glance-terms { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; } .glance-term-head { display: flex; align-items: baseline; gap: 10px; } .glance-chip { font-family: var(--mono, ui-monospace, monospace); white-space: nowrap; flex: 0 0 auto; min-width: 92px; text-align: center; } .glance-term-text { font-size: 13px; color: var(--ink-2); line-height: 1.55; } .glance-term-text b { color: var(--ink); } .glance-jump { color: var(--accent-text); text-decoration: none; white-space: nowrap; font-size: 12px; } .glance-jump:hover { text-decoration: underline; } .glance-term-actions { margin-left: auto; flex: 0 0 auto; } .method-p { font-size: 13px; color: var(--ink-2); line-height: 1.55; margin: 0 0 10px; } .method-p b { color: var(--ink); } .method-formula { font-size: 14px; padding: 4px 0 10px; } .frac { display: inline-flex; flex-direction: column; vertical-align: middle; text-align: center; margin: 0 4px; } .frac-top { padding: 0 6px 2px; border-bottom: 1px solid var(--ink-2); } .frac-bot { padding: 2px 6px 0; } .ground-steps { margin: 0 0 12px; padding-left: 20px; display: flex; flex-direction: column; gap: 8px; font-size: 13px; color: var(--ink-2); line-height: 1.55; } .ground-steps b { color: var(--ink); } .ground-legend { border-top: 1px solid var(--border); padding-top: 10px; margin-bottom: 10px; } .ground-legend-row { font-size: 12.5px; color: var(--ink-2); margin: 0 0 6px; } .ground-legend-row b { color: var(--ink); letter-spacing: 0.04em; } @media (max-width: 640px) { .glance-term-head { flex-wrap: wrap; } }