Files
Socrates/apps/web/styles/base.css
dtoro b55425cc68 Pivot to text-first column-stack workspace + merge-with-review across AI artifacts
Workspace
- Pivot from "set of open panes" to a Finder-style miller column stack:
  TopBar / LeftSidebar / [section → entity → entity ...] / pinned text editor.
  openPanesStore is now an ordered Column[] with pushFrom / closeFrom /
  setStack; only one top-level section is rooted at a time.
- New entity column panes: Term, Block, Association, Constraint,
  Requirement, Finding. Click-through navigation truncates deeper
  columns automatically.
- LeftSidebar surfaces a pending-count chip per section (single-glance
  navigation cue) and spins its analyze ↻ via SVG Spinner whenever the
  LLM is working — including server-initiated runs caught by the runs
  poll, not just user-triggered ones.

Analyze pipeline + persistence
- Unified `concepts` pass (taxonomy + glossary in one LLM call) replaces
  the two-pass setup. Server still accepts ?section=taxonomy|glossary
  and normalizes them for back-compat.
- model / requirements / detection (assumptions, risks, inconsistencies)
  + cross-layer validation rules (X1–X4: stale term link, unlinked
  formalism, undefined linked term, prose-only term).
- Persistence: NarrativeDocument, ModelSnapshot, ChangelogEntry,
  TaxonomyTerm, RequirementEntry, Finding, AnalysisRun. Re-runs MERGE
  instead of replace: gentle update on existing items, suggested on new,
  deprecated on missing — same idiom for every artifact kind. User pins
  preserve "kept" decisions across re-analyses.
- Migrations: pivot_text_first, add_requirement_linked_term,
  term_review_state, review_state_for_reqs_and_findings,
  add_term_definition_pinned.

Concept ↔ ontology integration
- linkedTermId on Block / Association / Constraint / Requirement.
  PromoteToolbar lets the user formalize a concept inline: + Block /
  + Association / + Constraint / + Requirement, all routed through
  applyOps so undo/redo and SSE work for free.
- decideElement op for in-canvas keep/discard on review-pending model
  elements.

User-authored definitions
- TermColumn definition is click-to-edit. Save (Cmd-Enter / blur),
  Cancel (Esc), Reset to AI suggestion when pinned.
- definitionPinned flag on TaxonomyTerm: future Analyze runs leave the
  user's text alone. setTermDefinition repo function + POST
  /api/projects/[id]/terms/[termId]/definition endpoint.
- mergeTaxonomySuggestion + applyGlossaryDefinitions both pin-aware.

UX/UI
- StatusChip: single component for all state idioms (suggested,
  deprecated, accepted, dismissed, resolved, severity, validation code,
  confidence, warn). Replaces 5+ ad-hoc badge classes.
- PaneControls (PaneViewTabs + PaneFilterChip): separates view-mode
  toggles from filter chips so toggling Pending no longer flips you off
  the current view.
- PaneEmpty: unified empty-state with title + hint + action.
- PaneDrawer: collapsible groups for Pending / Discarded review; cards
  group as Kept (top) → Pending (bottom drawer) → Discarded (Findings
  only, hidden when empty). Restore action recovers dismissed/resolved
  findings.
- ConceptCard unifies Tree and A–Z views in Concepts; only Tree parents
  carry the chevron (no empty placeholder offset).
- Type + spacing tokens (--text-xs..xl, --space-1..6, --lh-tight/ui/
  prose, --radius-*) replace every ad-hoc value.
- Buttons standardized to body sans 500 (was a mishmash of mono / display).
- Card shells unified across Concepts / Requirements / Findings.

Cleanup
- Removed: LeftRail, FindingsPanel, IssuesPanel, SocratesDock,
  ProposalCard, SlashMenu, SlashExtension, slashSuggestion,
  CanvasHeader, TaxonomyPane, GlossaryPane, TermDetail (popover; now
  TermColumn).
- Section ids in openPanesStore: dropped taxonomy/glossary, added
  concepts. localStorage migration runs on hydrate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 00:12:06 +02:00

3121 lines
89 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ─── Base shared styles (theme variables defined per-aesthetic in HTML) ─── */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
font-family: var(--font-body);
color: var(--fg);
background: var(--bg);
/* Direct children fill the viewport */
display: flex;
flex-direction: column;
min-height: 100dvh;
}
body > * { flex: 1; min-height: 0; }
button { font-family: inherit; }
/* ─── Shell ─── */
.shell {
width: 100%;
height: 100dvh;
min-height: 0;
display: flex;
flex-direction: column;
background: var(--bg);
color: var(--fg);
font-family: var(--font-body);
font-size: 13.5px;
line-height: 1.55;
overflow: hidden;
letter-spacing: var(--tracking);
}
.shell-density-compact { font-size: 12.5px; line-height: 1.45; }
/* ─── Top bar ─── */
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
height: 44px;
padding: 0 16px;
background: var(--surface);
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.topbar-left { display: flex; align-items: center; gap: 14px; }
.brand { display: flex; align-items: center; gap: 8px; }
.brand-name { font-family: var(--font-display); font-weight: 600; font-size: var(--text-xl); letter-spacing: 0.01em; }
.breadcrumbs { display: flex; align-items: center; gap: 6px; font-size: var(--text-sm); color: var(--muted); font-family: var(--font-mono); }
.bc-sep { opacity: 0.45; }
.bc-active { color: var(--fg); }
.bc-branch { margin-left: 10px; padding: 2px 8px; border-radius: 4px; background: var(--accent-soft); color: var(--accent-strong); font-size: 11.5px; }
.bc-branch-glyph { margin-right: 4px; }
.topbar-right { display: flex; align-items: center; gap: 10px; }
.sync-pill { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); font-family: var(--font-mono); }
.sync-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px var(--ok-soft); }
.topbar-divider { width: 1px; height: 18px; background: var(--border); }
.icon-btn {
width: 26px; height: 26px; border-radius: 5px; border: 1px solid transparent;
background: transparent; color: var(--muted); font-size: 13px;
display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
font-family: var(--font-mono);
}
.icon-btn:hover { background: var(--surface-2); color: var(--fg); border-color: var(--border); }
.avatar {
width: 26px; height: 26px; border-radius: 50%;
background: var(--accent); color: var(--accent-on);
font-size: 11px; font-weight: 600;
display: inline-flex; align-items: center; justify-content: center;
font-family: var(--font-display); letter-spacing: 0.02em;
}
/* ─── Body layout ─── */
.shell-body {
flex: 1;
display: grid;
grid-template-columns: 320px 184px 1fr;
min-height: 0;
}
.shell-density-compact .shell-body { grid-template-columns: 296px 168px 1fr; }
.shell-presence-prominent .shell-body { grid-template-columns: 360px 184px 1fr; }
.shell-presence-subtle .shell-body { grid-template-columns: 0px 184px 1fr; }
/* ─── Left rail ─── */
.leftrail {
border-right: 1px solid var(--border);
border-left: 1px solid var(--border);
background: var(--surface);
padding: 8px 8px;
overflow-y: auto;
font-size: 11.5px;
position: relative;
}
.leftrail-collapsed {
padding: 14px 0;
display: flex; flex-direction: column; align-items: center; gap: 14px;
width: 36px;
min-width: 36px;
}
.rail-collapsed-stack {
display: flex; flex-direction: column; gap: 18px;
margin-top: 8px;
}
.rail-collapsed-tag {
font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.08em;
color: var(--muted); writing-mode: vertical-rl; text-orientation: mixed;
cursor: pointer;
}
.rail-collapsed-tag:hover { color: var(--fg); }
.rail-section-head {
display: flex; align-items: center; gap: 5px;
width: 100%;
background: transparent; border: none; padding: 0 4px;
cursor: pointer;
margin-bottom: 4px;
color: inherit;
height: 20px;
}
.rail-section-head:hover .rail-label { color: var(--fg); }
.rail-caret { display: none; }
.rail-section .rail-label { margin-bottom: 0; padding: 0; }
.rail-collapse-btn {
position: absolute; top: 8px; right: 6px;
width: 18px; height: 18px; border-radius: 4px;
border: none; background: transparent; color: var(--muted);
cursor: pointer; font-size: 11px; line-height: 1;
display: flex; align-items: center; justify-content: center;
}
.rail-collapse-btn:hover { background: var(--surface-2); color: var(--fg); }
.leftrail-collapsed .rail-collapse-btn { position: static; }
.rail-collapse-btn-bottom { display: none; }
.shell-density-compact .leftrail { padding: 10px 10px; font-size: 11.5px; }
.rail-section { margin-bottom: 10px; }
.rail-label {
text-transform: uppercase;
font-size: 9.5px;
font-family: var(--font-mono);
letter-spacing: 0.10em;
color: var(--muted);
margin-bottom: 4px;
padding: 0 4px;
}
.rail-list { list-style: none; padding: 0; margin: 0; }
.rail-item {
padding: 2px 6px; border-radius: 3px; cursor: pointer; color: var(--fg);
display: flex; align-items: center; gap: 6px;
font-size: 11.5px; line-height: 1.35;
}
.rail-item-text { flex: 1; }
.rail-count {
font-family: var(--font-mono); font-size: 9.5px;
padding: 1px 5px; border-radius: 3px;
background: var(--surface-2); color: var(--muted-strong);
letter-spacing: 0.02em;
flex-shrink: 0;
}
.rail-count-asm { background: var(--c-prop-bg); color: var(--c-prop-fg); }
.rail-count-req { background: var(--c-block-bg); color: var(--c-block-fg); }
.rail-count-q { background: var(--accent-soft); color: var(--accent-strong); }
.rail-count-risk { background: var(--warn-soft); color: var(--warn-strong); }
.rail-item:hover { background: var(--surface-2); }
.rail-item-active { background: var(--accent-soft); color: var(--accent-strong); }
.rail-item-muted { color: var(--muted); }
.rail-blocks { display: flex; flex-direction: column; gap: 1px; }
.rail-block {
display: flex; align-items: center; gap: 6px;
padding: 2px 6px; border-radius: 3px; cursor: pointer;
font-family: var(--font-mono); font-size: 10.5px;
line-height: 1.4;
}
.rail-block:hover { background: var(--surface-2); }
.rail-block-active { background: var(--accent-soft); color: var(--accent-strong); }
.rail-block-glyph { color: var(--muted); width: 12px; }
.rail-constraint .rail-block-glyph { color: var(--warn); }
.rail-actor .rail-block-glyph { color: var(--info); }
.rail-block-label { flex: 1; }
.rail-block-count {
font-size: 10px; color: var(--muted);
background: var(--surface-2); padding: 1px 5px; border-radius: 3px;
display: inline-flex; align-items: center; gap: 3px;
cursor: help;
}
.rail-block-count-glyph { opacity: 0.6; }
/* Legacy rules from the pre-pivot rail layout. Scoped to .rail-req so they
* can't bleed into the column-stack UI. (The unscoped `.req-traced { background:
* var(--ok) }` was rendering a solid-green strip behind the "Traced to …"
* hint inside RequirementsPane cards, making the link unreadable.) */
.rail-req {
display: flex; align-items: center; justify-content: space-between;
padding: 2px 6px; font-family: var(--font-mono); font-size: 10px; color: var(--muted-strong);
}
.rail-req .req-tag { letter-spacing: 0.04em; }
.rail-req .req-status { width: 6px; height: 6px; border-radius: 50%; }
.rail-req .req-traced { background: var(--ok); }
.rail-req .req-untraced { background: var(--warn); }
/* ─── Canvases ─── */
.canvases { display: grid; grid-template-columns: 1fr 1px 1fr; min-height: 0; background: var(--bg); }
.canvas { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.canvas-divider { background: var(--border); }
.canvas-header {
height: auto; min-height: 44px; padding: 8px 16px; flex-shrink: 0;
display: flex; align-items: center; justify-content: space-between;
border-bottom: 1px solid var(--border); background: var(--surface);
}
.shell-density-compact .canvas-header { min-height: 38px; padding: 6px 12px; }
.canvas-title { font-family: var(--font-display); font-weight: 600; font-size: 12.5px; letter-spacing: 0.02em; line-height: 1.3; }
.canvas-sub { font-size: 10.5px; color: var(--muted); font-family: var(--font-mono); line-height: 1.3; margin-top: 2px; }
.canvas-actions { display: flex; gap: 2px; background: var(--surface-2); padding: 2px; border-radius: 5px; }
.canvas-mode-pill {
font-size: 10.5px; padding: 3px 8px; border-radius: 4px;
color: var(--muted); cursor: pointer; font-family: var(--font-mono);
}
.canvas-mode-active { background: var(--surface); color: var(--fg); box-shadow: 0 1px 2px var(--shadow); }
.canvas-scroll { flex: 1; overflow-y: auto; min-height: 0; position: relative; }
.canvas-scroll-diagram { overflow: hidden; }
/* ─── Text canvas ─── */
.text-canvas {
max-width: 720px;
margin: 0 auto;
font-family: var(--font-prose);
color: var(--fg);
}
.t-h1 {
font-family: var(--font-display);
font-weight: 600;
font-size: 22px;
letter-spacing: -0.01em;
margin: 14px 0 16px 0;
color: var(--fg);
}
.t-h2 {
font-family: var(--font-display);
font-weight: 600;
font-size: 15px;
letter-spacing: 0.01em;
margin: 24px 0 8px 0;
color: var(--fg);
}
.t-p {
margin: 0 0 14px 0;
font-size: 14.5px;
line-height: 1.65;
color: var(--prose);
text-wrap: pretty;
}
.shell-density-compact .t-p { font-size: 13px; line-height: 1.55; margin-bottom: 10px; }
.shell-density-compact .t-h1 { font-size: 19px; }
.shell-density-compact .t-h2 { font-size: 13.5px; }
/* ─── Chips ─── */
.chip {
display: inline-flex; align-items: baseline; gap: 3px;
padding: 1px 6px; border-radius: 4px; cursor: pointer;
font-family: var(--font-mono);
font-size: 0.86em;
vertical-align: baseline;
transition: background .12s, box-shadow .12s;
white-space: nowrap;
}
.chip-glyph { font-size: 0.85em; opacity: 0.75; }
.chip-label { font-weight: 500; }
.chip-focus { box-shadow: 0 0 0 1.5px var(--accent); }
/* pill (default) */
.chip-style-pill { background: var(--chip-bg); color: var(--chip-fg); }
.chip-style-pill:hover { background: var(--chip-bg-hover); }
/* color-coded by kind */
.chip-style-color.chip-block { background: var(--c-block-bg); color: var(--c-block-fg); }
.chip-style-color.chip-property { background: var(--c-prop-bg); color: var(--c-prop-fg); }
.chip-style-color.chip-association { background: var(--c-assoc-bg); color: var(--c-assoc-fg); }
.chip-style-color.chip-requirement { background: var(--c-req-bg); color: var(--c-req-fg); }
/* underline */
.chip-style-underline {
background: transparent;
padding: 0 1px;
border-bottom: 1.5px solid var(--accent);
border-radius: 0;
color: var(--fg);
}
.chip-style-underline.chip-block { border-bottom-color: var(--c-block-fg); }
.chip-style-underline.chip-property { border-bottom-color: var(--c-prop-fg); }
.chip-style-underline.chip-association { border-bottom-color: var(--c-assoc-fg); }
.chip-style-underline.chip-requirement { border-bottom-color: var(--c-req-fg); }
.chip-style-underline:hover { background: var(--chip-bg); }
/* bracket */
.chip-style-bracket {
background: transparent;
color: var(--muted-strong);
padding: 0 1px;
}
.chip-style-bracket .chip-bracket { color: var(--muted); opacity: 0.6; }
.chip-style-bracket .chip-kind { color: var(--accent); margin-right: 3px; }
.chip-style-bracket .chip-label { color: var(--fg); }
.chip-style-bracket:hover { background: var(--chip-bg); border-radius: 3px; }
/* ─── Margin note ─── */
.margin-note {
display: flex; gap: 12px;
margin: 24px 0 8px 0;
padding: 12px 14px;
background: var(--note-bg);
border-left: 2px solid var(--accent);
border-radius: 0 6px 6px 0;
font-family: var(--font-prose);
font-size: 13px;
color: var(--prose);
}
.margin-note-glyph {
font-family: var(--font-display); font-weight: 600;
color: var(--accent); font-size: 17px; line-height: 1;
flex-shrink: 0;
}
.margin-note-who {
display: block;
font-family: var(--font-mono); font-size: 10.5px;
color: var(--accent); letter-spacing: 0.04em; text-transform: uppercase;
margin-bottom: 4px;
}
.margin-note-text { line-height: 1.5; }
/* ─── Diagram ─── */
.diagram-grid {
position: absolute; inset: 0;
background-image: radial-gradient(var(--grid-dot) 1px, transparent 1px);
background-size: 18px 18px;
background-position: 0 0;
opacity: 0.7;
pointer-events: none;
}
.diagram-legend {
position: absolute; bottom: 12px; left: 12px;
display: flex; gap: 14px;
background: var(--surface);
border: 1px solid var(--border);
padding: 6px 10px;
border-radius: 5px;
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--muted);
}
.legend-sw { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; }
.legend-block { background: var(--block-bg); border: 1px solid var(--block-border); }
.legend-actor { background: var(--block-actor-bg); border: 1px solid var(--block-border); }
.legend-constraint { background: var(--block-constraint-bg); border: 1px dashed var(--block-border); }
/* ─── Socrates dock ─── */
.dock {
border-right: 1px solid var(--border);
background: var(--surface);
display: flex; flex-direction: column;
overflow: hidden;
font-size: 12.5px;
min-height: 0;
}
.dock-header {
display: flex; align-items: center; gap: 8px;
padding: 8px 10px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.dock-header-text { flex: 1; min-width: 0; }
.dock-header-action {
width: 22px; height: 22px; border-radius: 4px;
border: 1px solid var(--border-strong);
background: transparent; color: var(--muted);
cursor: pointer; font-size: 13px; line-height: 1;
display: flex; align-items: center; justify-content: center;
}
.dock-header-action:hover { background: var(--surface-2); color: var(--fg); }
.dock-thread-wrap {
flex: 1;
min-height: 0;
overflow-y: auto;
padding: 10px 10px 6px;
display: flex; flex-direction: column;
}
.dock-section-label-inline {
margin-bottom: 8px;
flex-shrink: 0;
}
.dock-thread {
display: flex; flex-direction: column; gap: 8px;
flex: 1;
}
.bubble {
padding: 8px 10px; border-radius: 8px;
font-family: var(--font-prose); font-size: 12.5px; line-height: 1.5;
display: flex; gap: 8px;
align-items: flex-start;
}
.bubble-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.bubble-text { display: block; }
.dock-input-wrap {
flex-shrink: 0;
padding: 8px 10px;
border-top: 1px solid var(--border);
background: var(--surface);
}
.dock-input { margin-top: 0; }
/* Numbered options inside a bubble */
.bubble-options {
display: flex; flex-direction: column; gap: 3px;
margin-top: 2px;
}
.bubble-option {
display: flex; align-items: center; gap: 8px;
padding: 4px 7px;
background: var(--surface);
border: 1px solid var(--border-strong);
border-radius: 5px;
cursor: pointer;
text-align: left;
font-family: var(--font-prose);
color: var(--fg);
width: 100%;
transition: background .12s, border-color .12s;
}
.bubble-option:hover {
background: var(--surface-2);
border-color: var(--accent);
}
.bubble-option-num {
width: 15px; height: 15px; flex-shrink: 0;
border-radius: 3px;
background: var(--accent-soft); color: var(--accent-strong);
font-family: var(--font-mono); font-size: 9.5px; font-weight: 600;
display: flex; align-items: center; justify-content: center;
}
.bubble-option-text { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 6px; }
.bubble-option-label {
font-size: 11.5px; font-weight: 500; color: var(--fg);
line-height: 1.25;
}
.bubble-option-sub {
font-family: var(--font-mono); font-size: 9.5px;
color: var(--muted);
line-height: 1.25;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.bubble-option-key { display: none; }
.bubble-options-hint {
font-family: var(--font-mono); font-size: 9.5px;
color: var(--muted);
margin-top: 3px;
padding: 0 2px;
}
.bubble-options-hint kbd {
font-family: var(--font-mono); font-size: 9px;
padding: 0 3px; border-radius: 2px;
background: var(--surface-2); color: var(--muted-strong);
border: 1px solid var(--border);
margin: 0 1px;
}
.dock-subtle {
position: fixed; bottom: 24px; right: 24px;
width: 50px; height: 50px;
border-radius: 50%; border: 1px solid var(--border);
background: var(--surface);
display: flex; align-items: center; justify-content: center;
box-shadow: 0 6px 20px var(--shadow-strong);
cursor: pointer;
z-index: 10;
}
.dock-subtle-count {
position: absolute; top: -4px; right: -4px;
width: 18px; height: 18px; border-radius: 50%;
background: var(--accent); color: var(--accent-on);
font-size: 10px; font-weight: 600;
display: flex; align-items: center; justify-content: center;
font-family: var(--font-mono);
}
.dock-header {
display: flex; align-items: center; gap: 8px;
padding: 8px 10px;
border-bottom: 1px solid var(--border);
}
.dock-name { font-family: var(--font-display); font-weight: 600; font-size: 12.5px; }
.dock-status { display: flex; align-items: center; gap: 4px; font-size: 10px; color: var(--muted); font-family: var(--font-mono); }
.dock-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 2px var(--ok-soft); }
.dock-section { padding: 8px 10px; border-bottom: 1px solid var(--border); }
.dock-section:last-child { border-bottom: none; }
.dock-section-label {
text-transform: uppercase;
font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.10em;
color: var(--muted); margin-bottom: 6px;
}
.dock-section-label-2 { margin-top: 16px; }
.dock-thread { display: flex; flex-direction: column; gap: 8px; }
.bubble-socrates {
background: var(--bubble-socrates);
color: var(--prose);
border-left: 2px solid var(--accent);
border-radius: 2px 8px 8px 2px;
padding-left: 10px;
}
.bubble-socrates .bubble-sigil {
display: inline-block;
font-family: var(--font-display); font-weight: 600;
color: var(--accent); margin-right: 6px;
flex-shrink: 0;
}
.bubble-user {
background: var(--bubble-user);
color: var(--fg);
align-self: flex-end;
max-width: 88%;
}
.dock-input {
display: flex; align-items: center; gap: 6px;
padding: 7px 10px;
border: 1px solid var(--border-strong);
border-radius: 6px;
font-family: var(--font-mono);
font-size: 11.5px;
color: var(--muted);
background: var(--bg);
}
.dock-input-prompt { color: var(--accent); }
.dock-input-placeholder { flex: 1; }
.dock-input-shortcut { font-size: 10px; opacity: 0.55; }
/* Proposal */
.proposal {
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: 6px;
padding: 10px;
}
.proposal-title {
font-family: var(--font-display); font-weight: 600; font-size: 12.5px;
color: var(--fg); margin-bottom: 8px;
line-height: 1.35;
}
.proposal-meta { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.proposal-row { display: flex; gap: 8px; font-family: var(--font-mono); font-size: 10.5px; align-items: baseline; }
.proposal-key { color: var(--muted); width: 70px; flex-shrink: 0; }
.proposal-val { display: flex; gap: 4px; flex-wrap: wrap; }
.proposal-pill {
background: var(--accent-soft); color: var(--accent-strong);
padding: 1px 6px; border-radius: 3px; font-size: 10.5px;
}
.proposal-pill-req { background: var(--c-req-bg); color: var(--c-req-fg); }
.proposal-actions { display: flex; gap: 6px; }
.btn {
flex: 1;
padding: 6px 10px;
border-radius: 5px;
border: 1px solid var(--border-strong);
background: var(--surface);
color: var(--fg);
font-family: var(--font-mono);
font-size: 11.5px;
cursor: pointer;
}
.btn:hover { background: var(--surface-2); }
.btn-primary { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-strong); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); flex: 0; padding: 6px 8px; }
/* Watch list */
.watch { display: flex; flex-direction: column; gap: 6px; }
.watch-row {
display: flex; gap: 8px; align-items: flex-start;
font-size: 11.5px; line-height: 1.4; color: var(--prose);
}
.watch-tag {
font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.04em;
background: var(--c-prop-bg); color: var(--c-prop-fg);
padding: 2px 5px; border-radius: 3px;
flex-shrink: 0; margin-top: 1px;
}
.watch-tag-risk { background: var(--warn-soft); color: var(--warn-strong); }
.watch-validated .watch-tag { background: var(--ok-soft); color: var(--ok-strong); }
.watch-text { flex: 1; }
.watch-risk-high .watch-text { color: var(--fg); }
/* ─── Status bar ─── */
.statusbar {
height: 24px; flex-shrink: 0;
display: flex; align-items: center; gap: 12px;
padding: 0 16px;
font-family: var(--font-mono); font-size: 10.5px; color: var(--muted);
border-top: 1px solid var(--border);
background: var(--surface);
}
.status-spacer { flex: 1; }
/* ─── Sigil ─── */
.sigil { position: relative; }
.sigil-pulse {
animation: sigilpulse 2.4s ease-in-out infinite;
transform-origin: center;
}
@keyframes sigilpulse {
0%, 100% { opacity: 0.3; r: 2; }
50% { opacity: 1; r: 3.5; }
}
/* ─── Seed screen ─── */
.seed-screen {
width: 100%; height: 100dvh; min-height: 0;
display: flex; flex-direction: column;
background: var(--bg);
font-family: var(--font-body);
color: var(--fg);
overflow: hidden;
}
.seed-top {
display: flex; align-items: center; justify-content: space-between;
padding: 12px 20px;
border-bottom: 1px solid var(--border);
background: var(--surface);
flex-shrink: 0;
}
.seed-top-left { display: flex; align-items: center; gap: 10px; }
.seed-brand { font-family: var(--font-display); font-weight: 600; font-size: 16px; }
.seed-pip { color: var(--muted); }
.seed-step { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); }
.seed-top-right { display: flex; gap: 2px; background: var(--surface-2); padding: 2px; border-radius: 5px; }
.seed-mode-pill {
font-family: var(--font-mono); font-size: 11px; padding: 4px 12px;
border-radius: 4px; color: var(--muted); cursor: pointer;
}
.seed-mode-active { background: var(--surface); color: var(--fg); box-shadow: 0 1px 2px var(--shadow); }
.seed-body {
flex: 1;
display: grid;
grid-template-columns: minmax(280px, 380px) 1fr;
min-height: 0;
}
.seed-left {
border-right: 1px solid var(--border);
background: var(--surface);
padding: 22px 22px 18px;
overflow-y: auto;
}
.seed-section-label {
text-transform: uppercase;
font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em;
color: var(--muted); margin-bottom: 12px;
}
.seed-section-label-2 { margin-top: 24px; }
.seed-fields { display: flex; flex-direction: column; gap: 14px; }
.seed-field {
padding-left: 12px;
border-left: 2px solid var(--border-strong);
}
.seed-field-inferred { border-left-color: var(--accent); border-left-style: dashed; }
.seed-field-label {
font-family: var(--font-mono); font-size: 10.5px;
color: var(--muted); letter-spacing: 0.04em;
margin-bottom: 3px;
display: flex; gap: 8px; align-items: baseline;
}
.seed-conf { font-size: 9.5px; color: var(--accent); opacity: 0.85; }
.seed-field-value {
font-family: var(--font-prose);
font-size: 13.5px; line-height: 1.5;
color: var(--fg);
text-wrap: pretty;
}
.seed-mini-graph {
display: grid;
grid-template-columns: 1fr;
gap: 8px;
padding: 14px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 6px;
position: relative;
}
.mini-block {
border: 1px solid var(--block-border);
background: var(--block-bg);
padding: 8px 10px;
border-radius: 6px;
display: flex; flex-direction: column; gap: 1px;
}
.mini-block-3 { background: var(--block-constraint-bg); border-style: dashed; }
.mini-block-focus {
border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft);
}
.mini-stereo { font-family: var(--font-mono); font-size: 9.5px; color: var(--muted); letter-spacing: 0.04em; }
.mini-name { font-family: var(--font-display); font-weight: 600; font-size: 13px; }
.mini-prop { font-family: var(--font-mono); font-size: 11px; color: var(--muted-strong); margin-top: 2px; }
.mini-edge {
height: 14px;
background: linear-gradient(to bottom, var(--edge), var(--edge)) center/1px 100% no-repeat;
margin-left: 18px;
position: relative;
}
.mini-edge::after {
content: ""; position: absolute; left: -3px; bottom: 0;
border-left: 4px solid transparent; border-right: 4px solid transparent;
border-top: 5px solid var(--edge);
}
.seed-confidence { margin-top: 18px; }
.seed-confidence-row {
display: flex; justify-content: space-between;
font-family: var(--font-mono); font-size: 11px; color: var(--muted);
margin-bottom: 5px;
}
.seed-confidence-bar {
height: 4px; border-radius: 2px;
background: var(--surface-2);
overflow: hidden;
}
.seed-confidence-fill {
height: 100%; background: var(--accent);
}
.seed-confidence-hint {
margin-top: 6px;
font-size: 11px; color: var(--muted); font-family: var(--font-prose);
font-style: italic;
}
.seed-right {
display: flex; flex-direction: column;
min-height: 0;
background: var(--bg);
}
.seed-thread {
flex: 1; min-height: 0;
overflow-y: auto;
padding: 22px 36px;
display: flex; flex-direction: column; gap: 18px;
max-width: 760px;
margin: 0 auto;
width: 100%;
}
.seed-bubble {
display: flex; gap: 14px;
}
.seed-bubble-user { justify-content: flex-end; }
.seed-bubble-avatar { flex-shrink: 0; padding-top: 2px; }
.seed-bubble-body { max-width: 78%; }
.seed-bubble-user .seed-bubble-body {
background: var(--bubble-user);
padding: 10px 14px;
border-radius: 12px 12px 2px 12px;
color: var(--fg);
}
.seed-bubble-who {
font-family: var(--font-mono); font-size: 10.5px;
color: var(--muted); letter-spacing: 0.04em;
text-transform: uppercase; margin-bottom: 4px;
}
.seed-bubble-user .seed-bubble-who { display: none; }
.seed-bubble-text {
font-family: var(--font-prose);
font-size: 14.5px; line-height: 1.6;
color: var(--prose);
text-wrap: pretty;
}
.seed-bubble-user .seed-bubble-text { color: var(--fg); }
.seed-bubble-typing .seed-bubble-text { color: var(--muted); }
.seed-typing { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); font-family: var(--font-mono); }
.seed-typing span {
width: 4px; height: 4px; border-radius: 50%;
background: var(--accent); opacity: 0.35;
animation: typing 1.4s ease-in-out infinite;
}
.seed-typing span:nth-child(2) { animation-delay: 0.2s; }
.seed-typing span:nth-child(3) { animation-delay: 0.4s; }
@keyframes typing {
0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
40% { opacity: 1; transform: translateY(-2px); }
}
.seed-input-row {
border-top: 1px solid var(--border);
background: var(--surface);
padding: 14px 36px;
max-width: 760px; margin: 0 auto; width: 100%;
display: flex; flex-direction: column; gap: 10px;
flex-shrink: 0;
}
.seed-input {
display: flex; align-items: baseline; gap: 8px;
padding: 10px 14px;
background: var(--bg);
border: 1px solid var(--border-strong);
border-radius: 8px;
font-family: var(--font-prose);
font-size: 14px;
line-height: 1.5;
color: var(--fg);
}
.seed-input-prompt { color: var(--accent); font-family: var(--font-mono); }
.seed-input-text { flex: 1; }
.seed-input-caret {
display: inline-block;
width: 1.5px; height: 16px;
background: var(--accent);
animation: caret 1s steps(1) infinite;
vertical-align: -3px;
}
@keyframes caret { 50% { opacity: 0; } }
.seed-input-actions { display: flex; justify-content: flex-end; gap: 8px; }
.seed-btn {
padding: 6px 12px;
border-radius: 5px;
border: 1px solid var(--border-strong);
background: var(--surface);
color: var(--fg);
font-family: var(--font-mono);
font-size: 11.5px;
cursor: pointer;
}
.seed-btn-primary { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
/* ─── Slash menu (M2) ─── */
.slash-menu {
background: var(--surface);
border: 1px solid var(--border-strong);
border-radius: 6px;
box-shadow: 0 8px 24px var(--shadow-strong);
padding: 4px;
min-width: 280px;
display: flex; flex-direction: column; gap: 2px;
}
.slash-menu-empty {
padding: 10px 12px;
font-family: var(--font-mono);
font-size: 11.5px;
color: var(--muted);
}
.slash-menu-item {
display: grid;
grid-template-columns: 20px 1fr auto auto;
align-items: center;
gap: 8px;
padding: 6px 8px;
border-radius: 4px;
background: transparent;
border: none;
cursor: pointer;
text-align: left;
font-family: inherit;
color: var(--fg);
}
.slash-menu-item:hover,
.slash-menu-item-active {
background: var(--accent-soft);
color: var(--accent-strong);
}
.slash-menu-glyph {
font-family: var(--font-mono);
font-size: 13px;
color: var(--muted);
text-align: center;
}
.slash-menu-glyph-block { color: var(--c-block-fg); }
.slash-menu-glyph-property { color: var(--c-prop-fg); }
.slash-menu-glyph-association { color: var(--c-assoc-fg); }
.slash-menu-glyph-requirement { color: var(--c-req-fg); }
.slash-menu-label {
font-family: var(--font-display);
font-size: 13px;
font-weight: 500;
}
.slash-menu-hint {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--muted);
margin-right: 4px;
}
.slash-menu-key {
font-family: var(--font-mono);
font-size: 10px;
background: var(--surface-2);
color: var(--muted-strong);
border: 1px solid var(--border);
padding: 1px 5px;
border-radius: 3px;
}
/* TipTap-rendered narrative root */
.tiptap { outline: none; }
.tiptap:focus { outline: none; }
.tiptap p.t-p,
.tiptap > p {
margin: 0 0 14px 0;
font-size: 14.5px;
line-height: 1.65;
color: var(--prose);
text-wrap: pretty;
}
.tiptap > h1 {
font-family: var(--font-display);
font-weight: 600;
font-size: 22px;
margin: 14px 0 16px 0;
}
.tiptap > h2 {
font-family: var(--font-display);
font-weight: 600;
font-size: 15px;
margin: 24px 0 8px 0;
}
/* Make ProseMirror's inline-atom selection look like our chip-focus state. */
.tiptap .ProseMirror-selectednode .chip {
box-shadow: 0 0 0 1.5px var(--accent);
}
/* ─── Issues panel (M4) ─── */
.issues-panel {
position: fixed;
bottom: 32px;
right: 16px;
width: 380px;
max-height: 50vh;
background: var(--surface);
border: 1px solid var(--border-strong);
border-radius: 6px;
box-shadow: 0 8px 24px var(--shadow-strong);
display: flex;
flex-direction: column;
z-index: 50;
font-family: var(--font-body);
overflow: hidden;
}
.issues-panel-clean {
width: auto;
min-width: 200px;
}
.issues-panel-clean .issues-panel-head { color: var(--ok-strong); }
.issues-panel-clean-glyph {
color: var(--ok);
font-size: 14px;
font-weight: 600;
}
.issues-panel-collapsed {
max-height: none;
}
.issues-panel-head {
display: flex; align-items: center; gap: 10px;
padding: 8px 12px;
background: transparent;
border: none;
border-bottom: 1px solid var(--border);
cursor: pointer;
font-family: inherit;
color: var(--fg);
width: 100%;
text-align: left;
}
.issues-panel-collapsed .issues-panel-head { border-bottom: none; }
.issues-panel-head:hover { background: var(--surface-2); }
.issues-panel-title {
font-family: var(--font-display);
font-weight: 500;
font-size: 13px;
flex: 1;
}
.issues-panel-counts { display: flex; gap: 8px; }
.issues-count {
font-family: var(--font-mono);
font-size: 11px;
font-weight: 500;
}
.issues-count-error { color: var(--warn-strong); }
.issues-count-warning { color: var(--accent-strong); }
.issues-count-soft { color: var(--muted); }
.issues-panel-caret { font-size: 9px; color: var(--muted); }
.issues-panel-list {
list-style: none;
margin: 0;
padding: 4px;
overflow-y: auto;
flex: 1;
}
.issues-item {
display: grid;
grid-template-columns: 16px auto 1fr;
gap: 8px;
padding: 6px 10px;
border-radius: 4px;
cursor: pointer;
font-size: 12.5px;
line-height: 1.35;
}
.issues-item:hover { background: var(--surface-2); }
.issues-item-error .issues-item-sev { color: var(--warn-strong); }
.issues-item-warning .issues-item-sev { color: var(--accent); }
.issues-item-soft .issues-item-sev { color: var(--muted); }
.issues-item-sev { font-size: 11px; line-height: 1.6; text-align: center; }
.issues-item-code {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--muted-strong);
background: var(--surface-2);
padding: 1px 5px;
border-radius: 3px;
align-self: start;
margin-top: 1px;
}
.issues-item-msg { color: var(--prose); }
/* Issue dots in the rail */
.rail-issue-dot {
width: 6px; height: 6px;
border-radius: 50%;
margin-left: auto;
flex-shrink: 0;
margin-right: 4px;
}
.rail-issue-dot-error { background: var(--warn-strong); box-shadow: 0 0 0 2px var(--warn-soft); }
.rail-issue-dot-warning { background: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.rail-issue-dot-soft { background: var(--muted); }
/* Diagram node issue ring */
.sysml-node-issue-error {
border-color: var(--warn-strong) !important;
box-shadow: 0 0 0 2px var(--warn-soft), 0 2px 4px var(--shadow);
}
.sysml-node-issue-warning {
border-color: var(--accent) !important;
box-shadow: 0 0 0 2px var(--accent-soft), 0 2px 4px var(--shadow);
}
.sysml-node-issue-soft {
border-style: dotted !important;
}
/* ─── Chip inline rename (M5) ─── */
.chip-rename {
font-family: inherit;
font-size: 0.86em;
color: inherit;
background: var(--surface);
border: none;
border-bottom: 1px solid var(--accent);
outline: none;
padding: 0 1px;
min-width: 50px;
font-weight: 500;
}
.chip-rename:focus { background: var(--surface-2); }
.chip.chip-editing { box-shadow: 0 0 0 1.5px var(--accent); }
/* ─── Dock input (M6) ─── */
.dock-input { display: flex; align-items: center; gap: 6px; }
.dock-input-field {
flex: 1;
border: none;
background: transparent;
outline: none;
font: inherit;
font-family: var(--font-prose);
font-size: 12.5px;
color: var(--fg);
min-width: 0;
}
.dock-input-field::placeholder { color: var(--muted); }
.dock-input-field:disabled { color: var(--muted); cursor: not-allowed; }
.dock-input-send {
background: transparent;
border: 1px solid var(--border-strong);
border-radius: 4px;
padding: 2px 6px;
font-family: var(--font-mono);
font-size: 10px;
color: var(--muted);
cursor: pointer;
}
.dock-input-send:hover:not(:disabled) {
background: var(--accent);
color: var(--accent-on);
border-color: var(--accent);
}
.dock-input-send:disabled {
opacity: 0.4;
cursor: not-allowed;
}
/* ─── Proposal card (M7) ─── */
.proposal-card {
background: var(--surface-2);
border: 1px solid var(--border-strong);
border-radius: 8px;
padding: 10px 12px;
margin: 6px 0;
display: flex; flex-direction: column; gap: 8px;
font-family: var(--font-prose);
font-size: 12.5px;
color: var(--prose);
}
.proposal-card-pending { opacity: 0.6; }
.proposal-card-head {
display: flex; align-items: baseline; gap: 8px;
border-bottom: 1px solid var(--border);
padding-bottom: 4px;
}
.proposal-card-tag {
font-family: var(--font-mono);
font-size: 9px;
letter-spacing: 0.10em;
background: var(--accent);
color: var(--accent-on);
padding: 1px 6px;
border-radius: 3px;
}
.proposal-card-stats {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--muted-strong);
flex: 1;
text-align: right;
}
.proposal-card-reasoning {
line-height: 1.5;
color: var(--fg);
}
.proposal-card-ops {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--muted-strong);
}
.proposal-card-ops summary {
cursor: pointer;
padding: 2px 0;
color: var(--muted);
}
.proposal-card-ops ul {
margin: 4px 0 0 0;
padding-left: 14px;
}
.proposal-card-ops li { margin-bottom: 2px; }
.proposal-card-section {
display: flex; flex-direction: column; gap: 4px;
}
.proposal-card-section-label {
font-family: var(--font-mono);
font-size: 9.5px;
letter-spacing: 0.10em;
text-transform: uppercase;
color: var(--muted);
}
.proposal-card-impact-grid {
display: flex; flex-direction: column; gap: 3px;
}
.proposal-card-impact-row {
display: grid;
grid-template-columns: 80px 1fr;
gap: 8px;
font-family: var(--font-mono);
font-size: 10.5px;
}
.proposal-card-impact-key { color: var(--muted-strong); }
.proposal-card-impact-val { color: var(--fg); word-break: break-word; }
.proposal-card-issue-list {
margin: 0;
padding-left: 14px;
font-size: 11.5px;
}
.proposal-card-issue-list li { line-height: 1.4; }
.proposal-card-issues-resolved li { color: var(--ok-strong); }
.proposal-card-issues-created li { color: var(--warn-strong); }
.proposal-card-error { color: var(--warn-strong); }
.proposal-card-actions {
display: flex; gap: 6px;
border-top: 1px solid var(--border);
padding-top: 6px;
}
.proposal-card-btn {
padding: 4px 12px;
border-radius: 4px;
border: 1px solid var(--border-strong);
background: var(--surface);
color: var(--fg);
font-family: var(--font-mono);
font-size: 11px;
cursor: pointer;
}
.proposal-card-btn:hover:not(:disabled) { background: var(--surface-2); }
.proposal-card-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.proposal-card-btn-primary {
background: var(--accent);
color: var(--accent-on);
border-color: var(--accent);
}
.proposal-card-btn-primary:hover:not(:disabled) {
background: var(--accent-strong);
border-color: var(--accent-strong);
}
.proposal-card-meta {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--muted);
text-align: right;
}
/* System bubble (apply confirmation, dismissals) */
.bubble.bubble-system {
background: transparent;
color: var(--muted-strong);
font-family: var(--font-mono);
font-size: 10.5px;
font-style: italic;
padding: 2px 8px;
border: none;
text-align: center;
}
/* Propose button next to send */
.dock-input-propose {
background: transparent;
border: 1px solid var(--border-strong);
border-radius: 4px;
padding: 2px 8px;
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--muted-strong);
cursor: pointer;
white-space: nowrap;
}
.dock-input-propose:hover:not(:disabled) {
background: var(--accent-soft);
color: var(--accent-strong);
border-color: var(--accent);
}
.dock-input-propose:disabled {
opacity: 0.4;
cursor: not-allowed;
}
/* ─── Findings panel (M8) ─── */
.findings-panel {
position: fixed;
/* Sit just above the IssuesPanel; both anchored bottom-right */
bottom: 32px;
right: 412px;
width: 460px;
max-height: 50vh;
background: var(--surface);
border: 1px solid var(--border-strong);
border-radius: 6px;
box-shadow: 0 8px 24px var(--shadow-strong);
display: flex;
flex-direction: column;
z-index: 50;
font-family: var(--font-body);
overflow: hidden;
}
.findings-panel-collapsed { max-height: none; }
.findings-panel-head {
display: flex; align-items: center; gap: 10px;
padding: 8px 12px;
background: transparent;
border: none;
border-bottom: 1px solid var(--border);
cursor: pointer;
font-family: inherit;
color: var(--fg);
width: 100%;
text-align: left;
}
.findings-panel-collapsed .findings-panel-head { border-bottom: none; }
.findings-panel-head:hover { background: var(--surface-2); }
.findings-panel-counts { display: flex; gap: 8px; }
.findings-count {
font-family: var(--font-mono);
font-size: 11px;
font-weight: 500;
}
.findings-count-asm { color: var(--accent-strong); }
.findings-count-risk { color: var(--warn-strong); }
.findings-count-inc { color: var(--ok-strong); }
.findings-count-none { color: var(--muted); font-style: italic; }
.findings-panel-title {
font-family: var(--font-display);
font-weight: 500;
font-size: 13px;
flex: 1;
}
.findings-panel-stale {
margin-left: 6px;
font-family: var(--font-mono);
font-size: 10px;
color: var(--warn-strong);
}
.findings-panel-caret { font-size: 9px; color: var(--muted); }
.findings-panel-actions {
display: flex; align-items: center; gap: 10px;
padding: 6px 12px;
border-bottom: 1px solid var(--border);
background: var(--surface-2);
}
.findings-panel-btn {
padding: 3px 10px;
border-radius: 4px;
border: 1px solid var(--accent);
background: var(--accent);
color: var(--accent-on);
font-family: var(--font-mono);
font-size: 10.5px;
cursor: pointer;
}
.findings-panel-btn:hover:not(:disabled) { background: var(--accent-strong); border-color: var(--accent-strong); }
.findings-panel-btn:disabled { opacity: 0.45; cursor: wait; }
.findings-panel-meta {
font-family: var(--font-mono);
font-size: 10px;
color: var(--muted);
}
.findings-panel-error {
padding: 8px 12px;
background: var(--warn-soft);
color: var(--warn-strong);
font-family: var(--font-mono);
font-size: 11px;
border-bottom: 1px solid var(--border);
}
.findings-panel-list {
list-style: none;
margin: 0;
padding: 4px;
overflow-y: auto;
flex: 1;
}
.findings-item {
display: grid;
grid-template-columns: 14px 28px auto auto 1fr auto auto;
gap: 6px;
align-items: baseline;
padding: 5px 8px;
border-radius: 4px;
font-size: 12px;
line-height: 1.4;
}
.findings-item:hover { background: var(--surface-2); }
.findings-item-glyph {
font-size: 11px;
text-align: center;
}
.findings-item-glyph-assumption { color: var(--accent-strong); }
.findings-item-glyph-risk { color: var(--warn-strong); }
.findings-item-glyph-inconsistency { color: var(--ok-strong); }
.findings-item-tag {
font-family: var(--font-mono);
font-size: 9.5px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--muted-strong);
background: var(--surface-2);
padding: 1px 5px;
border-radius: 3px;
}
.findings-item-sev {
font-family: var(--font-mono);
font-size: 9.5px;
padding: 1px 5px;
border-radius: 3px;
}
.findings-item-sev-low { background: var(--surface-2); color: var(--muted-strong); }
.findings-item-sev-medium { background: var(--accent-soft); color: var(--accent-strong); }
.findings-item-sev-high { background: var(--warn-soft); color: var(--warn-strong); }
.findings-item-code {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--muted-strong);
background: var(--surface-2);
padding: 1px 5px;
border-radius: 3px;
}
.findings-item-text { color: var(--prose); }
.findings-item-conf {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--muted);
}
.findings-item-refs {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--muted);
}
/* ─── Live seed screen extras (M8 polish) ─── */
.seed-meta {
font-family: var(--font-mono);
font-size: 10px;
color: var(--muted);
margin-left: 8px;
}
.seed-input { display: flex; align-items: center; gap: 6px; flex: 1; }
.seed-input-field {
flex: 1;
border: none;
background: transparent;
outline: none;
font: inherit;
font-family: var(--font-prose);
font-size: 14px;
color: var(--fg);
min-width: 0;
}
.seed-input-field::placeholder { color: var(--muted); }
.seed-input-field:disabled { color: var(--muted); cursor: not-allowed; }
/* ─── TopBar polish (M8) ─── */
.topbar .brand { cursor: pointer; }
.topbar .brand:hover .brand-name { color: var(--accent); }
.topbar .breadcrumbs .bc-item:hover { color: var(--fg); }
.topbar-new {
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 500;
padding: 3px 10px;
border-radius: var(--radius-md);
border: 1px solid var(--accent);
background: var(--accent);
color: var(--accent-on);
text-decoration: none;
}
.topbar-new:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
/* ─── Rail click affordance + panel flash (M8 polish) ─── */
.rail-item-clickable { cursor: pointer; }
.rail-item-clickable:hover {
background: var(--accent-soft);
color: var(--accent-strong);
}
@keyframes panel-flash {
0% { background: var(--accent-soft); }
100% { background: transparent; }
}
.issues-panel-flash, .findings-panel-flash {
animation: panel-flash 0.9s ease-out;
}
/* Heading anchored target highlight */
@keyframes heading-flash {
0% { background: var(--accent-soft); }
100% { background: transparent; }
}
.tiptap .heading-flash {
animation: heading-flash 1.6s ease-out;
border-radius: 4px;
padding: 0 6px;
margin: 0 -6px;
}
/* ─── Pivoted shell (text-first) ─────────────────────────────────────── */
.shell-body-pivot {
display: grid;
grid-template-columns: 220px 1fr;
min-height: 0;
}
/* Left sidebar */
.leftsidebar {
border-right: 1px solid var(--border);
background: var(--surface);
padding: var(--space-2) var(--space-3);
overflow-y: auto;
font-size: var(--text-sm);
font-family: var(--font-body);
display: flex;
flex-direction: column;
gap: var(--space-4);
}
.leftsidebar-collapsed {
width: 32px;
padding: var(--space-2) 0;
align-items: center;
}
.leftsidebar-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 2px 2px;
}
.leftsidebar-title {
font-family: var(--font-display);
font-weight: 600;
font-size: var(--text-sm);
letter-spacing: 0.02em;
}
.leftsidebar-collapse-toggle {
width: 20px; height: 20px;
border: 1px solid transparent;
background: transparent;
color: var(--muted);
font-size: 13px; line-height: 1;
cursor: pointer; border-radius: var(--radius-sm);
}
.leftsidebar-collapse-toggle:hover { background: var(--surface-2); color: var(--fg); border-color: var(--border); }
.leftsidebar-group {
display: flex; flex-direction: column; gap: 2px;
}
.leftsidebar-group-label {
text-transform: uppercase;
letter-spacing: 0.08em;
font-size: 9.5px;
color: var(--muted);
font-family: var(--font-mono);
padding: 2px 4px;
}
.leftsidebar-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 1px;
}
.leftsidebar-row {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
gap: var(--space-2);
padding: 2px 5px;
border-radius: var(--radius-sm);
border: 1px solid transparent;
}
.leftsidebar-row:hover { background: var(--surface-2); }
.leftsidebar-row-open { background: var(--accent-soft); border-color: var(--accent); }
.leftsidebar-row-main {
display: flex; align-items: center; justify-content: space-between;
flex: 1; gap: var(--space-2);
background: transparent;
border: none;
padding: 1px 0;
font: inherit;
color: inherit;
cursor: pointer;
text-align: left;
min-width: 0;
}
.leftsidebar-row-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.leftsidebar-row-count {
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--muted);
flex-shrink: 0;
}
.leftsidebar-analyze {
width: 20px; height: 20px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--muted);
font-size: var(--text-xs);
border-radius: var(--radius-sm);
cursor: pointer;
font-family: var(--font-mono);
display: inline-flex;
align-items: center;
justify-content: center;
/* The ↻ glyph is rendered as the button's only child so it can be
* rotated as a unit when the LLM is working on this section. */
line-height: 1;
}
.leftsidebar-analyze:hover:not(:disabled) {
border-color: var(--accent);
color: var(--accent);
}
.leftsidebar-analyze:disabled { cursor: progress; opacity: 0.95; }
.leftsidebar-analyze-running {
color: var(--accent);
border-color: var(--accent);
}
/* Spinner SVG component handles its own animation (animateTransform), so
* .spinner here just needs alignment helpers. */
.spinner {
display: inline-block;
vertical-align: middle;
color: var(--accent);
}
/* Status slot keeps the row width consistent whether or not we render an indicator */
.leftsidebar-row-status-slot {
display: inline-block;
width: 10px;
height: 10px;
}
.leftsidebar-row-dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
margin: 0 2px;
}
.leftsidebar-row-dot-ok { background: var(--ok); }
.leftsidebar-row-dot-failed { background: var(--err, #b00020); }
.leftsidebar-spinner {
display: inline-block;
width: 10px;
height: 10px;
border: 1.5px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: leftsidebar-spin 0.8s linear infinite;
vertical-align: middle;
}
@keyframes leftsidebar-spin {
to { transform: rotate(360deg); }
}
/* Main workspace
* ─────────────────────────────────────────────────────────────────────────
* Layout: [.main-workspace-columns (h-scroll)] [.pane (text editor, fills)].
* Columns are stacked left-to-right (Finder-style miller columns); the inner
* container scrolls horizontally so deep chains stay reachable on narrow
* viewports without ever pushing the text editor offscreen.
*/
.main-workspace {
display: flex;
flex-direction: row;
align-items: stretch;
min-width: 0;
min-height: 0;
background: var(--bg);
}
.main-workspace-columns {
display: flex;
flex-direction: row;
align-items: stretch;
min-width: 0;
overflow-x: auto;
overflow-y: hidden;
}
.main-workspace > .pane {
flex: 1 1 0;
min-width: 360px;
border-left: 1px solid var(--border);
}
/* Wrapper that holds a section pane + its right-edge resize handle. */
.pane-with-handle {
position: relative;
display: flex;
flex-direction: column;
flex-shrink: 0;
flex-grow: 0;
border-right: 1px solid var(--border);
background: var(--bg);
}
.pane-with-handle > .pane {
flex: 1;
min-height: 0;
min-width: 0;
}
.pane-resize-handle {
position: absolute;
top: 0;
right: -3px;
width: 6px;
height: 100%;
cursor: col-resize;
z-index: 5;
background: transparent;
transition: background 0.12s ease;
}
.pane-resize-handle:hover,
.pane-resize-handle:active {
background: var(--accent-soft);
}
/* Pane frame */
.pane {
display: flex;
flex-direction: column;
min-width: 0;
min-height: 0;
}
.pane-header {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: var(--space-2) var(--space-4);
gap: var(--space-2) var(--space-3);
min-height: 34px;
border-bottom: 1px solid var(--border);
background: var(--surface);
flex-shrink: 0;
}
.pane-titles {
display: flex;
flex-direction: column;
gap: 0;
min-width: 0;
flex: 1 1 140px;
}
.pane-title {
font-family: var(--font-display);
font-weight: 600;
font-size: var(--text-lg);
line-height: var(--lh-tight);
letter-spacing: 0.01em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.pane-subtitle {
font-family: var(--font-mono);
font-size: var(--text-xs);
line-height: var(--lh-tight);
color: var(--muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-top: 1px;
}
/* On wide panes pane-right sits at the far right; on narrow panes it wraps
* to its own row underneath the title via the parent's flex-wrap. The cluster
* stays coherent (tabs + analyze + close) because it's a single flex item. */
.pane-right {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
margin-left: auto;
}
.pane-close {
width: 22px; height: 22px;
border: 1px solid transparent;
background: transparent;
color: var(--muted);
font-size: 14px; line-height: 1;
cursor: pointer; border-radius: var(--radius-md);
}
.pane-close:hover { background: var(--surface-2); color: var(--fg); border-color: var(--border); }
.pane-action {
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 500;
padding: 2px 9px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--fg);
border-radius: var(--radius-md);
cursor: pointer;
letter-spacing: 0;
}
.pane-action:hover:not(:disabled) {
border-color: var(--accent);
color: var(--accent);
}
.pane-action:disabled { cursor: not-allowed; opacity: 0.6; }
/* Legacy pane-tabs (kept for any unmigrated callers; new code uses
* .pane-controls + PaneViewTabs/PaneFilterChip). */
.pane-tabs {
display: inline-flex;
gap: 2px;
background: var(--surface-2);
padding: 2px;
border-radius: var(--radius-md);
align-items: center;
flex-wrap: wrap;
}
.pane-tab {
font-family: var(--font-mono);
font-size: var(--text-xs);
padding: 2px 7px;
border: none;
background: transparent;
color: var(--muted);
border-radius: var(--radius-sm);
cursor: pointer;
white-space: nowrap;
}
.pane-tab:disabled { opacity: 0.45; cursor: not-allowed; }
.pane-tab-active { background: var(--surface); color: var(--fg); box-shadow: 0 1px 2px var(--shadow); }
.pane-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.pane-empty {
padding: var(--space-5);
font-size: var(--text-md);
color: var(--muted);
font-style: italic;
}
/* Topbar Analyze All button */
.topbar-analyze-all {
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 500;
padding: 4px 11px;
border: 1px solid var(--accent);
background: var(--accent);
color: var(--accent-on);
border-radius: var(--radius-md);
cursor: pointer;
letter-spacing: 0;
}
.topbar-analyze-all:hover:not(:disabled) {
filter: brightness(1.06);
}
.topbar-analyze-all:disabled {
opacity: 0.6;
cursor: progress;
}
/* ─── Unified list-card shell ─────────────────────────────────────────
* Single rule for the three card kinds across the panes — Concepts uses
* term-tile for both Tree and AZ views (so they look identical bar the
* chevron column), Requirements uses req-row, Findings uses finding-row.
* Pads, fills, borders, radius, hover behavior, and `position: relative`
* (so .row-active's inset shadow renders) all live here. Per-kind classes
* only add layout-specific bits like the chevron column or head spacing. */
.term-tile,
.req-row,
.finding-row {
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: var(--space-2) var(--space-3);
user-select: none;
position: relative;
transition: border-color 100ms ease, background 100ms ease;
}
.term-tile:hover,
.req-row:hover,
.finding-row:hover {
border-color: var(--accent);
}
/* Term tiles (Concepts pane — Tree view) ─────────────────────────────────
* Each row is [chevron][content]. The row sits inside a tree-node <li>
* that carries a CSS custom property `--tree-depth` so we can render a
* faint vertical guide for every ancestor depth without per-component
* markup. Children render in a nested .term-list-children which has no
* extra padding (depth handles the inset). */
.term-list {
list-style: none;
margin: 0;
padding: var(--space-3);
display: flex;
flex-direction: column;
gap: var(--space-2);
overflow-y: auto;
}
.term-list-children {
padding: 0;
gap: var(--space-1);
margin-top: var(--space-1);
}
.term-tree-node {
--tree-indent: 14px;
position: relative;
display: flex;
flex-direction: column;
gap: var(--space-1);
/* Indent the entire node by depth × indent. Children inherit `--tree-depth`
* one greater than their parent via the inline style. */
padding-left: calc(var(--tree-depth, 0) * var(--tree-indent));
}
/* Vertical guide: a faint hairline aligned to the chevron column on each
* indent level. Drawn only when at depth ≥ 1. */
.term-tree-node[style*="--tree-depth"]:not([style*="--tree-depth: 0"])::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: calc((var(--tree-depth, 0) - 1) * var(--tree-indent) + 9px);
width: 1px;
background: var(--border);
pointer-events: none;
}
.term-tile {
display: flex;
align-items: flex-start;
gap: var(--space-2);
cursor: pointer;
}
.term-tile[draggable="true"] { cursor: grab; }
.term-tile[draggable="true"]:active { cursor: grabbing; }
.term-tile-chevron {
flex-shrink: 0;
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
background: transparent;
border: 1px solid transparent;
border-radius: var(--radius-sm);
font-family: var(--font-mono);
font-size: 10px;
color: var(--muted);
cursor: pointer;
margin-top: 1px;
}
.term-tile-chevron:hover {
background: var(--surface);
color: var(--fg);
border-color: var(--border);
}
.term-tile-chevron-empty {
cursor: default;
pointer-events: none;
/* Reserve the same width so labels at every depth align horizontally. */
}
.term-tile-content {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: var(--space-1);
}
/* Align concept-card head with req-row / finding-row: a flex row with the
* primary text on the left and the badge stack on the right. */
.term-tile-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-2);
}
/* Term name rendered as primary body text (not a serif heading), so the
* concept card reads as a "data row" alongside requirement/finding cards
* rather than a Notion-style article card. */
.term-label {
font-family: var(--font-body);
font-weight: 500;
font-size: var(--text-md);
line-height: var(--lh-ui);
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.term-def {
font-size: var(--text-sm);
line-height: var(--lh-ui);
color: var(--muted);
/* Two-line clamp keeps long definitions from dominating the list. The
* full text is still available in TermDetail. */
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.term-drag-hint {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--muted);
letter-spacing: 0.05em;
}
.term-linked {
font-family: var(--font-mono);
font-size: var(--text-xs);
padding: 1px 6px;
background: var(--accent-soft);
color: var(--accent-strong);
border: 1px solid var(--accent);
border-radius: var(--radius-sm);
cursor: pointer;
align-self: flex-start;
}
/* (Concepts AZ view now uses .term-list / .term-tile / ConceptCard, the
* same shell as Tree view. Old .glossary-row / .glossary-term / .glossary-
* def / .glossary-list classes are deleted — kept the container rule
* removed so any stale markup falls through to the unified card.) */
.term-def-empty { color: var(--muted); font-style: italic; }
/* Requirements */
.req-list {
list-style: none;
margin: 0;
padding: var(--space-3);
display: flex;
flex-direction: column;
gap: var(--space-2);
overflow-y: auto;
}
.req-row {
display: flex;
flex-direction: column;
gap: var(--space-1);
cursor: pointer;
}
/* Unsupported requirements get a left-edge warning stripe via inset
* box-shadow (same pattern as .row-active) so the shell stays consistent. */
.req-row-unsupported { box-shadow: inset 3px 0 0 var(--warn); }
.req-status-deprecated { opacity: 0.78; }
.req-status-deprecated .req-text { text-decoration: line-through; text-decoration-color: var(--muted); }
.req-term-link {
display: inline-block;
margin: var(--space-1) 0 0;
font-family: var(--font-mono);
font-size: var(--text-xs);
padding: 1px 6px;
background: var(--accent-soft);
color: var(--accent-strong);
border: 1px solid var(--accent);
border-radius: var(--radius-sm);
cursor: pointer;
}
.req-term-link:hover { background: var(--accent); color: var(--surface); }
.req-row-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-2);
}
.req-row-meta {
display: inline-flex;
align-items: center;
gap: var(--space-1);
flex-shrink: 0;
}
.req-tag {
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--muted);
letter-spacing: 0.04em;
flex-shrink: 0;
}
/* req-flag superseded by <StatusChip variant="warn" />; kept for legacy markup. */
.req-flag {
font-family: var(--font-mono);
font-size: 9.5px;
padding: 1px 6px;
background: var(--warn-soft);
color: var(--warn-strong);
border-radius: var(--radius-sm);
}
.req-text { font-size: var(--text-md); line-height: var(--lh-ui); }
.req-traced { font-size: var(--text-sm); color: var(--muted); margin-top: var(--space-1); }
.req-traced-link {
background: none;
border: none;
font: inherit;
color: var(--accent);
cursor: pointer;
padding: 0;
text-decoration: underline dotted;
}
/* Findings */
.finding-list {
list-style: none;
margin: 0;
padding: var(--space-3);
display: flex;
flex-direction: column;
gap: var(--space-2);
overflow-y: auto;
}
.finding-row {
display: flex;
flex-direction: column;
gap: var(--space-1);
cursor: pointer;
}
.finding-row-open { background: var(--surface); }
.finding-row-head {
display: grid;
grid-template-columns: auto 1fr auto;
gap: var(--space-2);
align-items: start;
width: 100%;
background: transparent;
border: none;
font: inherit;
color: inherit;
cursor: pointer;
text-align: left;
padding: 1px 0;
}
.finding-disc { font-family: var(--font-mono); color: var(--muted); flex-shrink: 0; }
.finding-text { font-size: var(--text-md); line-height: var(--lh-ui); }
.finding-meta {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
flex-shrink: 0;
}
.finding-conf { color: var(--muted); }
/* finding-code superseded by <StatusChip variant="code" />; legacy. */
.finding-code {
font-family: var(--font-mono);
font-size: 9.5px;
padding: 1px 5px;
background: var(--surface-2);
color: var(--muted);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
}
.finding-anchors {
display: flex;
gap: var(--space-2);
padding: 0 var(--space-3) var(--space-2) var(--space-5);
}
.finding-anchor {
font-family: var(--font-mono);
font-size: var(--text-xs);
padding: 1px 6px;
background: var(--accent-soft);
color: var(--accent-strong);
border: 1px solid var(--accent);
border-radius: 3px;
cursor: pointer;
}
.finding-anchor:hover { background: var(--accent); color: var(--surface); }
/* Review state on findings */
/* finding-status-suggested / -deprecated styling lives in the unified card
* status block lower in this file, so all four card kinds share one idiom. */
.term-decide-resolve {
color: var(--ink);
background: var(--surface-2);
border-color: var(--border);
}
.term-decide-resolve:hover { border-color: var(--accent); }
/* Active row indicator: the row in this column whose detail is open in the
* next column. Reused across Concepts, Model summary, Requirements, Findings.
* Idiom: 3px solid accent strip on the left edge + soft accent fill, no
* homemade glyph (replaced the previous '' arrow). The !important on the
* box-shadow wins over the suggested/deprecated status stripe so an active
* pending row still shows accent (active state trumps review state). */
.row-active {
background: var(--accent-soft) !important;
box-shadow: inset 3px 0 0 var(--accent) !important;
border-color: var(--accent) !important;
}
/* ─── StatusChip — unified state idiom ──────────────────────────────────
* Legibility first: 12px mono, weight 600, 20px height, generous letter
* spacing on the all-caps glyphs. Text colors lean strong (fg / accent-
* strong / warn-strong / ok-strong) rather than muted, so the chips read
* cleanly even at the small sizes used inside finding-meta stacks.
* Tabular figures align numeric chips when stacked. */
.status-chip {
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--font-mono);
font-size: 12px;
font-weight: 400;
letter-spacing: 0.05em;
line-height: 1;
padding: 0 8px;
border-radius: var(--radius-sm);
user-select: none;
white-space: nowrap;
height: 20px;
font-feature-settings: "tnum", "lnum";
}
.status-chip-accent {
background: var(--accent);
color: var(--accent-on);
}
.status-chip-muted {
background: var(--surface-2);
color: var(--fg);
border: 1px solid var(--border-strong);
}
.status-chip-warn {
background: var(--warn-soft);
color: var(--warn-strong);
border: 1px solid var(--warn);
}
.status-chip-ok {
background: var(--ok-soft);
color: var(--ok-strong);
border: 1px solid var(--ok);
}
.status-chip-info {
background: var(--surface);
color: var(--accent-strong);
border: 1px solid var(--accent-strong);
}
/* ─── PaneViewTabs — segmented control for view modes ────────────────── */
.pane-view-tabs {
display: inline-flex;
background: var(--surface-2);
border-radius: var(--radius-md);
padding: 2px;
gap: 1px;
}
.pane-view-tab {
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 500;
padding: 2px 8px;
border: none;
background: transparent;
color: var(--muted);
border-radius: var(--radius-sm);
cursor: pointer;
white-space: nowrap;
}
.pane-view-tab-active {
background: var(--surface);
color: var(--fg);
box-shadow: 0 1px 2px var(--shadow);
}
.pane-view-tab:hover:not(.pane-view-tab-active) { color: var(--fg); }
/* ─── PaneFilterChip — filter toggle with optional count pip ──────────── */
.pane-filter-chip {
display: inline-flex;
align-items: center;
gap: 5px;
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 500;
padding: 2px 8px;
background: transparent;
color: var(--muted);
border: 1px solid var(--border);
border-radius: var(--radius-md);
cursor: pointer;
white-space: nowrap;
}
.pane-filter-chip:hover:not(:disabled) { border-color: var(--accent); color: var(--fg); }
.pane-filter-chip-attention { color: var(--accent-strong); border-color: var(--accent); font-weight: 600; }
.pane-filter-chip-active {
background: var(--accent);
color: var(--accent-on);
border-color: var(--accent);
}
.pane-filter-chip:disabled { opacity: 0.45; cursor: not-allowed; }
.pane-filter-chip-pip {
display: inline-block;
min-width: 12px;
height: 12px;
padding: 0 3px;
font-size: 8.5px;
font-weight: 600;
line-height: 12px;
text-align: center;
background: var(--accent);
color: var(--accent-on);
border-radius: 7px;
}
.pane-filter-chip-active .pane-filter-chip-pip {
background: var(--accent-on);
color: var(--accent);
}
/* ─── PaneEmpty — unified empty state ─────────────────────────────────── */
.pane-empty-v2 {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: var(--space-3);
padding: var(--space-5);
font-size: var(--text-md);
color: var(--muted);
}
.pane-empty-icon {
font-family: var(--font-mono);
font-size: var(--text-md);
color: var(--muted);
}
.pane-empty-title {
font-family: var(--font-display);
font-weight: 600;
font-size: var(--text-lg);
color: var(--fg);
line-height: var(--lh-tight);
}
.pane-empty-hint { font-style: italic; line-height: var(--lh-ui); }
.pane-empty-action {
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 500;
padding: 3px 10px;
border: 1px solid var(--accent);
background: var(--accent);
color: var(--accent-on);
border-radius: var(--radius-md);
cursor: pointer;
}
.pane-empty-action:hover:not(:disabled) { filter: brightness(1.05); }
.pane-empty-action:disabled { opacity: 0.5; cursor: not-allowed; }
/* ─── LeftSidebar pending-count chip ──────────────────────────────────── */
/* ─── PaneDrawer — collapsible group at the bottom of a list pane ────── */
.pane-drawer {
display: flex;
flex-direction: column;
flex-shrink: 0;
border-top: 1px solid var(--border);
background: var(--surface);
}
.pane-drawer-pending {
border-top: 1px solid var(--accent);
background: linear-gradient(
to bottom,
color-mix(in srgb, var(--accent-soft) 55%, var(--surface)) 0%,
var(--surface) 28px
);
}
.pane-drawer-muted {
background: var(--surface-2);
}
.pane-drawer-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-2) var(--space-3);
gap: var(--space-2);
}
.pane-drawer-toggle {
display: inline-flex;
align-items: center;
gap: var(--space-2);
background: transparent;
border: none;
cursor: pointer;
padding: 0;
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 600;
color: var(--fg);
}
.pane-drawer-muted .pane-drawer-toggle { color: var(--muted-strong); }
.pane-drawer-caret {
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--muted);
width: 10px;
display: inline-block;
}
.pane-drawer-title { letter-spacing: 0.02em; }
.pane-drawer-count {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 18px;
height: 16px;
padding: 0 5px;
font-family: var(--font-mono);
font-size: 10px;
font-weight: 600;
color: var(--muted-strong);
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: 8px;
}
.pane-drawer-pending .pane-drawer-count {
color: var(--accent-on);
background: var(--accent);
border-color: var(--accent);
}
.pane-drawer-action { display: inline-flex; align-items: center; gap: var(--space-1); }
.pane-drawer-body {
border-top: 1px dashed var(--border);
max-height: 50vh;
overflow-y: auto;
}
/* Pane bodies that use the drawer layout: kept list fills the top
* (scrollable), drawers stack at the bottom. */
.pane-drawer-stack {
flex: 1 1 0;
min-height: 0;
display: flex;
flex-direction: column;
}
.pane-drawer-main {
flex: 1 1 0;
min-height: 0;
overflow-y: auto;
}
/* Container for the two-cluster pane header right-slot (view tabs + filter
* chip + analyze button). Replaces the pane-tabs container that mixed
* concerns. */
.pane-controls {
display: inline-flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.leftsidebar-pending-chip {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 16px;
height: 13px;
padding: 0 4px;
margin-left: var(--space-2);
font-family: var(--font-mono);
font-size: 9px;
font-weight: 600;
background: var(--accent);
color: var(--accent-on);
border-radius: 7px;
}
/* (position: relative now lives on the unified shell rule near the top of
* this file; this block was redundant.) */
/* Detail-column scrollable body (TermColumn / BlockColumn / etc.) */
.column-body {
flex: 1 1 0;
min-height: 0;
overflow-y: auto;
background: var(--surface);
}
.column-review-row { display: inline-flex; align-items: center; gap: var(--space-2); }
/* Block detail-column properties */
.block-prop-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.block-prop {
display: flex; justify-content: space-between; gap: var(--space-2);
padding: var(--space-1) var(--space-3);
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: var(--radius-md);
font-size: var(--text-sm);
}
.block-prop-name { font-weight: 600; }
.block-prop-type { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted); }
/* Constraint expression */
.constraint-expr {
display: block;
padding: var(--space-2) var(--space-3);
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: var(--radius-md);
font-family: var(--font-mono);
font-size: var(--text-sm);
line-height: var(--lh-ui);
}
/* Finding row in the listing pane (no expand-in-place anymore) */
.finding-row-head-static { padding: var(--space-1) 0; }
.termdetail-finding-btn {
display: flex;
width: 100%;
text-align: left;
background: transparent;
border: none;
padding: 0;
cursor: pointer;
gap: var(--space-2);
align-items: baseline;
}
.finding-sev {
padding: 1px 5px;
border-radius: 3px;
font-size: 9.5px;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.finding-sev-low { background: var(--surface-2); color: var(--muted); border: 1px solid var(--border); }
.finding-sev-medium { background: var(--warn-soft, #fff5d6); color: var(--warn-strong, #b58900); }
.finding-sev-high { background: var(--err-soft, #ffe0e0); color: var(--err, #b00020); }
.finding-thread { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
/* Contextual Socrates thread */
.ctx-thread { display: flex; flex-direction: column; gap: 8px; }
.ctx-thread-messages {
display: flex;
flex-direction: column;
gap: 8px;
max-height: 320px;
overflow-y: auto;
padding-right: 4px;
}
.ctx-thread-loading { font-family: var(--font-mono); font-size: 11px; color: var(--muted); padding: 6px; }
.ctx-bubble { display: flex; gap: 8px; align-items: flex-start; }
.ctx-bubble-user { padding-left: 24px; }
.ctx-bubble-assistant { }
.ctx-bubble-body {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 5px;
padding: 6px 10px;
font-size: 12px;
line-height: 1.5;
max-width: 100%;
}
.ctx-bubble-user .ctx-bubble-body { background: var(--accent-soft); border-color: var(--accent); }
.ctx-bubble-options { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.ctx-option {
background: transparent;
border: 1px solid var(--border);
font: inherit;
font-size: 11.5px;
padding: 3px 8px;
border-radius: 4px;
cursor: pointer;
text-align: left;
}
.ctx-option:hover { border-color: var(--accent); background: var(--surface-2); }
.ctx-option-n { font-family: var(--font-mono); color: var(--muted); margin-right: 6px; }
.ctx-option-sub { font-size: 10.5px; color: var(--muted); margin-left: 6px; }
.ctx-thread-input-row { display: flex; gap: 6px; }
.ctx-thread-input {
flex: 1;
font: inherit;
font-size: 12px;
padding: 6px 8px;
border: 1px solid var(--border);
border-radius: 4px;
background: var(--surface);
resize: vertical;
}
.ctx-thread-actions { display: flex; flex-direction: column; gap: 4px; }
.ctx-send {
font-family: var(--font-mono);
font-size: 11px;
padding: 4px 10px;
border: 1px solid var(--accent);
background: var(--accent);
color: var(--accent-on, #fff);
border-radius: 4px;
cursor: pointer;
}
.ctx-send:disabled { opacity: 0.5; cursor: not-allowed; }
.ctx-thread-resolve { display: flex; gap: 6px; padding-top: 4px; border-top: 1px dashed var(--border); }
.ctx-resolve-btn,
.ctx-dismiss-btn {
font-family: var(--font-mono);
font-size: 10.5px;
padding: 3px 8px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--muted);
border-radius: 4px;
cursor: pointer;
}
.ctx-resolve-btn:hover { color: var(--ok); border-color: var(--ok); }
.ctx-dismiss-btn:hover { color: var(--err, #b00020); border-color: var(--err, #b00020); }
/* Model summary */
.model-summary { padding: 12px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; }
.model-summary-h { margin: 0; font-family: var(--font-display); font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.model-summary-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.model-summary-row {
display: grid;
grid-template-columns: 64px 1fr auto;
align-items: center;
gap: 8px;
padding: 4px 8px;
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: 4px;
cursor: pointer;
font: inherit;
text-align: left;
width: 100%;
}
.model-summary-row-static { cursor: default; }
.model-summary-row:hover { border-color: var(--accent); }
.model-summary-kind {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.model-summary-label { font-size: 12px; }
.model-summary-row-wrap { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.model-summary-row-wrap .model-summary-row { flex: 1; min-width: 0; }
.model-status-suggested { padding: 2px 0 2px 6px; border-left: 2px solid var(--accent); }
.model-status-deprecated { opacity: 0.78; }
.model-status-deprecated .model-summary-label { text-decoration: line-through; text-decoration-color: var(--muted); }
.model-decide-row { display: inline-flex; gap: 5px; }
/* Diagram nodes — review state */
.sysml-node-review-suggested {
outline: 2px dashed var(--accent);
outline-offset: 2px;
}
.sysml-node-review-deprecated {
opacity: 0.55;
filter: grayscale(0.4);
}
.model-summary-link {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--accent-strong);
background: var(--accent-soft);
padding: 2px 7px;
border-radius: 3px;
border: 1px solid var(--accent);
cursor: pointer;
}
.model-summary-link:hover { background: var(--accent); color: var(--surface); }
/* Chip suggestion (taxonomy term match in plain text) */
.chip-suggestion {
text-decoration: underline dotted var(--accent);
text-underline-offset: 3px;
cursor: pointer;
}
.chip-suggestion:hover {
background: var(--accent-soft);
border-radius: 2px;
}
/* Concepts pane — focus ring shared with req/finding rows. The term-tile
* cursor + term-tile-head layout live near the unified card-shell rule
* earlier in this file. */
.term-tile:focus-visible,
.req-row:focus-visible,
.finding-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.term-linked-dot {
font-size: 11px;
line-height: 1;
color: var(--accent-strong);
align-self: center;
user-select: none;
}
/* Review state on cards — same idiom across term-tile, glossary-row,
* req-row, and finding-row: a left-edge stripe (via inset box-shadow,
* matching .row-active) and a strikethrough on the title for deprecated. */
.term-status-suggested,
.req-status-suggested,
.finding-status-suggested {
background: var(--accent-soft);
box-shadow: inset 3px 0 0 var(--accent);
}
.term-status-deprecated,
.req-status-deprecated,
.finding-status-deprecated {
opacity: 0.78;
box-shadow: inset 3px 0 0 var(--muted);
}
.term-status-deprecated .term-label,
.req-status-deprecated .req-text,
.finding-status-deprecated .finding-text {
text-decoration: line-through;
text-decoration-color: var(--muted);
}
.term-badge {
font-family: var(--font-mono);
font-size: 9px;
letter-spacing: 0.05em;
padding: 2px 6px;
border-radius: 3px;
font-weight: 600;
user-select: none;
}
.term-badge-new {
background: var(--accent);
color: var(--surface);
}
.term-badge-deprecated {
background: var(--surface-2);
color: var(--muted);
border: 1px solid var(--border);
}
.term-decision-row {
display: flex;
gap: var(--space-1);
margin-top: var(--space-2);
}
.term-decide {
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 500;
padding: 2px 9px;
border-radius: var(--radius-sm);
cursor: pointer;
border: 1px solid var(--border);
background: var(--surface);
color: var(--fg);
}
.term-decide:hover { border-color: var(--accent); }
.term-decide-keep {
background: var(--accent);
color: var(--accent-on);
border-color: var(--accent);
}
.term-decide-keep:hover { filter: brightness(1.05); }
.term-decide-discard {
color: var(--muted);
}
.term-decide-discard:hover { color: var(--fg); border-color: var(--muted); }
/* Pending tab in pane header — pip + attention indicator */
.pane-tab-attention { color: var(--accent-strong); font-weight: 600; }
.pane-tab-pip {
display: inline-block;
margin-left: 4px;
min-width: 13px;
height: 13px;
padding: 0 3px;
font-family: var(--font-mono);
font-size: 8.5px;
font-weight: 600;
line-height: 13px;
text-align: center;
background: var(--accent);
color: var(--surface);
border-radius: 7px;
vertical-align: 1px;
}
/* TermDetail popover — right-side sheet driven by focusTermId */
.termdetail-scrim {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.18);
z-index: 90;
animation: termdetail-fade 120ms ease-out;
}
.termdetail {
position: fixed;
top: 0;
right: 0;
bottom: 0;
width: min(440px, 90vw);
background: var(--surface);
border-left: 1px solid var(--border);
box-shadow: -8px 0 24px rgba(0, 0, 0, 0.08);
z-index: 91;
display: flex;
flex-direction: column;
overflow-y: auto;
animation: termdetail-slide 160ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
@keyframes termdetail-slide {
from { transform: translateX(20px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes termdetail-fade {
from { opacity: 0; }
to { opacity: 1; }
}
.termdetail-head {
position: sticky;
top: 0;
background: var(--surface);
padding: 18px 22px 12px;
border-bottom: 1px solid var(--border);
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: auto auto;
column-gap: 12px;
z-index: 1;
}
.termdetail-eyebrow {
grid-row: 1;
font-family: var(--font-mono);
font-size: 9.5px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--muted);
}
.termdetail-title {
grid-row: 2;
margin: 4px 0 0 0;
font-family: var(--font-display);
font-size: 22px;
font-weight: 600;
line-height: 1.2;
}
.termdetail-close {
grid-row: 1 / span 2;
align-self: start;
background: transparent;
border: 1px solid var(--border);
border-radius: 4px;
width: 28px;
height: 28px;
cursor: pointer;
font-size: 13px;
color: var(--muted);
}
.termdetail-close:hover { color: var(--ink); border-color: var(--accent); }
.termdetail-section {
padding: var(--space-4) var(--space-5);
border-bottom: 1px solid var(--border);
}
.termdetail-section:last-child { border-bottom: none; }
.termdetail-section-h {
margin: 0 0 var(--space-2) 0;
font-family: var(--font-mono);
font-size: 9.5px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--muted);
font-weight: 500;
}
/* Section header gains an optional right slot for inline meta (e.g. the
* "pinned" chip on the Definition section). */
.termdetail-section-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-2);
margin: 0 0 var(--space-2) 0;
}
.termdetail-section-head .termdetail-section-h { margin: 0; }
.termdetail-section-right { display: inline-flex; align-items: center; gap: var(--space-1); }
.termdetail-section-body { font-size: var(--text-md); line-height: var(--lh-prose); }
.termdetail-def { margin: 0; line-height: var(--lh-prose); }
.termdetail-empty { margin: 0; color: var(--muted); font-style: italic; font-size: var(--text-sm); line-height: var(--lh-ui); }
/* Click-to-edit affordance on the read state. Subtle: cursor + focus ring +
* a faint underline-on-hover so users see it's editable without making the
* card noisy. */
.termdetail-def-clickable {
cursor: text;
border-radius: var(--radius-sm);
margin: calc(var(--space-1) * -1) calc(var(--space-2) * -1);
padding: var(--space-1) var(--space-2);
transition: background 100ms;
}
.termdetail-def-clickable:hover {
background: var(--surface-2);
}
.termdetail-def-clickable:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 1px;
}
.termdetail-def-empty-btn {
display: inline-block;
background: transparent;
border: 1px dashed var(--border-strong);
text-align: left;
width: 100%;
}
.termdetail-def-empty-btn:hover { border-color: var(--accent); color: var(--fg); }
/* Inline editor */
.termdetail-def-edit {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.termdetail-def-textarea {
font-family: var(--font-prose);
font-size: var(--text-md);
line-height: var(--lh-prose);
padding: var(--space-2) var(--space-3);
background: var(--surface);
color: var(--fg);
border: 1px solid var(--accent);
border-radius: var(--radius-md);
resize: vertical;
min-height: 60px;
}
.termdetail-def-textarea:focus { outline: none; box-shadow: 0 0 0 2px var(--accent-soft); }
.termdetail-def-actions {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--space-2);
}
.termdetail-def-btn {
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 500;
padding: 3px 10px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--fg);
border-radius: var(--radius-md);
cursor: pointer;
}
.termdetail-def-btn:hover { border-color: var(--accent); }
.termdetail-def-btn-primary {
background: var(--accent);
color: var(--accent-on);
border-color: var(--accent);
}
.termdetail-def-btn-primary:hover { filter: brightness(1.05); }
.termdetail-def-link {
background: none;
border: none;
padding: 0;
font: inherit;
color: var(--accent-strong);
cursor: pointer;
text-decoration: underline dotted;
font-size: var(--text-sm);
}
.termdetail-def-link:hover { color: var(--accent); }
.termdetail-def-hint {
margin-left: auto;
font-family: var(--font-mono);
font-size: 10px;
color: var(--muted);
}
.termdetail-row {
display: flex;
gap: var(--space-3);
align-items: baseline;
flex-wrap: wrap;
margin-bottom: var(--space-1);
}
.termdetail-row-label {
font-family: var(--font-mono);
font-size: 9.5px;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--muted);
min-width: 56px;
}
.termdetail-row-body {
display: inline-flex;
gap: var(--space-2);
flex-wrap: wrap;
align-items: center;
}
.termdetail-chip {
display: inline-block;
padding: 1px 7px;
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: var(--radius-md);
font-size: var(--text-sm);
cursor: pointer;
}
.termdetail-chip:hover { border-color: var(--accent); background: var(--accent-soft); }
.termdetail-synonym {
display: inline-block;
padding: 1px 6px;
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--muted);
background: var(--surface-2);
border-radius: var(--radius-sm);
}
.termdetail-formalism-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.termdetail-formalism {
display: flex;
align-items: center;
gap: var(--space-3);
width: 100%;
padding: var(--space-2) var(--space-3);
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: var(--radius-md);
cursor: pointer;
text-align: left;
}
.termdetail-formalism:hover:not(.termdetail-formalism-static) { border-color: var(--accent); }
.termdetail-formalism-static { cursor: default; }
.termdetail-formalism-static:hover { border-color: var(--border); }
.termdetail-formalism-kind {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.termdetail-formalism-label { flex: 1; font-weight: 600; font-size: var(--text-md); }
.termdetail-formalism-jump { font-size: var(--text-xs); color: var(--accent-strong); }
.termdetail-findings {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.termdetail-finding {
display: flex;
gap: var(--space-2);
align-items: baseline;
padding: var(--space-2) var(--space-3);
background: var(--surface-2);
border: 1px solid var(--border);
border-left-width: 3px;
border-radius: var(--radius-md);
font-size: var(--text-sm);
line-height: var(--lh-ui);
}
.termdetail-finding-assumption { border-left-color: #d4a017; }
.termdetail-finding-risk { border-left-color: #b03030; }
.termdetail-finding-inconsistency { border-left-color: #5a5a8a; }
.termdetail-finding-kind {
font-family: var(--font-mono);
font-size: 9.5px;
text-transform: uppercase;
color: var(--muted);
letter-spacing: 0.05em;
}
.termdetail-finding-text { flex: 1; }
/* Promote toolbar (TermColumn) */
.promote-toolbar { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.promote-btn {
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: 500;
padding: 3px 10px;
background: var(--surface-2);
color: var(--fg);
border: 1px solid var(--border);
border-radius: var(--radius-md);
cursor: pointer;
}
.promote-btn:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); }
.promote-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.promote-btn-primary { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.promote-btn-primary:hover:not(:disabled) { filter: brightness(1.05); }
.promote-form {
display: flex;
flex-direction: column;
gap: var(--space-3);
padding: var(--space-3);
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: var(--radius-md);
}
.promote-form-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: var(--space-3);
}
.promote-form-title { font-weight: 600; font-size: var(--text-md); line-height: var(--lh-tight); }
.promote-form-subtitle {
font-family: var(--font-mono);
font-size: 9.5px;
color: var(--muted);
margin-top: 1px;
}
.promote-form-cancel {
background: transparent;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
width: 20px;
height: 20px;
cursor: pointer;
font-size: var(--text-xs);
color: var(--muted);
}
.promote-form-cancel:hover { color: var(--fg); border-color: var(--accent); }
.promote-field { display: flex; flex-direction: column; gap: 2px; }
.promote-field-label {
font-family: var(--font-mono);
font-size: 9.5px;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--muted);
}
.promote-input,
.promote-textarea {
font: inherit;
font-size: var(--text-sm);
padding: 4px 7px;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius-md);
color: var(--fg);
}
.promote-input:focus,
.promote-textarea:focus { outline: none; border-color: var(--accent); }
.promote-textarea { resize: vertical; min-height: 42px; font-family: var(--font-display); line-height: var(--lh-ui); }
.promote-checkbox-list {
display: flex;
flex-direction: column;
gap: 2px;
max-height: 130px;
overflow-y: auto;
}
.promote-checkbox { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); cursor: pointer; }
.promote-empty { font-size: var(--text-sm); color: var(--muted); font-style: italic; }
.promote-form-actions { display: flex; justify-content: flex-end; gap: var(--space-2); }
@keyframes promote-flash {
0% { background: var(--accent-soft); }
100% { background: transparent; }
}
.termdetail-flash-block,
.termdetail-flash-association,
.termdetail-flash-constraint,
.termdetail-flash-requirement {
animation: promote-flash 1100ms ease-out;
}