@import '_content/Blazored.Toast/Blazored.Toast.bundle.scp.css';

/* /Components/Analytics/MarginBreakdown.razor.rz.scp.css */
/* The Margin pane's tree, from the CRIF workspaces' results tree with its literals turned into
   tokens: one value column, the root rows in the brand colour, and the notes at the foot. */

.margin-breakdown[b-r1zd08fz8v] {
    font-size: var(--cpd-text-1);
}

/* The header and every row are one grid — chevron, label, then the figure columns — so a heading
   sits over its figures: the tracks are sized in the row's own font, never the figure's or the
   heading's (a `ch` taken in the mono figure and in the small heading are different widths). One
   figure column sizes to its content; the drill-down's three are equal and fixed. */
.margin-header[b-r1zd08fz8v],
.margin-row[b-r1zd08fz8v] {
    display: grid;
    grid-template-columns: var(--cpd-space-lg) minmax(0, 1fr) max-content;
    column-gap: var(--cpd-space-sm);
    align-items: baseline;
}

.margin-header.margin-compare[b-r1zd08fz8v],
.margin-row.margin-compare[b-r1zd08fz8v] {
    grid-template-columns: var(--cpd-space-lg) minmax(0, 1fr) repeat(3, 18ch);
}

.margin-header[b-r1zd08fz8v] {
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border-bottom: 1px solid var(--cpd-border-subtle);
    margin-bottom: var(--cpd-space-xs);
}

.margin-header-label[b-r1zd08fz8v] {
    font-size: var(--cpd-text-0);
    text-transform: uppercase;
    text-align: right;
    color: var(--cpd-text-muted);
}

/* A one-column tree's line: the row, then the ƒx trigger's column when the pane has a formula fetch
   (an empty track otherwise). The trigger sits beside the row's button, not in it, so each is its
   own control; its column is as wide as the trigger, so a row without one keeps the figures in line. */
.margin-line[b-r1zd08fz8v] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
}

.margin-fx[b-r1zd08fz8v] {
    display: flex;
    justify-content: center;
    width: var(--cpd-space-2xl);
}

/* Two triggers, ƒx and Top Contributors: the column holds both. */
.margin-fx.margin-fx-pair[b-r1zd08fz8v] {
    width: calc(2 * var(--cpd-space-2xl));
}

/* A row's largest contributors, under it one depth in: a quiet note, then a line per trade in the
   row's own grid — name, share of the figure, allocation under the figure's column. */
.margin-contributors[b-r1zd08fz8v] {
    padding: 0 var(--cpd-space-sm) var(--cpd-space-xs);
    padding-left: calc(var(--cpd-space-sm) + var(--cpd-space-lg) + var(--margin-depth) * var(--cpd-space-lg));
    font-size: var(--cpd-text-0);
}

.margin-contributor[b-r1zd08fz8v] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) max-content max-content;
    column-gap: var(--cpd-space-md);
    align-items: baseline;
    color: var(--cpd-text-muted);
}

.margin-contributor-share[b-r1zd08fz8v] {
    min-width: 7ch;
}

.margin-contributors-note[b-r1zd08fz8v] {
    margin: var(--cpd-space-xs) 0 0;
    color: var(--cpd-text-muted);
}

/* A button and a div share the row look: the button's own chrome is reset so an open-able row reads
   as the same line as a leaf. The depth indents by one spacing step per level. */
.margin-row[b-r1zd08fz8v] {
    width: 100%;
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    padding-left: calc(var(--cpd-space-sm) + var(--margin-depth) * var(--cpd-space-lg));
    border: 0;
    border-radius: var(--cpd-radius-sm);
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
}

button.margin-row[b-r1zd08fz8v] {
    cursor: pointer;
}

button.margin-row:hover[b-r1zd08fz8v] {
    background: var(--cpd-surface-hover);
}

button.margin-row:focus-visible[b-r1zd08fz8v] {
    outline: 2px solid var(--cpd-gold);
    outline-offset: 2px;
}

.margin-chevron[b-r1zd08fz8v] {
    text-align: center;
    color: var(--cpd-text-muted);
}

.margin-label[b-r1zd08fz8v] {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.margin-root .margin-label[b-r1zd08fz8v] {
    font-weight: 600;
    color: var(--cpd-gold);
}

.margin-value[b-r1zd08fz8v] {
    font-family: var(--cpd-font-mono);
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

.margin-notes[b-r1zd08fz8v] {
    margin: var(--cpd-space-md) 0 0;
    padding-left: var(--cpd-space-lg);
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}

.margin-figures[b-r1zd08fz8v] {
    margin-bottom: var(--cpd-space-md);
}

.margin-section-heading[b-r1zd08fz8v] {
    margin: var(--cpd-space-md) 0 var(--cpd-space-xs);
    font-size: var(--cpd-text-1);
    font-weight: 600;
}

.margin-note-group .margin-notes[b-r1zd08fz8v] {
    margin-top: 0;
}

.margin-note-text[b-r1zd08fz8v] {
    color: var(--cpd-text);
}

.margin-note-details[b-r1zd08fz8v] {
    margin: var(--cpd-space-xs) 0 var(--cpd-space-sm);
    padding-left: var(--cpd-space-lg);
    overflow-wrap: anywhere;
}

button.margin-row:disabled[b-r1zd08fz8v] {
    cursor: default;
    color: inherit;
}

.margin-aggregation-note[b-r1zd08fz8v] {
    margin: 0 0 var(--cpd-space-md);
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}

/* The Incremental | Standalone switch: word buttons, each sized to its label, as the Sensitivities
   page's view switch is. */
.margin-view-switcher[b-r1zd08fz8v] {
    width: fit-content;
    margin-bottom: var(--cpd-space-xs);
}

.margin-view-switcher .trade-mode-btn[b-r1zd08fz8v] {
    width: auto;
    height: auto;
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    font-size: var(--cpd-text-0);
    white-space: nowrap;
}

.margin-view-note[b-r1zd08fz8v] {
    margin: 0 0 var(--cpd-space-md);
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}
/* /Components/Analytics/MarginProfileChart.razor.rz.scp.css */
/* The Reg Calcs Profile chart's series, over the shared chart block (.cpd-chart, app.css: the frame,
   axes and hover readout). Its series take the shared chart slots (--cpd-series-1..3, app.css), and
   FRTB capital, the headline line, the text colour: a fourth hue would need validating, and the
   capital is what a reader reads first. Each mark takes its colour from its slot class through
   --mp-colour, so a line, a hover dot and a legend or readout sample of one series are one colour by
   construction. Text stays in text tokens, never a series colour. */
.series-1[b-bumoxlbae6] { --mp-colour: var(--cpd-series-1); }
.series-2[b-bumoxlbae6] { --mp-colour: var(--cpd-series-2); }
.series-3[b-bumoxlbae6] { --mp-colour: var(--cpd-series-3); }
.series-total[b-bumoxlbae6] { --mp-colour: var(--cpd-text); }

.mp-legend[b-bumoxlbae6] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-xs) var(--cpd-space-md);
    margin-bottom: var(--cpd-space-xs);
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}

.mp-legend-item[b-bumoxlbae6] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
}

/* A legend sample is a short length of its series' line, drawn with the line's own classes. */
.mp-swatch[b-bumoxlbae6] {
    width: var(--cpd-space-lg);
    height: var(--cpd-space-xs);
    overflow: visible;
}

/* The Exposure Profile's line (2 wide, round): SIMM's two lines and FRTB capital. FRTB's charges sit
   beneath the capital, thinner, and differ from one another by dash as well as colour: the light
   scheme's orange and aqua are under 3:1 against the page, so they never rest on colour alone. */
.mp-line[b-bumoxlbae6] {
    fill: none;
    stroke: var(--mp-colour);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.mp-line.charge[b-bumoxlbae6] {
    stroke-width: 1.5;
}

.mp-line.dashed[b-bumoxlbae6] {
    stroke-dasharray: 8 5;
}

.mp-line.dotted[b-bumoxlbae6] {
    stroke-dasharray: 1 5;
}

.mp-dot[b-bumoxlbae6],
.mp-chart .chart-hover-dot[b-bumoxlbae6] {
    fill: var(--mp-colour);
}
/* /Components/Analytics/MarginProfilePane.razor.rz.scp.css */
/* The Reg Calcs Profile pane: a toolbar over the one view shown, then the notes. */
.margin-profile-pane[b-28c8oi84cq] {
    font-size: var(--cpd-text-1);
}

/* The group picker at the left, the view switch and the export cluster at the right; they wrap
   onto two lines in a narrow pane rather than squeezing the picker's names. */
.mp-toolbar[b-28c8oi84cq] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--cpd-space-sm);
    margin-bottom: var(--cpd-space-sm);
}

.mp-toolbar-actions[b-28c8oi84cq] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    margin-left: auto;
}

/* The group picker's buttons carry names, so each sizes to its label, as the view switch's do. */
.mp-group-picker[b-28c8oi84cq] {
    width: fit-content;
}

.mp-group-picker .trade-mode-btn[b-28c8oi84cq] {
    width: auto;
    height: auto;
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    font-size: var(--cpd-text-0);
    white-space: nowrap;
}

.mp-notes[b-28c8oi84cq] {
    margin: var(--cpd-space-md) 0 0;
    padding-left: var(--cpd-space-lg);
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}
/* /Components/Analytics/PaneViewSwitcher.razor.rz.scp.css */
/* .trade-mode-btn (trade-mode-switcher.css, global) is a fixed square sized for single-glyph icon
   buttons; these carry words, so each button sizes to its label, as the Sensitivities pane's
   Ladder | Table does. */
.pane-view-switcher[b-5asgc70i5d] {
    width: fit-content;
}

.pane-view-switcher .trade-mode-btn[b-5asgc70i5d] {
    width: auto;
    height: auto;
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    font-size: var(--cpd-text-0);
    white-space: nowrap;
}
/* /Components/Analytics/XvaAnalytic.razor.rz.scp.css */
/* The xVA analytic's own body. Card/header/chevron chrome belongs to SummaryTile and the pane's to
   DetailPane; what is here is the figure look, lifted verbatim from XvaTile.razor.css so the tile
   reads exactly as it did before there was one component drawing it, plus the pane-only parts
   (mode content, breakdown).

   The figure look moved to XvaHeadline.razor.css with the markup it styles, when the headline became
   its own component so the trades list could draw the same figures above its grid: CSS isolation is
   per file, so a rule left behind here would match nothing there. The two colour classes below stay
   because this file still uses one of them, on a failed run's message. */

.val-positive[b-cro6560xeo] { color: var(--token-rate); }
.val-negative[b-cro6560xeo] { color: var(--token-position); }

.xva-state-msg[b-cro6560xeo] {
    font-size: 12px;
    color: var(--cpd-text-subtle);
}

.xva-scope-summary[b-cro6560xeo] {
    margin-top: 8px;
    font-size: 10px;
    font-family: var(--cpd-font-mono);
    color: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
}

.xva-run-btn[b-cro6560xeo] {
    margin-top: 8px;
}

.xva-progress[b-cro6560xeo] {
    margin-top: 8px;
}

.xva-mode-content[b-cro6560xeo] {
    margin-bottom: 8px;
}

/* The pane body's export cluster (PaneBody display): the profile's copy and download, at the right
   end of a row above the headline, as a table carries its own above its rows. */
.xva-pane-export[b-cro6560xeo] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--cpd-space-sm);
}
/* /Components/Analytics/XvaHeadline.razor.rz.scp.css */
/* The xVA figure look, moved here with the markup it styles when the headline became its own
   component: Blazor's CSS isolation stamps a component's scope attribute onto the markup compiled
   into its own .razor file, so these rules match nothing if they stay in XvaAnalytic.razor.css.
   Lifted verbatim from there (and, before that, from XvaTile.razor.css) so the tile reads exactly as
   it did before there was one component drawing it. */

.xva-stat-grid[b-8c5a526d9p] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* 10px by design, NOT var(--cpd-tile-gap): these are paired figures inside one readout, not
       separate cards, and 16px between them read as two lists. */
    gap: 10px;
}

/* Two 15px mono figures plus their labels stop fitting side by side once the tile is under about
   240px wide - the compact right rail (--cpd-pane-rail-w 240px, less the tile's own padding) is
   exactly there. The container is SummaryTile's root .summary-tile, which declares
   `container-type: inline-size`; unnamed, so this resolves to that nearest ancestor container
   whichever tile the body is rendered into - and a container query resolves against ancestors
   regardless of which component's stylesheet the rule came from, which is why the move is safe. */
@container (max-width: 239.98px) {
    .xva-stat-grid[b-8c5a526d9p] { grid-template-columns: 1fr; }
}

.xva-stat[b-8c5a526d9p] {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.xva-stat-label[b-8c5a526d9p] {
    font-size: 9px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
}

.xva-stat-value[b-8c5a526d9p] {
    font-family: var(--cpd-font-mono);
    font-size: 15px;
    font-weight: 600;
}

/* The "± 8" Monte Carlo standard error under each figure. 0.3 measured 2.7:1 in dark mode; 0.35 is
   the lowest rung that clears 3:1 in both themes, and is the tier the other 10px captions use. */
.xva-stat-se[b-8c5a526d9p] {
    font-family: var(--cpd-font-mono);
    font-size: 10px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
}

/* This readout is a 95% interval (1.96σ). The simulation-settings dialog states its accuracy target
   at a user-selected threshold defaulting to the same 95%, so the two agree by default - and both
   say which basis they are on, so a non-default threshold cannot be silently mistaken for this one. */
.xva-stat-se-basis[b-8c5a526d9p] {
    font-size: 0.75em;
    letter-spacing: 0.03em;
    opacity: 0.6;
}

/* The pane's headline. Six figures across on a wide pane, folding to two and then one rather than
   shrinking the mono figures below where they are legible. */
.xva-headline[b-8c5a526d9p] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 16px;
    margin-bottom: 16px;
}

/* The run cell names a count, and an uncharged FCA/FBA cell a missing curve — not money, so neither
   is a figure in the same weight as the ones beside it. */
.xva-run-value[b-8c5a526d9p] {
    font-size: 13px;
    font-weight: 500;
}

/* What the figures are a total of, while a scope run is still streaming. Same 10px caption tier as
   the ± readouts: it qualifies the figures rather than competing with them. */
.xva-headline-caption[b-8c5a526d9p] {
    margin-top: 6px;
    font-size: 10px;
    font-family: var(--cpd-font-mono);
    color: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
}
/* /Components/Assistant/AssistantConfirmCard.razor.rz.scp.css */
/* Gate B's card (docs/ux-shape.md §24). Tokens only (rules 1-3). It sits in the Assistant's reply,
   framed in the assistant colour like the reply's own edge, so it reads as the Assistant asking; its
   one primary button is gold, as every primary action is, because pressing it is the reader's commit. */
.assistant-confirm[b-kt2of0ot0h] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    border: 1px solid var(--cpd-assist);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-2);
}

.assistant-confirm-question[b-kt2of0ot0h] {
    margin: 0;
    font-weight: 600;
    color: var(--cpd-text);
}

.assistant-confirm-context[b-kt2of0ot0h],
.assistant-confirm-note[b-kt2of0ot0h] {
    margin: 0;
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-muted);
}

.assistant-confirm-items[b-kt2of0ot0h] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    margin: 0;
    padding: 0;
    list-style: none;
}

.assistant-confirm-item[b-kt2of0ot0h] {
    display: flex;
    flex-direction: column;
}

.assistant-confirm-item .assistant-confirm-context[b-kt2of0ot0h],
.assistant-confirm-item .assistant-confirm-status[b-kt2of0ot0h] {
    padding-left: var(--cpd-space-xl);
}

.assistant-confirm-status[b-kt2of0ot0h],
.assistant-confirm-outcome[b-kt2of0ot0h] {
    margin: 0;
    font-size: var(--cpd-text-1);
    color: var(--cpd-text);
}

.assistant-confirm-actions[b-kt2of0ot0h] {
    display: flex;
    gap: var(--cpd-space-sm);
    align-items: center;
}
/* /Components/Assistant/AssistantMessage.razor.rz.scp.css */
/* One transcript message (AssistantMessage.razor). Tokens only (docs/ux-shape.md rules 1-3). The
   reader's question sits right on a raised surface; the Assistant's reply sits left with the
   assistant colour as its marker. */
.assistant-message[b-s9kcapj8eo] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    font-size: var(--cpd-text-2);
    line-height: 1.5;
}

.assistant-message-text[b-s9kcapj8eo] {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* A reply is laid out in paragraphs and lists (AssistantText), so its own line breaks are not kept. */
.assistant-reply-text[b-s9kcapj8eo] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    white-space: normal;
}

.assistant-reply-text p[b-s9kcapj8eo] {
    margin: 0;
}

.assistant-reply-text ul[b-s9kcapj8eo],
.assistant-reply-text ol[b-s9kcapj8eo] {
    margin: 0;
    padding-left: var(--cpd-space-lg);
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

.assistant-reply-text code[b-s9kcapj8eo] {
    font-family: var(--cpd-font-mono);
    font-size: var(--cpd-text-1);
    padding: 0 var(--cpd-space-xs);
    border-radius: var(--cpd-radius-sm);
    background: var(--cpd-surface-3);
}

.assistant-message--reader[b-s9kcapj8eo] {
    align-self: flex-end;
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    border-radius: var(--cpd-radius-lg);
    background: var(--cpd-surface-3);
    color: var(--cpd-text);
}

.assistant-message--assistant[b-s9kcapj8eo] {
    align-self: stretch;
    padding-left: var(--cpd-space-md);
    border-left: 2px solid var(--cpd-assist);
    color: var(--cpd-text);
}

.assistant-steps[b-s9kcapj8eo] {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.assistant-step[b-s9kcapj8eo]::before {
    content: "\2192";
    margin-right: var(--cpd-space-xs);
    color: var(--cpd-assist);
}

.assistant-failure[b-s9kcapj8eo] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--cpd-space-xs);
    color: var(--cpd-text);
}

.assistant-retry[b-s9kcapj8eo] {
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    color: var(--cpd-gold);
    cursor: pointer;
}

.assistant-retry:hover[b-s9kcapj8eo],
.assistant-retry:focus-visible[b-s9kcapj8eo] {
    text-decoration: underline;
}

.assistant-stopped[b-s9kcapj8eo] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

/* The thumbs under a finished reply, and what they say once chosen: muted, beside the steps' size, so
   they read as a footnote to the answer rather than an action on the page. */
.assistant-rating[b-s9kcapj8eo] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

/* The thumbs-down's optional note: one line, then Send and Cancel. */
.assistant-note[b-s9kcapj8eo] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
}

.assistant-note-input[b-s9kcapj8eo] {
    flex: 1;
    min-width: 0;
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-1);
    color: var(--cpd-text);
    font: inherit;
    font-size: var(--cpd-text-1);
}

.assistant-note-input[b-s9kcapj8eo]::placeholder {
    color: var(--cpd-text-subtle);
}

.assistant-note-input:focus-visible[b-s9kcapj8eo] {
    outline: 2px solid var(--cpd-assist);
    outline-offset: 1px;
}

.assistant-note-send[b-s9kcapj8eo],
.assistant-note-cancel[b-s9kcapj8eo] {
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    font-size: var(--cpd-text-1);
    cursor: pointer;
}

.assistant-note-send[b-s9kcapj8eo] {
    color: var(--cpd-gold);
}

.assistant-note-cancel[b-s9kcapj8eo] {
    color: var(--cpd-text-muted);
}

.assistant-note-send:hover[b-s9kcapj8eo],
.assistant-note-send:focus-visible[b-s9kcapj8eo],
.assistant-note-cancel:hover[b-s9kcapj8eo],
.assistant-note-cancel:focus-visible[b-s9kcapj8eo] {
    text-decoration: underline;
}
/* /Components/Assistant/AssistantPanel.razor.rz.scp.css */
/* The Assistant's panel (docs/ux-shape.md §24, §18). Tokens only (rules 1-3).

   From 1024 wide (the expanded size class, docs/ux-shape.md §18) it is a third column: MainLayout
   places it in an <aside> after <main>, in the .cpd-shell flex row, so the page reflows narrower
   while the panel is open and back when it closes; PageRenderer's own container query then gives the
   page one column where two no longer fit. Below 1024 the nav is a rail or a drawer and the page has
   no room beside it, so the panel is a drawer over the page's right edge, the page keeping its width
   underneath (amended 2026-10-14: from 1366 before, which covered the page's Run button, Save bar and
   the Assistant control at 1280). Its width is --cpd-assist-panel-w either
   way, never more than the window. Above the page and the compact nav (1050), below MudBlazor's
   drawer, popovers and dialogs (1100+). As a column it is never under a dialog: a dialog's container
   stops at the panel's edge (app.css, "Assistant panel beside a dialog"), so the panel stays usable
   while a dialog is open; as a drawer a dialog still covers it. */
.assistant-panel[b-g8kaomch5l] {
    display: flex;
    flex-direction: column;
    width: var(--cpd-assist-panel-w);
    height: 100vh;
    background: var(--cpd-surface-raised);
    border-left: 1px solid var(--cpd-border);
    color: var(--cpd-text);
}

@media (max-width: 1023.98px) {
    .assistant-panel[b-g8kaomch5l] {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        width: min(var(--cpd-assist-panel-w), 100vw);
        height: auto;
        z-index: 1080;
        box-shadow: var(--cpd-shadow-card);
    }
}

.assistant-header[b-g8kaomch5l] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    padding: var(--cpd-space-md) var(--cpd-space-lg);
    border-bottom: 1px solid var(--cpd-border);
}

.assistant-heading[b-g8kaomch5l] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
}

/* The panel's marker: the assistant colour, which nothing outside the Assistant uses. */
.assistant-marker[b-g8kaomch5l] {
    flex-shrink: 0;
    inline-size: var(--cpd-space-sm);
    block-size: var(--cpd-space-sm);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-assist);
}

.assistant-title[b-g8kaomch5l] {
    flex: 1;
    margin: 0;
    font-size: var(--cpd-text-3);
    font-weight: 600;
}

.assistant-frame[b-g8kaomch5l] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--cpd-space-xs);
    margin: 0;
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.assistant-frame-page[b-g8kaomch5l] {
    color: var(--cpd-text);
    font-weight: 600;
}

.assistant-transcript[b-g8kaomch5l] {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-lg);
    padding: var(--cpd-space-lg);
}

.assistant-examples[b-g8kaomch5l] {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
}

.assistant-example[b-g8kaomch5l] {
    display: flex;
    justify-content: flex-start;
    inline-size: 100%;
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-md);
    background: transparent;
    color: var(--cpd-text);
    font: inherit;
    font-size: var(--cpd-text-2);
    text-align: start;
    cursor: pointer;
    transition: border-color var(--cpd-transition-fast);
}

.assistant-example:hover[b-g8kaomch5l],
.assistant-example:focus-visible[b-g8kaomch5l] {
    border-color: var(--cpd-assist);
}

.assistant-progress[b-g8kaomch5l] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-sm) var(--cpd-space-lg);
    border-top: 1px solid var(--cpd-border);
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

/* A pulsing dot in the assistant colour: something is happening. Still under reduced motion. */
.assistant-progress-bar[b-g8kaomch5l] {
    flex-shrink: 0;
    inline-size: var(--cpd-space-sm);
    block-size: var(--cpd-space-sm);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-assist);
    animation: assistant-progress-pulse-b-g8kaomch5l 1.2s ease-in-out infinite;
}

@keyframes assistant-progress-pulse-b-g8kaomch5l {
    50% { opacity: 0.3; }
}

@media (prefers-reduced-motion: reduce) {
    .assistant-progress-bar[b-g8kaomch5l] {
        animation: none;
    }
}

.assistant-progress-text[b-g8kaomch5l] {
    flex: 1;
}

.assistant-stop[b-g8kaomch5l] {
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-sm);
    background: transparent;
    color: var(--cpd-text);
    font: inherit;
    cursor: pointer;
}

.assistant-stop:hover[b-g8kaomch5l],
.assistant-stop:focus-visible[b-g8kaomch5l] {
    border-color: var(--cpd-text);
}

.assistant-composer[b-g8kaomch5l] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-sm) var(--cpd-space-md) var(--cpd-space-md) var(--cpd-space-lg);
    border-top: 1px solid var(--cpd-border);
}

.assistant-input[b-g8kaomch5l] {
    flex: 1;
    min-width: 0;
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-1);
    color: var(--cpd-text);
    font: inherit;
    font-size: var(--cpd-text-2);
}

.assistant-input[b-g8kaomch5l]::placeholder {
    color: var(--cpd-text-subtle);
}

.assistant-input:focus-visible[b-g8kaomch5l] {
    outline: 2px solid var(--cpd-assist);
    outline-offset: 1px;
}
/* /Components/Assistant/AssistantToggle.razor.rz.scp.css */
/* The top bar's "Assistant" control (AssistantToggle.razor). Tokens only (docs/ux-shape.md rules
   1-3). A quiet text button like the bar's other actions; while the panel is open, the assistant
   colour underlines it, the panel's marker repeated where the reader opened it. Never gold: gold is
   the page's primary action. */
.assistant-toggle[b-38skl9trk4] {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: var(--cpd-radius-sm);
    background: transparent;
    color: var(--cpd-text);
    font: inherit;
    font-size: var(--cpd-text-2);
    cursor: pointer;
}

.assistant-toggle:hover[b-38skl9trk4] {
    background: var(--cpd-surface-hover);
}

.assistant-toggle:focus-visible[b-38skl9trk4] {
    outline: 2px solid var(--cpd-assist);
    outline-offset: 1px;
}

.assistant-toggle--open[b-38skl9trk4] {
    border-bottom-color: var(--cpd-assist);
}

/* The bar's own width, as the session group's collapse (TopBarHost.razor.css): when it is cramped,
   the icon stands for the word, which stays the button's accessible name through aria-label. Wider than
   the session group's own collapse (749.98): with the panel open at 1440 the bar is about 830px, and
   the word pushed the session group into the actions (browser check, 2026-10-14). */
@container topbar (max-width: 999.98px) {
    .assistant-toggle-label[b-38skl9trk4] {
        display: none;
    }
}
/* /Components/Changes/DocumentChanges.razor.rz.scp.css */
/* The Changes pane: the list beside the selected change from 641px of pane width, stacked below
   it. A container query, because the pane's width is the page's pane column, not the viewport. */
.document-changes[b-dlsbi63fig] {
    container-type: inline-size;
}

.changes-layout[b-dlsbi63fig] {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--cpd-space-lg);
    align-items: start;
}

@container (min-width: 641px) {
    .changes-layout[b-dlsbi63fig] {
        grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    }
}

.changes-list[b-dlsbi63fig] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

.changes-row[b-dlsbi63fig] {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: var(--cpd-space-sm);
    align-items: baseline;
    width: 100%;
    padding: var(--cpd-space-sm);
    border: 1px solid transparent;
    border-radius: var(--cpd-radius-md);
    background: none;
    color: var(--cpd-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background var(--cpd-transition-fast);
}

.changes-row:hover[b-dlsbi63fig] {
    background: var(--cpd-surface-hover);
}

.changes-row:focus-visible[b-dlsbi63fig] {
    outline: 2px solid var(--cpd-focus);
    outline-offset: 1px;
}

.changes-row.selected[b-dlsbi63fig] {
    background: var(--cpd-gold-soft);
    border-color: var(--cpd-gold-border);
}

.changes-dot[b-dlsbi63fig] {
    align-self: center;
    width: var(--cpd-space-sm);
    height: var(--cpd-space-sm);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-gold);
}

.changes-row.inherited .changes-dot[b-dlsbi63fig] {
    background: var(--cpd-text-subtle);
}

.changes-row-title[b-dlsbi63fig] {
    font-size: var(--cpd-text-2);
    overflow-wrap: anywhere;
}

.changes-row-time[b-dlsbi63fig] {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.changes-row-author[b-dlsbi63fig],
.changes-snapshots[b-dlsbi63fig] {
    grid-column: 2 / -1;
}

.changes-row-author[b-dlsbi63fig] {
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.changes-snapshots[b-dlsbi63fig] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-xs);
    margin-top: var(--cpd-space-xs);
}

.changes-snapshot[b-dlsbi63fig] {
    padding: 0 var(--cpd-space-sm);
    border: 1px solid var(--cpd-gold-border);
    border-radius: var(--cpd-radius-pill);
    font-size: var(--cpd-text-0);
    color: var(--cpd-text);
}

/* "Before this workspace started": a dashed rule either side of the words. */
.changes-divider[b-dlsbi63fig] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    margin: var(--cpd-space-sm) 0;
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}

.changes-divider[b-dlsbi63fig]::before,
.changes-divider[b-dlsbi63fig]::after {
    content: "";
    flex: 1;
    border-top: 1px dashed var(--cpd-border-strong);
}

.changes-detail-header[b-dlsbi63fig] {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--cpd-space-md);
    margin-bottom: var(--cpd-space-md);
}

/* Restore this version and Snapshot here, side by side, wrapping under the title when narrow. */
.changes-detail-actions[b-dlsbi63fig] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-sm);
}

.changes-detail-title[b-dlsbi63fig] {
    font-size: var(--cpd-text-3);
}

.changes-detail-meta[b-dlsbi63fig] {
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-muted);
}

/* A value in the field table (ChangeFieldTable): compact JSON in the monospace face, cut short with
   the whole value as its tooltip. */
[b-dlsbi63fig] .change-value {
    display: inline-block;
    max-width: 40ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
    font-family: var(--cpd-font-mono);
    font-size: var(--cpd-text-1);
}
/* /Components/ClientErrorHost.razor.rz.scp.css */
/*
    The same three rules ErrorDetailsHost.razor.css carries, because scoped CSS is scoped to the
    component that declares it: the server dialog's stylesheet does not reach this one, and without
    these the stack trace renders in a two-row textarea nobody can read.

    Deliberately a subset, not a copy. The metadata list and the copy row keep the server's class
    names (so they inherit the same design tokens, which are document-global) but this dialog has no
    redacted variant, so there is nothing here for it. The custom properties - --cpd-space-*,
    --cpd-contrast-rgb, --cpd-font-mono, --cpd-radius-md - are written onto the document by the
    server chrome's theme provider and inherit into this subtree like any other CSS.
*/

.cpd-error-modal-meta[b-kzvirfregk] {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.25rem var(--cpd-space-md);
    margin-bottom: var(--cpd-space-lg);
}

.cpd-error-modal-meta dt[b-kzvirfregk] {
    font-weight: 600;
    opacity: 0.7;
}

.cpd-error-modal-meta dd[b-kzvirfregk] {
    margin: 0;
}

.cpd-error-modal-copy-row[b-kzvirfregk] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    margin-bottom: var(--cpd-space-sm);
}

.cpd-error-modal-trace[b-kzvirfregk] {
    width: 100%;
    min-height: 20rem;
    max-height: 50vh;
    resize: vertical;
    font-family: var(--cpd-font-mono);
    font-size: 0.85rem;
    white-space: pre;
    background: rgba(var(--cpd-contrast-rgb), 0.06);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.18);
    border-radius: var(--cpd-radius-md);
    color: inherit;
    padding: var(--cpd-space-md);
}
/* /Components/Environments/CatchUpPanel.razor.rz.scp.css */
/* Publish, then Finish: the primary action last, at the right edge (docs/ux-shape.md entry 4). */
.catch-up-actions[b-oshki2vi7w] {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
}

/* A side's value in the table: compact JSON in the monospace face, cut short with the whole value as
   its tooltip — as the Changes pane's field table shows one. Built in code, so it carries no scope of
   its own: reached through the panel's root. */
.catch-up-panel[b-oshki2vi7w]  .catch-up-value {
    display: inline-block;
    max-width: 24ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
    font-family: var(--cpd-font-mono);
    font-size: var(--cpd-text-1);
}

.catch-up-note[b-oshki2vi7w] {
    margin: var(--cpd-space-md) 0 0;
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-muted);
}
/* /Components/Environments/WorkspaceSettingsFields.razor.rz.scp.css */
/* Each setting is its label, its choice and its hint, stacked, with the dialog's field gap below. */
.workspace-setting[b-8uwdclljtb] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--cpd-space-xs);
    margin-bottom: var(--cpd-space-lg);
}
/* /Components/Feedback/EmptyState.razor.rz.scp.css */
.empty-state[b-wpdqjqu1x4] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-2);
}

.empty-state a[b-wpdqjqu1x4],
.empty-state-button[b-wpdqjqu1x4] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    color: var(--cpd-gold);
}

/* The button is the link's twin: an action on this page rather than a place to go, read the same. */
.empty-state-button[b-wpdqjqu1x4] {
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    cursor: pointer;
}

.empty-state a:hover[b-wpdqjqu1x4],
.empty-state a:focus-visible[b-wpdqjqu1x4],
.empty-state-button:hover[b-wpdqjqu1x4],
.empty-state-button:focus-visible[b-wpdqjqu1x4] {
    text-decoration: underline;
}
/* /Components/Feedback/SaveBar.razor.rz.scp.css */
.save-bar[b-3f84yurr4j] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
}

.save-bar-actions[b-3f84yurr4j] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--cpd-space-sm);
}

/* A dialog's bar sits bottom-right in its actions and takes the actions' full width, so the blockers
   above its buttons read left to right. */
.save-bar-dialog[b-3f84yurr4j] {
    width: 100%;
}

/* Where the WIP write stands, beside the buttons (docs/ux-shape.md §20, 2026-10-16): "Saving WIP…" and
   "WIP saved 14:02" read quietly, as secondary text. */
.save-bar-wip[b-3f84yurr4j] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-2);
    white-space: nowrap;
}

/* A WIP that is not on the server as the form stands - retrying, or changed elsewhere - in the
   attention role. */
.save-bar-wip-attention[b-3f84yurr4j] {
    color: var(--cpd-warning);
    font-size: var(--cpd-text-2);
}

.save-bar-actions[b-3f84yurr4j]  .save-bar-progress {
    margin-left: var(--cpd-space-sm);
}
/* /Components/Feedback/SaveBlockers.razor.rz.scp.css */
.save-blockers-title[b-hqa73x7iro] {
    font-weight: 600;
}

.save-blockers-list[b-hqa73x7iro] {
    margin: var(--cpd-space-xs) 0 0;
    padding-left: var(--cpd-space-lg);
}

.save-blocker-link[b-hqa73x7iro] {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    text-decoration: underline;
    cursor: pointer;
}

.save-blocker-link:focus-visible[b-hqa73x7iro] {
    outline: none;
    box-shadow: 0 0 0 3px var(--cpd-focus);
}
/* /Components/Inputs/ChangedMarker.razor.rz.scp.css */
/* The changed marker sits before a field's label (docs/ux-shape.md §20): a dot in the Attention tone's
   colour (the one .tone-attention takes in app.css), so it reads as "not committed yet". It is told
   apart from the override marker (entry 19: gold, after the label, with a reset) by its place, its
   colour and having no action. */
.changed-marker[b-h44yvulla7] {
    display: inline-block;
    flex-shrink: 0;
    inline-size: var(--cpd-space-sm);
    block-size: var(--cpd-space-sm);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-warning);
}
/* /Components/Inputs/OverrideMarker.razor.rz.scp.css */
/* The override marker sits in a field's label line, beside the label (docs/ux-shape.md entry 19).
   The dot takes the colour a trade's own override has always had (the solid "this trade" chip's
   --cpd-gold), at the size of a mark rather than a pill, so it reads as a state and not a warning. */
.override-marker[b-o7tcpvfzw4] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
}

.override-marker-dot[b-o7tcpvfzw4] {
    display: inline-block;
    inline-size: var(--cpd-space-sm);
    block-size: var(--cpd-space-sm);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-gold);
}

.override-marker-reset[b-o7tcpvfzw4] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: var(--cpd-space-xl);
    padding: 0 var(--cpd-space-xs);
    border: 0;
    border-radius: var(--cpd-radius-sm);
    background: none;
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
    line-height: 1;
    cursor: pointer;
}

.override-marker-reset:hover[b-o7tcpvfzw4] {
    color: var(--cpd-gold);
}

.override-marker-reset:focus-visible[b-o7tcpvfzw4] {
    outline: none;
    box-shadow: 0 0 0 var(--cpd-space-xs) var(--cpd-focus);
}
/* /Components/Inputs/TermInput.razor.rz.scp.css */
/* The term input (docs/ux-shape.md entry 19, 2026-10-13): what the term lands on reads in a label
   line, muted and short, so nothing sits beside the box and the field is as wide as its box. Under
   the box only where there is no label line (an outlined box, a grid cell). */
.term-input[b-madfggbf9a] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    min-width: 0;
}

/* In a label line the box is as wide as that line needs (the label, the override marker, the (?) and
   a yyyy-MM-dd date with its marks; the owner, 2026-10-13: "just enough for the labels"), whatever a
   longer line says: that one is cut, with its full text in its title. Named with Mud's own class,
   which a scoped rule must out-specify. */
.term-input[b-madfggbf9a]  .mud-input-control.term-input-box {
    flex: 0 0 auto;
    width: 12rem;
}

/* With no label line (a grid cell, an outlined box) the box is as wide as a term: a tenor or a
   yyyy-MM-dd date is at most ten characters, plus an outlined control's padding (the valuation bar's)
   and the calendar button. */
.term-input.hint-below[b-madfggbf9a]  .mud-input-control.term-input-box {
    width: calc(13ch + 2 * var(--cpd-space-md) + 2rem);
}

.term-input-head[b-madfggbf9a] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    min-width: 0;
}

.term-input-label[b-madfggbf9a] {
    font-size: var(--cpd-text-1);
    font-weight: 600;
    white-space: nowrap;
}

/* The line under the box (no label line to hold it): one short line, never wider than the box. */
.term-input-foot[b-madfggbf9a] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    min-width: 0;
    contain: inline-size;
}

/* The line: the text and its marks together, taking what the label line leaves and never widening
   the field (contain keeps its length out of the field's own width). */
.term-input-line[b-madfggbf9a] {
    display: inline-flex;
    flex: 1 1 0;
    align-items: center;
    gap: var(--cpd-space-xs);
    min-width: 0;
    contain: inline-size;
}

/* The short line itself: muted, cut with an ellipsis when it must be (its full text is its title). */
.term-input-derived[b-madfggbf9a] {
    min-width: 0;
    flex: 0 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--cpd-text-0);
    font-variant-numeric: tabular-nums;
    font-weight: 400;
    color: var(--cpd-text-muted);
}

.term-input-derived.warn[b-madfggbf9a] {
    color: var(--cpd-warning);
}

.term-input-derived.error[b-madfggbf9a] {
    color: var(--cpd-error);
}

/* ↷ (the roll moved the date) and the link (a tenor kept against its anchor): marks, titled. */
.term-input-mark[b-madfggbf9a] {
    display: inline-flex;
    flex: none;
    align-items: center;
    color: var(--cpd-text-muted);
}

.term-input-mark.rolled[b-madfggbf9a] {
    color: var(--cpd-gold);
}

.term-input-mark[b-madfggbf9a]  .mud-icon-root,
.term-input-help[b-madfggbf9a]  .mud-icon-root {
    font-size: var(--cpd-text-1);
}

/* The (?) is centred on its label line by flex alone. Mud's tooltip wraps it in an inline-block,
   which would sit the button on a text baseline and drop it below the label's centre in some
   browsers; as a centring flex box it has no baseline. */
.term-input-help-anchor[b-madfggbf9a] {
    display: inline-flex;
    flex: none;
    align-items: center;
}

.term-input-help-anchor[b-madfggbf9a]  .mud-tooltip-root {
    display: inline-flex;
    align-items: center;
}

.term-input-help[b-madfggbf9a] {
    display: inline-flex;
    align-items: center;
    padding: 0;
    border: 0;
    background: none;
    color: var(--cpd-text-muted);
    cursor: pointer;
}

.term-input-help[aria-expanded="true"][b-madfggbf9a] {
    color: var(--cpd-gold);
}

.term-input-help:focus-visible[b-madfggbf9a],
.term-input-rule:focus-visible[b-madfggbf9a],
.term-chip:focus-visible[b-madfggbf9a],
.term-panel-action:focus-visible[b-madfggbf9a] {
    outline: none;
    box-shadow: 0 0 0 3px var(--cpd-focus);
}

/* The (?) panel. */
.term-panel[b-madfggbf9a],
.term-panel-lines[b-madfggbf9a] {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    max-width: 22rem;
    font-size: var(--cpd-text-0);
    line-height: 1.45;
}

.term-panel[b-madfggbf9a] {
    padding: var(--cpd-space-sm) var(--cpd-space-md);
}

.term-panel-line.quiet[b-madfggbf9a] {
    color: var(--cpd-text-muted);
}

.term-panel-line.warn[b-madfggbf9a] {
    color: var(--cpd-warning);
}

.term-panel-line.error[b-madfggbf9a] {
    color: var(--cpd-error);
}

/* The roll, where a convention owns it: a text button that opens the place that edits it (the leg's
   Adjust drawer), never a second control for the rule. */
.term-input-rule[b-madfggbf9a] {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.term-panel-action[b-madfggbf9a] {
    align-self: flex-start;
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-sm);
    background: var(--cpd-surface-2);
    color: inherit;
    font: inherit;
    cursor: pointer;
}

/* The hover tooltip's last line: what can be typed, set off from what the term lands on. The
   tooltip's own colours stand; only the rule above it is drawn, in the text's own colour. */
.term-tooltip-syntax[b-madfggbf9a] {
    padding-top: var(--cpd-space-xs);
    border-top: 1px solid currentColor;
}

.term-panel-syntax[b-madfggbf9a] {
    padding-top: var(--cpd-space-xs);
    border-top: 1px solid var(--cpd-border);
    color: var(--cpd-text-muted);
}

/* The calendar: the usual tenors as chips above the month, a legend and a note under it. */
.term-calendar[b-madfggbf9a] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-sm);
    max-width: 20rem;
}

.term-calendar-chips[b-madfggbf9a] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-xs);
}

.term-chip[b-madfggbf9a] {
    padding: 0 var(--cpd-space-sm);
    min-height: 1.5rem;
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-pill);
    background: none;
    color: inherit;
    font-family: var(--cpd-font-mono);
    font-size: var(--cpd-text-0);
    cursor: pointer;
}

.term-chip.active[b-madfggbf9a] {
    border-color: var(--cpd-gold);
    background: var(--cpd-gold);
    color: var(--cpd-dark);
}

.term-calendar-legend[b-madfggbf9a] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-md);
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}

.term-calendar-legend > span[b-madfggbf9a] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
}

.term-swatch[b-madfggbf9a] {
    display: inline-block;
    width: 0.75rem;
    height: 0.75rem;
    border-radius: var(--cpd-radius-sm);
}

.term-swatch.lands[b-madfggbf9a] {
    background: var(--cpd-gold);
}

.term-swatch.before[b-madfggbf9a] {
    border: 1.5px dashed var(--cpd-gold);
}

.term-swatch.off[b-madfggbf9a] {
    background: var(--cpd-surface-3);
}

.term-calendar-note[b-madfggbf9a] {
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}
/* /Components/JsonComponent/Deals/CashFlowsInput.razor.rz.scp.css */
/* A deal leg's table: it scrolls sideways inside this box when the page is too narrow for every
   column, never the page (docs/ux-shape.md rule 9), and each cell is as wide as what it holds — a
   yyyy-MM-dd date or a term, a notional such as −10,000,000.00 — in ch, so the widths
   follow the font rather than a pixel literal. The same rules are in CouponsInput.razor.css; keep the two in step. */
.deal-leg[b-eiq0weu1i4] {
    width: 100%;
    min-width: 0;
    overflow-x: auto;
}

.deal-leg[b-eiq0weu1i4]  .deal-date {
    min-width: 17ch;
}

.deal-leg[b-eiq0weu1i4]  .deal-date input {
    min-width: 11ch;
}

.deal-leg[b-eiq0weu1i4]  input.form-input.deal-number {
    width: 16ch;
    min-width: 16ch;
    text-align: right;
}
/* /Components/JsonComponent/Deals/CouponsInput.razor.rz.scp.css */
/* A deal leg's table: it scrolls sideways inside this box when the page is too narrow for every
   column, never the page (docs/ux-shape.md rule 9), and each cell is as wide as what it holds — a
   yyyy-MM-dd date or a term, a notional such as −10,000,000.00 — in ch, so the widths
   follow the font rather than a pixel literal. The same rules are in CashFlowsInput.razor.css; keep the two in step. */
.deal-leg[b-1x06w2pc35] {
    width: 100%;
    min-width: 0;
    overflow-x: auto;
}

.deal-leg[b-1x06w2pc35]  .deal-date {
    min-width: 17ch;
}

.deal-leg[b-1x06w2pc35]  .deal-date input {
    min-width: 11ch;
}

.deal-leg[b-1x06w2pc35]  input.form-input.deal-number {
    width: 16ch;
    min-width: 16ch;
    text-align: right;
}
/* /Components/JsonComponent/SingletonKeyInput.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). */
.singleton-key-note[b-3gvdkfagjj] {
    margin: 0;
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}
/* /Components/JsonComponent/TradeInput.razor.rz.scp.css */
/* The term sheet's Schedule disclosure reads as the legs' Adjust drawers do (LegColumn.razor.css):
   a quiet toggle above what it shows. */
.term-sheet-schedule > summary[b-qfendnt9zy] {
    cursor: pointer;
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-muted);
}

.term-sheet-schedule[open] > summary[b-qfendnt9zy] {
    margin-bottom: var(--cpd-space-sm);
}
/* /Components/JsonComponent/Trades/LegColumn.razor.rz.scp.css */
/* The Adjust drawer's toggle reads as a quiet disclosure, as the app's other disclosures do
   (CurveLeaf's advanced settings): the convention's rules are rarely the question. Open, the drawer
   is a section of its own — an inset panel — so its rules do not read as more of the leg's inputs,
   and its text is at the body scale rather than the small label size a rule's depth would give it
   (2026-10-12 user test). Its fields flow inside it like any section's. */
.leg-adjust > summary[b-xx6p5lm9yn] {
    cursor: pointer;
    font-size: var(--cpd-text-2);
    color: var(--cpd-text-muted);
}

.leg-adjust[open][b-xx6p5lm9yn] {
    padding: var(--cpd-space-sm) var(--cpd-space-md) var(--cpd-space-md);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-1);
}

.leg-adjust[open] > summary[b-xx6p5lm9yn] {
    margin-bottom: var(--cpd-space-sm);
    color: var(--cpd-text);
}

.leg-adjust[b-xx6p5lm9yn]  .json-field,
.leg-adjust[b-xx6p5lm9yn]  .json-section {
    --json-label-size: var(--cpd-text-1);
}

.leg-adjust[b-xx6p5lm9yn]  .derived-value,
.leg-adjust[b-xx6p5lm9yn]  .form-input {
    font-size: var(--cpd-text-2);
}

/* A rule's grammar text ("t + 1 bd (USD & ZAR)") is the convention editor's shorthand, not a
   trader's: the drawer shows a rule by its fields alone. */
.leg-adjust[b-xx6p5lm9yn]  .json-section-summary {
    display: none;
}
/* /Components/Layout/Breadcrumbs.razor.rz.scp.css */
.breadcrumbs ol[b-fdc59oyn0c] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    list-style: none;
    margin: 0 0 var(--cpd-space-xs);
    padding: 0;
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-muted);
}

.breadcrumbs li + li[b-fdc59oyn0c]::before {
    content: "›";
    margin: 0 var(--cpd-space-xs);
    color: var(--cpd-text-subtle);
}

.breadcrumbs a[b-fdc59oyn0c] {
    color: inherit;
    text-decoration: none;
}

.breadcrumbs a:hover[b-fdc59oyn0c],
.breadcrumbs a:focus-visible[b-fdc59oyn0c] {
    color: var(--cpd-gold);
    text-decoration: underline;
}

.breadcrumbs li[aria-current="page"][b-fdc59oyn0c] {
    color: var(--cpd-text);
}
/* /Components/Layout/DisplayMenu.razor.rz.scp.css */
/* The Display menu (DisplayMenu.razor). Tokens only (docs/ux-shape.md rules 1-3). The panel is
   rendered by the shell's popover provider but authored here, so these scoped rules still reach it;
   the MudIcon inside each choice is a child component, hence ::deep for it. */
.display-menu[b-uhuuahwctf] {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
}

/* Three groups, each a quiet heading over a row of choices - the run control's dropdown spacing. */
.display-menu-body[b-uhuuahwctf] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-md);
    padding: var(--cpd-space-md) var(--cpd-space-lg);
}

.display-menu-group[b-uhuuahwctf] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

/* The run control's popover title, for the same job: it introduces the choices, it is not one. */
.display-menu-heading[b-uhuuahwctf] {
    font-size: var(--cpd-text-0);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--cpd-text-muted);
}

.display-menu-options[b-uhuuahwctf] {
    display: flex;
    gap: var(--cpd-space-xs);
}

/* A choice is a plain toggle button in the top-bar selects' outline (.topbar-select-field), so the
   panel reads as part of the bar it opened from. */
.display-menu-option[b-uhuuahwctf] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-sm);
    background: transparent;
    color: var(--cpd-text);
    font: inherit;
    font-size: var(--cpd-text-2);
    white-space: nowrap;
    cursor: pointer;
}

.display-menu-option:hover[b-uhuuahwctf] {
    border-color: var(--cpd-text);
}

.display-menu-option:focus-visible[b-uhuuahwctf] {
    outline: none;
    border-color: var(--cpd-gold);
    box-shadow: 0 0 0 3px var(--cpd-gold-ring);
}

/* The current choice: the nav's selected look (gold on gold-soft), plus the check mark and
   aria-pressed in the markup, so it is never colour alone. */
.display-menu-option--selected[b-uhuuahwctf] {
    border-color: var(--cpd-gold);
    background: var(--cpd-gold-soft);
    color: var(--cpd-gold);
}

/* Hidden, not removed: the check keeps its width, so choosing does not shift the labels. */
.display-menu-option[b-uhuuahwctf]  .display-menu-check--off {
    visibility: hidden;
}
/* /Components/Layout/EnvironmentBand.razor.rz.scp.css */
/* A row of its own between the top bar and the page (MainLayout's flex column), gutters as the top
   bar's, never squeezed by the page below it. */
.environment-band[b-yz9y0ivn99] {
    flex-shrink: 0;
    padding: var(--cpd-space-sm) var(--cpd-space-xl);
}

.environment-band-content[b-yz9y0ivn99] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--cpd-space-sm) var(--cpd-space-md);
}

/* Catch up, then Delete, with more room between them than a pair of buttons usually has: the
   destructive one is not to be hit for the other. CatchUpBand's own actions take the same form. */
.environment-band-actions[b-yz9y0ivn99],
.environment-band-content[b-yz9y0ivn99]  .environment-band-actions {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-lg);
}
/* /Components/Layout/EnvironmentBar.razor.rz.scp.css */
/* The workspace picker: the top bar's select look (.topbar-select-field in app.css, chevron and
   warning role included) on a button holding a glyph and a name. Tokens only (docs/ux-shape.md
   rules 1-3). The panel is rendered by the shell's popover provider but authored here, so these
   scoped rules still reach it. */
.environment-bar[b-mrabmyxdi5] {
    position: relative;
    display: flex;
    align-items: center;
    min-width: 0;
}

/* Fills the slot MainLayout gives the bar (.cpd-shell-topbar .environment-bar, a fixed width like the date's
   and the currency's) and never more: a long name gives way with an ellipsis, so the picker cannot
   run over the date beside it. */
.environment-picker[b-mrabmyxdi5] {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: var(--cpd-space-sm);
    width: 100%;
    min-width: 0;
    overflow: hidden;
    text-align: start;
}

.environment-picker-name[b-mrabmyxdi5] {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The glyph: a ringed letter, in the colour of what it names. The letter says it too, so the colour
   is never alone. */
.environment-glyph[b-mrabmyxdi5] {
    display: inline-grid;
    flex: none;
    place-items: center;
    width: var(--cpd-space-xl);
    height: var(--cpd-space-xl);
    border: 1px solid currentColor;
    border-radius: var(--cpd-radius-pill);
    font-size: var(--cpd-text-0);
    font-weight: 700;
    line-height: 1;
}

.environment-glyph--production[b-mrabmyxdi5] {
    color: var(--cpd-success);
}

.environment-glyph--workspace[b-mrabmyxdi5] {
    color: var(--cpd-gold);
}

.environment-glyph--snapshot[b-mrabmyxdi5] {
    color: var(--cpd-accent);
}

/* The panel: search, the groups (scrolling on their own), then the footer. As wide as a phone
   allows, with the page gutter either side. */
.environment-panel[b-mrabmyxdi5] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    width: min(26rem, calc(100vw - 2 * var(--cpd-space-lg)));
    padding: var(--cpd-space-md);
}

.environment-groups[b-mrabmyxdi5] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-md);
    max-height: min(60vh, 28rem);
    overflow-y: auto;
}

.environment-group[b-mrabmyxdi5] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

.environment-group-title[b-mrabmyxdi5] {
    font-size: var(--cpd-text-0);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--cpd-text-muted);
}

/* A list row: glyph at the row's left edge, its words beside it. justify-content is stated because
   MudBlazor's global button rule centres a button's content. */
.environment-option[b-mrabmyxdi5] {
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--cpd-space-sm);
    width: 100%;
    padding: var(--cpd-space-sm);
    border: 1px solid transparent;
    border-radius: var(--cpd-radius-md);
    background: transparent;
    color: var(--cpd-text);
    font: inherit;
    text-align: start;
    cursor: pointer;
}

.environment-option:hover[b-mrabmyxdi5] {
    background: var(--cpd-surface-hover);
}

.environment-option:focus-visible[b-mrabmyxdi5] {
    outline: 2px solid var(--cpd-focus);
    outline-offset: 1px;
}

.environment-option--here[b-mrabmyxdi5] {
    background: var(--cpd-gold-soft);
    border-color: var(--cpd-gold-border);
}

.environment-option-text[b-mrabmyxdi5] {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--cpd-space-xs);
    min-width: 0;
}

.environment-option-name[b-mrabmyxdi5] {
    font-size: var(--cpd-text-2);
    font-weight: 600;
    overflow-wrap: anywhere;
}

.environment-option-meta[b-mrabmyxdi5] {
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
    overflow-wrap: anywhere;
}

.environment-pills[b-mrabmyxdi5] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-xs);
}

.environment-pill[b-mrabmyxdi5] {
    padding: 0 var(--cpd-space-sm);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-pill);
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}

/* A workspace about to be deleted: ToneMapping's attention class, stated here because the page
   renderer's ::deep tone rules do not reach the top bar. The words say it too. */
.environment-pill.tone-attention[b-mrabmyxdi5] {
    border-color: var(--cpd-warning);
    color: var(--cpd-warning);
}

.environment-panel-footer[b-mrabmyxdi5] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
    padding-top: var(--cpd-space-sm);
    border-top: 1px solid var(--cpd-border);
}

/* Manage sits at the far end, away from the two actions. */
.environment-panel-footer[b-mrabmyxdi5]  .environment-manage {
    margin-inline-start: auto;
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* The shell's geometry - the .cpd-shell row, the rail, the top bar's grid, the content area and its
   gutters - is app.css's ("Shell geometry"), shared with App.razor's boot skeleton. */

/* The Assistant's column (docs/ux-shape.md §24): after <main> in the .cpd-shell row, as wide as what
   the panel draws into it - nothing while the panel is closed, --cpd-assist-panel-w while it is open
   from 1024 up, when <main> (flex: 1) gives way and the page reflows. Below 1024 the panel is a fixed
   drawer, out of the row, so the column takes no width (AssistantPanel.razor.css). */
.assistant-column[b-8mn00kelc1] {
    flex-shrink: 0;
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
.brand-bar[b-n1ncd9fj8m] {
    height: 3.5rem;
    display: flex;
    align-items: center;
    background: var(--cpd-surface-0);
    padding: 0 var(--cpd-space-lg);
    border-bottom: 1px solid var(--cpd-border-subtle);
}
.navbar-brand[b-n1ncd9fj8m] {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--cpd-text);
}
.logo-accent[b-n1ncd9fj8m] { color: var(--cpd-gold); }
/* /Components/Layout/RunControlBar.razor.rz.scp.css */
/* The run control as one split button, 40px tall like the bar's other controls: Run on the left, the
   chevron that opens the dropdown on the right, joined with no gap. Tokens only (docs/ux-shape.md
   rules 1-3). The Mud classes are named beside ours so these rules outrank MudBlazor's own. */
.run-control-bar[b-iwnyzrxl63] {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
}

.run-control-split[b-iwnyzrxl63] {
    position: relative;
    display: inline-flex;
    align-items: stretch;
}

/* The disabled button takes no pointer events; the wrapper is what shows its title. */
.run-control-run[b-iwnyzrxl63] {
    display: inline-flex;
}

.run-control-split[b-iwnyzrxl63]  .mud-button-root.run-control-main,
.run-control-split[b-iwnyzrxl63]  .mud-button-root.run-control-menu {
    height: 40px;
    box-shadow: none;
}

.run-control-split[b-iwnyzrxl63]  .mud-button-root.run-control-main {
    border-start-end-radius: 0;
    border-end-end-radius: 0;
    padding-inline: var(--cpd-space-md);
}

/* The dot, the word and the count sit inside Mud's label span, so the spacing goes there. */
.run-control-split[b-iwnyzrxl63]  .run-control-main .mud-button-label {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-sm);
}

/* The chevron half: no minimum width and a hairline between the halves. */
.run-control-split[b-iwnyzrxl63]  .mud-button-root.run-control-menu {
    min-width: 0;
    padding-inline: var(--cpd-space-xs);
    border-start-start-radius: 0;
    border-end-start-radius: 0;
    border-inline-start: 1px solid rgba(var(--cpd-dark-rgb), 0.35);
}

/* Run that cannot be pressed keeps the gold, dimmed, rather than Mud's grey: the control does not
   change shape or colour family when a mode change makes Run current. !important because MudBlazor's
   own disabled rules (.mud-button-root:disabled, .mud-button-filled:disabled) set both with it. */
.run-control-split[b-iwnyzrxl63]  .mud-button-root.run-control-main.mud-button-filled:disabled,
.run-control-split[b-iwnyzrxl63]  .mud-button-root.run-control-menu.mud-button-filled:disabled {
    background-color: var(--cpd-gold) !important;
    color: var(--cpd-dark) !important;
    opacity: 0.55;
}

.run-control-split[b-iwnyzrxl63]  .run-control-chevron {
    transition: transform 0.15s;
}

.run-control-split[b-iwnyzrxl63]  .run-control-chevron--open {
    transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
    .run-control-split[b-iwnyzrxl63]  .run-control-chevron {
        transition: none;
    }
}

.run-control-split[b-iwnyzrxl63]  .run-control-spinner {
    width: var(--cpd-space-md);
    height: var(--cpd-space-md);
    color: currentColor;
}

/* The status dot: hollow before anything has run, the warning role when inputs changed, the error
   role when a run failed at these inputs, the success role when current — shape as well as colour, and the sentence in Run's tooltip and the hidden
   caption (rule 13). Ringed in the button's own ink so a filled dot reads on the gold. */
.run-control-dot[b-iwnyzrxl63] {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.run-control-dot--never[b-iwnyzrxl63] {
    border: 1.5px solid currentColor;
}

.run-control-dot--stale[b-iwnyzrxl63] {
    background: var(--cpd-warning);
    box-shadow: 0 0 0 1.5px currentColor;
}

.run-control-dot--failed[b-iwnyzrxl63] {
    background: var(--cpd-error);
    box-shadow: 0 0 0 1.5px currentColor;
}

.run-control-dot--current[b-iwnyzrxl63] {
    background: var(--cpd-success);
    box-shadow: 0 0 0 1.5px currentColor;
}

.run-control-dot--pending[b-iwnyzrxl63] {
    background: var(--cpd-gold);
}

/* How many analytics Run computes, as a small pill in the button's own ink. */
.run-control-count[b-iwnyzrxl63] {
    display: inline-grid;
    place-items: center;
    min-width: 18px;
    height: 18px;
    padding-inline: var(--cpd-space-xs);
    border-radius: var(--cpd-radius-pill);
    background: color-mix(in srgb, currentColor 18%, transparent);
    font-size: var(--cpd-text-0);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* The status sentence the dot stands for, in the flow for assistive technology only. */
.run-control-caption[b-iwnyzrxl63] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* The dropdown: a title, then one row per analytic, its label then its segmented mode choice,
   aligned in two columns so the choices line up. Rendered by the shell's popover provider, but
   authored here, so these scoped rules still reach it. */
.run-control-popover-body[b-iwnyzrxl63] {
    display: grid;
    grid-template-columns: auto auto;
    align-items: center;
    gap: var(--cpd-space-sm) var(--cpd-space-lg);
    padding: var(--cpd-space-md) var(--cpd-space-lg);
}

.run-control-popover-title[b-iwnyzrxl63] {
    grid-column: 1 / -1;
    font-size: var(--cpd-text-0);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--cpd-text-muted);
}

.run-control-mode-row[b-iwnyzrxl63] {
    display: contents;
}

.run-control-mode-label[b-iwnyzrxl63] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    font-size: var(--cpd-text-2);
    color: var(--cpd-text);
    white-space: nowrap;
}

.run-control-mode-label--all[b-iwnyzrxl63] {
    font-weight: 600;
}

/* Divides "All" from the analytics it sets. */
.run-control-rule[b-iwnyzrxl63] {
    grid-column: 1 / -1;
    margin: 0;
    border: 0;
    border-top: 1px solid var(--cpd-border);
}

.run-control-mode-label--off[b-iwnyzrxl63] {
    color: var(--cpd-text-subtle);
}
/* /Components/Layout/SiteFooter.razor.rz.scp.css */
.site-footer[b-wts74y6cvs] {
    border-top: 1px solid var(--cpd-border);
    background: var(--cpd-surface-0);
    padding: var(--cpd-space-lg) var(--cpd-space-2xl);
}

.site-footer-inner[b-wts74y6cvs] {
    max-width: 1200px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--cpd-space-lg);
    flex-wrap: wrap;
}

.site-footer-copy[b-wts74y6cvs] {
    color: var(--cpd-text-muted);
    font-size: 0.8125rem;
}

@media (max-width: 640.98px) {
    .site-footer[b-wts74y6cvs] { padding: var(--cpd-space-lg); }
    .site-footer-inner[b-wts74y6cvs] { justify-content: center; text-align: center; }
}

/* Compact: in the app shell the footer is chrome, not a destination. Horizontal padding
   matches the top bar and the content (app.css, "Shell geometry") so the links line up with the content
   above, and the centred max-width is dropped because app content is left-aligned rather
   than a centred document column. */
.site-footer-compact[b-wts74y6cvs] {
    padding: var(--cpd-space-sm) var(--cpd-space-xl) var(--cpd-space-sm) var(--cpd-space-2xl);
}

.site-footer-compact .site-footer-inner[b-wts74y6cvs] {
    max-width: none;
    margin: 0;
}
/* /Components/Layout/TopBarHost.razor.rz.scp.css */
/* Inside the top bar's two groups (TopBarHost.razor). Where the groups sit on the bar - the session
   group centred, the actions at the right - is app.css's ("Shell geometry"), which owns the bar's grid.
   The controls are child components, hence ::deep. Tokens only (docs/ux-shape.md rules 1-3); widths
   change at the listed breakpoints (rule 10), and where the session group collapses to icons, at
   the bar's own width (a container query on .cpd-shell-topbar, below). Keep app.css's .cpd-skeleton-* blocks at the same widths, so the
   skeleton is not a layout shift. */
.topbar-session[b-ziwjnc1myk],
.topbar-actions[b-ziwjnc1myk] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-md);
    min-width: 0;
}

/* Wide enough for a short environment name in bold. */
.topbar-session[b-ziwjnc1myk]  .environment-bar {
    flex-shrink: 0;
    width: 140px;
}

.topbar-session[b-ziwjnc1myk]  .valuation-date-bar {
    flex-shrink: 0;
    width: 160px;
}

/* Narrower than the date beside it: the widest option is three characters, where a date is ten. The
   floor is the floating label, not the value: at 110px "Reporting currency" wrapped onto two lines
   over the value and clipped it (browser pass, 2026-09-28). */
.topbar-session[b-ziwjnc1myk]  .reporting-currency-bar {
    flex-shrink: 0;
    width: 128px;
}

.topbar-actions[b-ziwjnc1myk]  .notification-bell-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    padding: 0;
    border: none;
    background: transparent;
    line-height: 1;
}

.topbar-actions[b-ziwjnc1myk]  .notification-bell-btn .bi {
    font-size: var(--cpd-text-4);
    line-height: 1;
}

/* Below 1024 the session group compacts: the date and currency narrow, and the environment picker
   becomes an icon and the environment's name - its "Environment" label is visually hidden (the
   select keeps it as aria-label) and the icon stands in for it. */
@media (max-width: 1023.98px) {
    .topbar-session[b-ziwjnc1myk]  .environment-bar {
        width: auto;
        gap: var(--cpd-space-xs);
    }

    .topbar-session[b-ziwjnc1myk]  .environment-bar .topbar-select-field {
        width: auto;
    }

    .topbar-session[b-ziwjnc1myk]  .environment-bar .topbar-select-label {
        width: 1px;
        height: 1px;
        padding: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    /* Material's account_tree, the nav's icon for environments, drawn as a mask so it takes the
       text colour: no colour in the image, and no element the component would have to render. */
    .topbar-session[b-ziwjnc1myk]  .environment-bar::before {
        content: "";
        flex: none;
        inline-size: var(--cpd-space-lg);
        block-size: var(--cpd-space-lg);
        background-color: currentColor;
        color: var(--cpd-text-muted);
        -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M22 11V3h-7v3H9V3H2v8h7V8h2v10h4v3h7v-8h-7v3h-2V8h2v3z'/%3E%3C/svg%3E") center / contain no-repeat;
        mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M22 11V3h-7v3H9V3H2v8h7V8h2v10h4v3h7v-8h-7v3h-2V8h2v3z'/%3E%3C/svg%3E") center / contain no-repeat;
    }

    /* Away from production the picker carries the warning role; the icon follows it. */
    .topbar-session[b-ziwjnc1myk]  .environment-bar:has(.topbar-select-field--elsewhere)::before {
        color: var(--cpd-warning);
    }

    .topbar-session[b-ziwjnc1myk]  .valuation-date-bar {
        width: 144px;
    }

    /* Under the label's own floor (above), so the label ellipsises rather than running past the
       field's border. */
    .topbar-session[b-ziwjnc1myk]  .reporting-currency-bar {
        width: 112px;
    }

    .topbar-session[b-ziwjnc1myk]  .reporting-currency-bar .topbar-select-label {
        max-inline-size: calc(100% - var(--cpd-space-lg));
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

/* Where the one-row bar is too narrow for the session group (layout pass, 2026-10-09: it overflowed
   between 641 and about 700px of window with the compact rail), the environment, the date and the
   currency each become an icon in their outlined box, and Run stays as it is. Each is still the
   same control, only with its text made transparent: clicking the icon opens the same picker, the
   label stays in the accessibility tree (visually hidden, not removed), and the control's title -
   the environment's sentence, "Valuation date: 2026-10-09", "Reporting currency: ZAR" - is the
   tooltip that says what the icon stands for. The icons are masks drawn in the text colour over
   the control, which lets clicks through to it.

   A container query on the bar (app.css names .cpd-shell-topbar "topbar"), not a window width
   (docs/ux-shape.md rule 10): what decides is the bar's own width, so an expanded sidebar counts
   too. The bounds are the bar's content width at the overflow - a 700px window less the 56px rail
   and the bar's 56px of padding is 588px, rounded up to 600 - and 150px more when the environment
   picker is there (its icon, its name and a gap), so the picker's presence moves the bound. The
   picker renders first in the group, so "after an environment picker" is the ~ sibling selector.
   Phones are left out (the @media): there the group has a row of its own and wraps instead.
   app.css's .cpd-skeleton-* blocks follow the narrower bound (the skeleton has no environment). */
@media (min-width: 641px) {
    @container topbar (max-width: 749.98px) {
        .topbar-session[b-ziwjnc1myk]  .environment-bar,
        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar,
        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .reporting-currency-bar {
            position: relative;
            flex-shrink: 0;
            width: calc(var(--cpd-space-2xl) + var(--cpd-space-sm));
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar::before,
        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar::before,
        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .reporting-currency-bar::before {
            content: "";
            position: absolute;
            inset: 0;
            z-index: 1;
            margin: auto;
            inline-size: calc(var(--cpd-space-lg) + var(--cpd-space-xs));
            block-size: calc(var(--cpd-space-lg) + var(--cpd-space-xs));
            background-color: currentColor;
            color: var(--cpd-text-muted);
            pointer-events: none;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar::before {
            -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M22 11V3h-7v3H9V3H2v8h7V8h2v10h4v3h7v-8h-7v3h-2V8h2v3z'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M22 11V3h-7v3H9V3H2v8h7V8h2v10h4v3h7v-8h-7v3h-2V8h2v3z'/%3E%3C/svg%3E") center / contain no-repeat;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar:has(.topbar-select-field--elsewhere)::before {
            color: var(--cpd-warning);
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar::before {
            -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V8h16v13z'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V8h16v13z'/%3E%3C/svg%3E") center / contain no-repeat;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .reporting-currency-bar::before {
            -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 14V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zm-9-1c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm13-6v11c0 1.1-.9 2-2 2H4v-2h17V7h2z'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 14V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zm-9-1c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm13-6v11c0 1.1-.9 2-2 2H4v-2h17V7h2z'/%3E%3C/svg%3E") center / contain no-repeat;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar .topbar-select-label,
        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .reporting-currency-bar .topbar-select-label,
        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar .mud-input-label {
            width: 1px;
            height: 1px;
            padding: 0;
            overflow: hidden;
            clip-path: inset(50%);
            white-space: nowrap;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar .topbar-select-field,
        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .reporting-currency-bar .topbar-select-field {
            width: 100%;
            padding: 0;
            color: transparent;
            background-image: none;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar .mud-input-control {
            min-inline-size: 0;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar .mud-input {
            padding-inline: 0;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar .mud-input-slot {
            padding-inline: 0;
            color: transparent;
            caret-color: transparent;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar .mud-input-slot::placeholder {
            color: transparent;
        }

        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar .mud-input-adornment,
        .topbar-session[b-ziwjnc1myk]  .environment-bar ~ .valuation-date-bar .mud-input-outlined-border legend {
            display: none;
        }
    }

    @container topbar (max-width: 599.98px) {
        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar,
        .topbar-session[b-ziwjnc1myk]  .reporting-currency-bar {
            position: relative;
            flex-shrink: 0;
            width: calc(var(--cpd-space-2xl) + var(--cpd-space-sm));
        }

        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar::before,
        .topbar-session[b-ziwjnc1myk]  .reporting-currency-bar::before {
            content: "";
            position: absolute;
            inset: 0;
            z-index: 1;
            margin: auto;
            inline-size: calc(var(--cpd-space-lg) + var(--cpd-space-xs));
            block-size: calc(var(--cpd-space-lg) + var(--cpd-space-xs));
            background-color: currentColor;
            color: var(--cpd-text-muted);
            pointer-events: none;
        }

        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar::before {
            -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V8h16v13z'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V8h16v13z'/%3E%3C/svg%3E") center / contain no-repeat;
        }

        .topbar-session[b-ziwjnc1myk]  .reporting-currency-bar::before {
            -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 14V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zm-9-1c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm13-6v11c0 1.1-.9 2-2 2H4v-2h17V7h2z'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 14V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zm-9-1c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm13-6v11c0 1.1-.9 2-2 2H4v-2h17V7h2z'/%3E%3C/svg%3E") center / contain no-repeat;
        }

        .topbar-session[b-ziwjnc1myk]  .reporting-currency-bar .topbar-select-label,
        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar .mud-input-label {
            width: 1px;
            height: 1px;
            padding: 0;
            overflow: hidden;
            clip-path: inset(50%);
            white-space: nowrap;
        }

        .topbar-session[b-ziwjnc1myk]  .reporting-currency-bar .topbar-select-field {
            width: 100%;
            padding: 0;
            color: transparent;
            background-image: none;
        }

        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar .mud-input-control {
            min-inline-size: 0;
        }

        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar .mud-input {
            padding-inline: 0;
        }

        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar .mud-input-slot {
            padding-inline: 0;
            color: transparent;
            caret-color: transparent;
        }

        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar .mud-input-slot::placeholder {
            color: transparent;
        }

        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar .mud-input-adornment,
        .topbar-session[b-ziwjnc1myk]  .valuation-date-bar .mud-input-outlined-border legend {
            display: none;
        }
    }
}

/* Phones: MainLayout puts the session group on a row of its own under the name and the actions;
   it wraps rather than scroll, with room between rows for the floating labels. */
@media (max-width: 640.98px) {
    .topbar-session[b-ziwjnc1myk] {
        flex-wrap: wrap;
        justify-content: center;
        row-gap: var(--cpd-space-lg);
    }
}
/* /Components/Market/Capture/CurveCaptureDialog.razor.rz.scp.css */
.capture-header[b-uzh1xax85z] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.capture-generator-chip[b-uzh1xax85z] {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.66rem;
    color: var(--cpd-gold);
    background: rgba(var(--cpd-gold-rgb), 0.08);
    border: 1px solid rgba(var(--cpd-gold-rgb), 0.25);
    border-radius: var(--cpd-radius-sm);
    padding: 2px 8px;
}

/* The spec's name in the chip: a link, in the chip's own colour, underlined so it reads as one. */
.capture-generator-link[b-uzh1xax85z] {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.capture-body[b-uzh1xax85z] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
}

.capture-field[b-uzh1xax85z] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.capture-field-label[b-uzh1xax85z] {
    font-size: 0.66rem;
    color: var(--cpd-accent);
}

.capture-composite[b-uzh1xax85z] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* The rate convention on one line: the toggle, then the rate's day count, then (compound only) the
   frequency, so the day count never moves when Compound is chosen. */
.capture-convention-row[b-uzh1xax85z] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-md);
}

.capture-convention-select[b-uzh1xax85z] {
    flex: 0 0 auto;
    min-width: 9rem;
}

/* A new curve's identity: Type, then what that type is keyed by, side by side. */
.capture-key-row[b-uzh1xax85z] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--cpd-space-md);
}

.capture-key-row > .capture-field[b-uzh1xax85z] {
    min-width: 10rem;
}

/* The curve's own name: room for a source system's long name, not the dialog's whole width. */
.capture-field-name[b-uzh1xax85z] {
    max-width: 40rem;
}

/* Derived text under a field (Shape's interpolation) and the rate-model hand-over line. */
.capture-field-caption[b-uzh1xax85z] {
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-muted);
}

.capture-segmented .mud-toggle-item[b-uzh1xax85z] {
    font-size: 0.72rem;
}

.capture-gold-btn[b-uzh1xax85z] {
    color: var(--cpd-gold);
    border-color: rgba(var(--cpd-gold-rgb), 0.5);
    font-size: 0.66rem;
    align-self: flex-start;
}

.capture-compare[b-uzh1xax85z] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
}

.capture-compare-row[b-uzh1xax85z] {
    margin-bottom: var(--cpd-space-lg);
}

.capture-compare-notice .capture-compare[b-uzh1xax85z] {
    margin-top: var(--cpd-space-sm);
}

.capture-footer-note[b-uzh1xax85z] {
    font-size: 0.69rem;
    color: var(--cpd-text-subtle);
}
/* /Components/Market/Capture/CurveChart.razor.rz.scp.css */
.curve-chart[b-y8ftd0y6qd] {
    display: flex;
    align-items: stretch;
    gap: 6px;
    width: 100%;
}

.curve-chart-gutter[b-y8ftd0y6qd] {
    position: relative;
    width: 56px;
    flex: none;
}

.curve-chart-y-label[b-y8ftd0y6qd] {
    position: absolute;
    right: 0;
    transform: translateY(-50%);
    font-family: var(--cpd-font-mono);
    font-size: 0.6rem;
    color: rgba(var(--cpd-contrast-rgb), calc(0.42 * var(--cpd-text-alpha-scale)));
    white-space: nowrap;
}

.curve-chart-plot[b-y8ftd0y6qd] {
    position: relative;
    flex: 1;
    min-width: 0;
}

.curve-chart-svg[b-y8ftd0y6qd] {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
    font-family: var(--cpd-font-mono);
}

.curve-chart-extrap-region[b-y8ftd0y6qd] {
    fill: var(--cpd-gold-faint);
}

.curve-chart-extrap-split[b-y8ftd0y6qd] {
    stroke: rgba(var(--cpd-gold-rgb), 0.35);
    stroke-width: 1;
    stroke-dasharray: 3 3;
}

.curve-chart-gridline-h[b-y8ftd0y6qd] {
    stroke: rgba(var(--cpd-contrast-rgb), 0.06);
    stroke-width: 1;
}

.curve-chart-gridline-v[b-y8ftd0y6qd] {
    stroke: rgba(var(--cpd-contrast-rgb), 0.04);
    stroke-width: 1;
}

.curve-chart-baseline[b-y8ftd0y6qd] {
    stroke: rgba(var(--cpd-contrast-rgb), 0.18);
    stroke-width: 1;
}

.curve-chart-line[b-y8ftd0y6qd] {
    fill: none;
    stroke: var(--cpd-gold);
    stroke-width: 2;
    stroke-linejoin: round;
}

.curve-chart-line-tail[b-y8ftd0y6qd] {
    stroke-dasharray: 5 4;
}

.curve-chart-pillar[b-y8ftd0y6qd] {
    fill: var(--cpd-dark);
    stroke: var(--cpd-gold);
    stroke-width: 1.6;
}

.curve-chart-crosshair-v[b-y8ftd0y6qd] {
    stroke: rgba(var(--cpd-contrast-rgb), 0.45);
    stroke-width: 1;
}

.curve-chart-crosshair-h[b-y8ftd0y6qd] {
    stroke: rgba(var(--cpd-contrast-rgb), 0.2);
    stroke-width: 1;
    stroke-dasharray: 2 3;
}

.curve-chart-hover-dot[b-y8ftd0y6qd] {
    fill: var(--cpd-gold);
}

.curve-chart-extrap-label[b-y8ftd0y6qd] {
    position: absolute;
    top: 2px;
    font-family: var(--cpd-font-mono);
    font-size: 0.56rem;
    letter-spacing: 0.08em;
    color: rgba(var(--cpd-gold-rgb), 0.6);
    white-space: nowrap;
    pointer-events: none;
}

.curve-chart-x-label[b-y8ftd0y6qd] {
    position: absolute;
    transform: translateX(-50%);
    font-family: var(--cpd-font-mono);
    font-size: 0.6rem;
    color: rgba(var(--cpd-contrast-rgb), calc(0.42 * var(--cpd-text-alpha-scale)));
    white-space: nowrap;
    pointer-events: none;
}

.curve-chart-readout[b-y8ftd0y6qd] {
    position: absolute;
    top: 16px;
    transform: translateX(-50%);
    display: flex;
    gap: 10px;
    align-items: baseline;
    background: var(--cpd-surface-dialog);
    border: 1px solid rgba(var(--cpd-gold-rgb), 0.35);
    border-radius: var(--cpd-radius-md);
    padding: 5px 10px;
    font-family: var(--cpd-font-mono);
    font-size: 0.69rem;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: var(--cpd-shadow-soft);
}

.curve-chart-readout-date[b-y8ftd0y6qd] {
    color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale)));
}

.curve-chart-readout-tenor[b-y8ftd0y6qd] {
    color: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
}

.curve-chart-readout-value[b-y8ftd0y6qd] {
    color: var(--cpd-gold);
    font-weight: 600;
}

/* A second series (the impact panel's "before" beside its "after"): the muted contrast stroke
   behind the gold primary line, and a two-swatch legend under the plot. */
.curve-chart-line-comparison[b-y8ftd0y6qd] {
    stroke: rgba(var(--cpd-contrast-rgb), calc(0.45 * var(--cpd-text-alpha-scale)));
    stroke-width: 1.5;
}

.curve-chart-readout-comparison[b-y8ftd0y6qd] {
    color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale)));
}

.curve-chart-legend[b-y8ftd0y6qd] {
    display: flex;
    gap: var(--cpd-space-md);
    justify-content: flex-end;
    padding-top: var(--cpd-space-xs);
    font-family: var(--cpd-font-mono);
    font-size: var(--cpd-text-0);
    color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale)));
}

.curve-chart-legend-item[b-y8ftd0y6qd] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
}

.curve-chart-legend-swatch[b-y8ftd0y6qd] {
    display: inline-block;
    width: var(--cpd-space-lg);
    height: 2px;
    background: var(--cpd-gold);
}

.curve-chart-legend-swatch-comparison[b-y8ftd0y6qd] {
    background: rgba(var(--cpd-contrast-rgb), calc(0.45 * var(--cpd-text-alpha-scale)));
}
/* /Components/Market/Capture/CurveLeaf.razor.rz.scp.css */
/* Entry on the left (the grid and its keyboard flow), the live chart on the right; one column below
   1024 (docs/ux-shape.md entry 9). */
.leaf-body[b-gum078jv4g] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--cpd-space-lg);
}

@media (max-width: 1024px) {
    .leaf-body[b-gum078jv4g] {
        grid-template-columns: minmax(0, 1fr);
    }
}

.leaf-entry[b-gum078jv4g],
.leaf-view[b-gum078jv4g] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-md);
    min-width: 0;
}

.leaf-field[b-gum078jv4g] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

.leaf-field-label[b-gum078jv4g] {
    font-size: var(--cpd-text-0);
    color: var(--cpd-accent);
}

.leaf-field-caption[b-gum078jv4g] {
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-subtle);
}

.leaf-view-as[b-gum078jv4g] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
}

/* "View only" is the toggle's own caption, read at body size rather than as a footnote. */
.leaf-view-caption[b-gum078jv4g] {
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-muted);
}

/* Which linked index the forward reads, beside the toggle: as wide as an index name. */
.leaf-view-as[b-gum078jv4g]  .leaf-forward-select {
    flex: 0 0 auto;
    inline-size: 10rem;
}

.leaf-segmented .mud-toggle-item[b-gum078jv4g] {
    font-size: var(--cpd-text-0);
}

.leaf-chart-box[b-gum078jv4g] {
    background: var(--cpd-surface-inset);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-lg);
    padding: var(--cpd-space-sm);
}

.leaf-hints[b-gum078jv4g] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-sm);
}

.leaf-hint-chip[b-gum078jv4g] {
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-subtle);
    background: var(--cpd-surface-inset);
    border-radius: var(--cpd-radius-sm);
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
}

.leaf-advanced > summary[b-gum078jv4g] {
    cursor: pointer;
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-muted);
}

.leaf-advanced-body[b-gum078jv4g] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: var(--cpd-space-md);
    margin-top: var(--cpd-space-sm);
}

/* A date derived from a typed tenor is read-only in meaning and muted on screen (docs/ux-shape.md
   entry 19); the picker stays on the cell, and typing or picking a date makes it an input again.
   DateField is a child component, so its input is reached through ::deep. */
.leaf-body[b-gum078jv4g]  .leaf-derived input {
    color: var(--cpd-text-muted);
}

/* The last-pillar marker (docs/table-shape.md's RowClass), matching the caption under Extrapolation
   that reads "Tail applies from the last pillar, …". `DataTable` renders the grid through
   `MudDataGrid`, so the row is reached only via `::deep`, and the cell class is named because
   MudBlazor paints every body cell through three classes (verified in a browser 2026-09-22). */
[b-gum078jv4g] tr.leaf-grid-split-row td.mud-table-cell {
    color: var(--cpd-gold);
}
/* /Components/Market/Capture/ObligorEntityInput.razor.rz.scp.css */
/* A candidate: the party's name, then what kind of party it is, muted. */
.obligor-option[b-oi8bmz4qvf] {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    width: 100%;
}

.obligor-option-kind[b-oi8bmz4qvf] {
    color: var(--mud-palette-text-secondary);
}
/* /Components/Market/MarketDataRequirements.razor.rz.scp.css */
.status-ok[b-6gs7710jb4],
.status-missing[b-6gs7710jb4] {
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 2px 8px;
    border-radius: 10px;
}

.status-ok[b-6gs7710jb4] {
    color: var(--token-rate);
    background: var(--token-rate-bg);
}

.status-missing[b-6gs7710jb4] {
    color: var(--token-position);
    background: var(--token-position-bg);
}
/* /Components/Market/MarketRefPicker.razor.rz.scp.css */
/* A labelled link reads as one line: the icon, "Linked to …", and its Unlink. */
.ref-picker-linked[b-9umk83a4mw] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
}
/* /Components/NotificationPanel.razor.rz.scp.css */
/* A visible focus ring for the bell and the drawer's buttons (ux rule 13, shakedown C19). The shell's
   .btn:focus ring is --cpd-focus, gold at 30% alpha, which is all but invisible on the dark top bar,
   and MudBlazor's buttons draw none of their own (outline: 0) - only a faint hover-like circle. Solid
   --cpd-gold, the same ring DataTable's hints and the Market rail tabs use. :focus-visible, so a mouse
   click does not leave a ring behind. The outline follows each button's own radius (round for
   MudIconButton), so only the square bell is given one. */
.notification-bell-btn:focus-visible[b-s7gsfyb1ce],
.notification-drawer-host[b-s7gsfyb1ce]  .mud-button-root:focus-visible {
    outline: 2px solid var(--cpd-gold);
    outline-offset: 2px;
}

.notification-bell-btn:focus-visible[b-s7gsfyb1ce] {
    border-radius: var(--cpd-radius-sm);
}
/* /Components/PageDescription/BodyView.razor.rz.scp.css */
/* The stale treatment's wrapper when the body is not stale (BodyView.razor): there so the content
   stays at one place in the tree, and laid out as if it were not. */
.page-body[b-uwasrab3kc] {
    display: contents;
}

/* A key/value row is BodyView's own markup, so its layout is styled here rather than from
   PageRenderer: a body drawn outside a page (the agreement dialog's Reference row, a create dialog's
   form) reads the same as one inside a pane — the label on the left, the value on the right.
   A label and its value share a line when both fit. When they do not (a long label in a narrow
   rail tile: "SIMM to collect · CP2-ISDA-2018-Rates"), the value moves to its own line, right-aligned,
   rather than both columns shrinking until the figure breaks across two lines. */
.page-key-values-row[b-uwasrab3kc] {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    column-gap: var(--cpd-space-sm);
}

.page-key-values-value[b-uwasrab3kc] {
    margin-left: auto;
    text-align: right;
}

/* A Body.ControlGroup is a short field set (a Designation pane's three fields, a Details pane's
   legal name + recovery rate, a dialog's settings row): a wrapping flex row, so its fields sit side
   by side and drop to their own line only when the row runs out of room. It is BodyView's own markup,
   so the layout lives here and every Body gets it wherever it is drawn - a PageRenderer page or a
   dialog (the xVA Simulation settings) - with no per-page or per-dialog copy on top of it. */
.page-control-group[b-uwasrab3kc] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--cpd-tile-gap);
}

/* Each field is ControlView's, a child component whose root never carries this file's scope, hence
   ::deep (`.page-control-group[b-…] > *`). --cpd-field-min matches .page-field-select's own min-width
   (PageRenderer.razor.css) so a select's longest option still fits before the row wraps; the
   --cpd-field-max cap stops a lone short field (a numeric recovery rate) from stretching to fill
   whatever space the row has left, which read as "the field is broken", not "the field is short".
   Both tighten together under compact density (220/320 -> 180/280). */
.page-control-group[b-uwasrab3kc] >  * {
    flex: 1 1 var(--cpd-field-min);
    max-width: var(--cpd-field-max);
}

/* A hero figure (Body.Figure): a Valuation KPI card's value, a PV outside the rail. The type scale's
   headline step, in tabular monospaced figures so digits line up across cards (docs/ux-shape.md §3, §6). */
.page-figure[b-uwasrab3kc] {
    font-family: var(--cpd-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: var(--cpd-text-4);
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
}

/* A Body.Section's caption: a sub-heading inside a tile or pane, one step below the pane's own title,
   so a pane of several tables reads as captioned parts rather than one run of rows. */
.page-section + .page-section[b-uwasrab3kc] {
    margin-top: var(--cpd-space-md);
}

.page-section-title[b-uwasrab3kc] {
    font-size: var(--cpd-text-1);
    font-weight: 600;
    margin: 0 0 var(--cpd-space-xs);
}
/* /Components/PageDescription/PageRenderer.razor.rz.scp.css */
/* The renderer root is a named query container so the pane layout below can ask how much room
   IT has rather than how wide the viewport is - the two differ by the sidebar's width, which the
   user can flip between 250px and 56px at any moment. Named, because SummaryTile's own root is
   an (unnamed) inline-size container too and an unnamed @container would resolve to whichever is
   nearest. */
.page-renderer[b-hj3k3nuptm] {
    container-type: inline-size;
    container-name: page-renderer;
}

/* The title row: the title takes what the topbar leaves, down to a basis wide enough for a
   heading, so a long subtitle does not push the topbar onto its own row; a topbar wider than the
   rest of the row wraps below the title and stays right-aligned (PageRenderer.razor). With no
   title (a list page whose heading is CPStudioBasePage's) the topbar keeps its left alignment. */
.page-renderer-title[b-hj3k3nuptm] {
    flex: 1 1 24rem;
    min-width: 0;
}

.page-renderer[b-hj3k3nuptm]  .page-renderer-topbar {
    margin-left: auto;
    justify-content: flex-end;
}

/* Replaces MudBlazor's `pa-4` on the flat tile so the padding follows the density tokens; the
   `mb-4` beside it is unchanged, being tile SEPARATION rather than tile density. The tile is a
   MudPaper, a child component whose root never carries this file's scope attribute, so the rule
   is reached through ::deep from the renderer's own root (a bare `.page-tile` matched nothing).
   Only a tile whose summary is not a bare grid takes it: a bare grid's DataTable draws its own
   header row and cell padding edge to edge, and padding round it would inset it twice. */
.page-renderer[b-hj3k3nuptm]  .page-tile--padded {
    padding: var(--cpd-tile-pad);
}

.page-tile-header[b-hj3k3nuptm] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 0.75rem;
}

.page-tile-header-controls[b-hj3k3nuptm] {
    display: flex;
    gap: 0.5rem;
}

/* Mobile first: below the expanded size class (docs/ux-shape.md entry 18) the pane layout is ONE
   column - the summary tiles become a wrapping strip ABOVE the detail pane, read top-to-bottom by
   the page's own scroller. The two-column rule is the container query further down. */
.page-tile-pane-layout[b-hj3k3nuptm] {
    display: flex;
    gap: var(--cpd-tile-gap);
    /* Stretch, not flex-start: in COLUMN mode align-items is a cross-axis WIDTH constraint, and
       flex-start shrink-wrapped both children - the strip of summary tiles collapsed to ~28px wide,
       one word per line. Stretch is the column equivalent of what flex-start means in a row. */
    flex-direction: column;
    align-items: stretch;
    /* The ribbon layer's box and its floor: positioned so the layer below can cover exactly this
       layout, and isolated so its z-index:-1 puts it under both columns without sinking it behind
       the page's own background. */
    position: relative;
    isolation: isolate;
}

/* The ribbon layer (TileRibbons.razor, drawn by tileRibbons.js; docs/ux-shape.md §22): under the
   columns' content, inert, and not drawn at all until the two-column query below shows it - the
   one place "is this two columns" is answered, which the script reads as "is the layer shown". */
.page-tile-pane-layout[b-hj3k3nuptm] >  .tile-ribbons {
    display: none;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
    pointer-events: none;
}

/* Opening a pane grows it out of its tile (§22, "Open in view"; Material's container transform):
   from the top right, the tile's side in both layouts - the rail is to the right in two columns
   and the strip above in one. Only a newly opened pane animates: its slot is keyed, so a re-render
   keeps an open pane's element. The duration is the 150 ms motion token, which the global
   reduced-motion rule in app.css zeroes, so under prefers-reduced-motion the pane appears without
   a transform. No fill mode: a transform held after the end would make every open pane a
   containing block for its fixed-position descendants. */
.page-pane-slot[b-hj3k3nuptm] {
    transform-origin: top right;
    animation: page-pane-grow-b-hj3k3nuptm var(--cpd-transition-fast);
}

@keyframes page-pane-grow-b-hj3k3nuptm {
    from {
        opacity: 0;
        transform: scale(0.9);
    }
}

.page-tile-pane-left[b-hj3k3nuptm] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-tile-gap);
}

/* A page's flat tiles on a page with a rail (PageRenderer.razor; docs/ux-shape.md §18, amended
   2026-10-15): the head of the primary column, above its open panes, spaced as the column spaces
   its panes. In one column the rail's strip (order -1 below) sits above them, which is §18's
   compact rule - rail tiles as a strip above the body - and the open panes follow them. */
.page-tile-flat[b-hj3k3nuptm] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-tile-gap);
}

.page-tile-pane-right[b-hj3k3nuptm] {
    order: -1;
    flex: none;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--cpd-tile-gap);
}

/* Each child is a tile's .page-rail-slot (the SummaryTile inside fills it) or the embedded lens's
   rail root, which is a child component's, so ::deep is required and the child combinator is NOT
   enough: the isolation rewriter appends the scope attribute to the LAST compound selector,
   so a bare `.page-tile-pane-right > *` compiles to `.page-tile-pane-right > *[b-<hash>]` -
   asking the child to carry THIS component's scope, which a child component's root never
   does. Verified in the emitted bundle; with ::deep it compiles to
   `.page-tile-pane-right[b-<hash>] > *`, which is the intended meaning.

   260px, not 220: a tile in this strip is itself a query container, and XvaTile's and
   SensitivityTile's stat grids drop to one column below 240px. A 220px basis put a wrapped
   tile the wrong side of that line, so the strip that exists to use the extra width
   rendered its figures stacked. 260 keeps every strip tile clear of the threshold. */
.page-tile-pane-right[b-hj3k3nuptm] >  * { flex: 1 1 260px; min-width: 0; }

/* From 1024px of the renderer's OWN width (the expanded size class's boundary, asked of the
   container rather than the viewport so it also follows the sidebar's 250px/56px flip): the
   primary column on the left, the tile rail on the right.

   Independent verticals (owner-reported shakedown bug): before the caps below, the two columns
   had NO height cap of their own, so the row's rendered height was simply `max(left, right)` and
   the page's single scroller (`.cpd-shell-content`, app.css "Shell geometry") carried both. Opening a
   tall pane (the trade editor, easily taller than the five-card rail) pushed everything BELOW the
   row down by however tall the pane happened to be; closing it left a wide blank rectangle beside
   a tall rail, reported as "a big empty gap when xVA is shown". Capping each column's OWN box at a
   generous share of the viewport and giving it its own scrollbar makes the pair genuinely
   independent: nothing past this row ever shifts because of what is open in either column, and a
   short/empty column just renders short. 4.75rem matches the `calc(100vh - 4.75rem)` app.css
   already uses for "viewport minus the top-row chrome" (`.hero`); it undercounts whatever this
   renderer's own title row/topbar/alerts add above the pane row, so on a short viewport
   the box can still run a little past the fold before its OWN scrollbar takes over - preferable to
   a host-specific magic number, since PageRenderer has no idea which page sits above it. The caps
   are a two-column device only: stacked, they would be two cramped, separately-scrolling boxes. */
@container page-renderer (min-width: 1024px) {
    .page-tile-pane-layout[b-hj3k3nuptm] {
        flex-direction: row;
        /* So the rail does not stretch to the detail pane's height. */
        align-items: flex-start;
        /* The gutter the ribbons cross (§22): at the tile gap a band is a hairline, so the two
           columns stand a diff tool's connector width apart. */
        column-gap: var(--cpd-space-2xl);
    }

    .page-tile-pane-left[b-hj3k3nuptm] {
        max-height: calc(100vh - 4.75rem);
        overflow-y: auto;
    }

    .page-tile-pane-right[b-hj3k3nuptm] {
        order: 0;
        flex: 0 0 var(--cpd-pane-rail-w);
        flex-direction: column;
        flex-wrap: nowrap;
        max-height: calc(100vh - 4.75rem);
        overflow-y: auto;
    }

    .page-tile-pane-right[b-hj3k3nuptm] >  * { flex: initial; min-width: auto; }

    /* Ribbons are a two-column device (§22): below this query the tile sits in the strip above its
       pane, and the tint and the repeated title carry the link. */
    .page-tile-pane-layout[b-hj3k3nuptm] >  .tile-ribbons { display: block; }
}

/* After the container query, so it wins: under forced colours the tints are gone, and a band in
   a system colour would only cover what it joins. */
@media (forced-colors: active) {
    .page-tile-pane-layout[b-hj3k3nuptm] >  .tile-ribbons { display: none; }
}

[b-hj3k3nuptm] .page-description-error {
    border: 1px dashed var(--mud-palette-error, #d32f2f);
    color: var(--mud-palette-error, #d32f2f);
    padding: 0.5rem 0.75rem;
    border-radius: 4px;
    font-weight: 600;
}

[b-hj3k3nuptm] .page-field-select {
    min-width: var(--cpd-field-min);
}

[b-hj3k3nuptm] .page-grid {
    width: 100%;
    border-collapse: collapse;
}

[b-hj3k3nuptm] .page-grid-row-nav {
    cursor: pointer;
}

/* The row's icon buttons are a single horizontal cluster, never a stack. Without this they are
   inline-blocks that wrap inside the (narrow, content-sized) sticky column — on Trades/View, whose
   rows carry three lens links plus a hedge link, they stacked one-per-line and quadrupled every
   row's height. nowrap makes the column size to the cluster instead of the cluster to the column. */
[b-hj3k3nuptm] .page-grid-row-controls {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.125rem;
}

/* A sticky column floats over the cells it covers, so it needs its own opaque background or the
   scrolled-under text shows through the lens icons. MudBlazor's own sticky styling assumes the
   default surface colour; this app themes the grid darker, hence the explicit surface token. The
   left border is what tells you the column is pinned rather than merely last.

   Specificity, not just source order: MudBlazor ships its own
   `.mud-data-grid .mud-table-cell.sticky-left, .mud-data-grid .mud-table-cell.sticky-right`
   rule (3 classes = 0,3,0) setting `background-color: var(--mud-palette-background-gray)` — its
   dark-theme default grey (#27272f), which clashes with this app's navy `--mud-palette-surface`.
   A plain `.page-grid-controls-header`/`.page-grid-controls-cell` selector (0,2,0) LOSES to that
   rule regardless of source order, so the pinned actions column rendered as a grey band on the
   Trades list and inside the hedge Composition pane. Repeating MudBlazor's own selector shape here
   plus our own marker class (0,4,0) beats it on specificity instead of relying on cascade order,
   which a future "simplify this selector" pass could silently break. Don't shorten this back to
   `.page-grid-controls-header`/`.page-grid-controls-cell` alone. */
[b-hj3k3nuptm] .mud-data-grid .mud-table-cell.sticky-right.page-grid-controls-header,
[b-hj3k3nuptm] .mud-data-grid .mud-table-cell.sticky-right.page-grid-controls-cell {
    background-color: var(--cpd-surface-table);
    border-left: 1px solid var(--mud-palette-table-lines);
}

/* A row state's tint is translucent (the hover wash is gold at 6%), so painting it alone would let
   the cells scrolled under the column show through (Workspaces' Created, 2026-10-14). It is layered
   as an image over the opaque surface above, which stays: a new row state adds its tint here the
   same way, never as a background-color. */
[b-hj3k3nuptm] .mud-table-row:hover .mud-table-cell.sticky-right.page-grid-controls-cell {
    background-image: linear-gradient(var(--cpd-row-hover), var(--cpd-row-hover));
}

/* The one stale treatment (`Body.Stale`, rendered by BodyView; docs/frontend-spec.md R-3.14 and
   §7.6's dashed rail): figures kept from an earlier run stay readable at full contrast, beside a
   dashed rail in the attention role and under a short caption, so the state is never colour alone.
   No opacity: dimming kept figures would take muted text below the contrast floor. */
[b-hj3k3nuptm] .page-stale {
    border-left: 3px dashed var(--cpd-warning);
    padding-left: var(--cpd-space-sm);
}

[b-hj3k3nuptm] .page-stale-caption {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-0);
    margin-bottom: var(--cpd-space-xs);
}
/* /Components/PageDescription/RailBody.razor.rz.scp.css */
/* A rail tile's figures in the tile style (docs/ux-shape.md §6, "Tile style"). Figures are
   monospaced tabular digits, so they line up; colour comes from what a figure means for the book
   (rail-gain / rail-loss, the success and error tokens), and never from a status. */

.rail-hero-figure[b-jba5v1qkb5],
.rail-more-value[b-jba5v1qkb5] {
    font-family: var(--cpd-font-mono);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.rail-gain[b-jba5v1qkb5] {
    color: var(--cpd-success);
}

.rail-loss[b-jba5v1qkb5] {
    color: var(--cpd-error);
}

/* A note under the figures: a run's progress, a reason, a "see the pane". Plain text, never a boxed
   alert: the tile's state already says how serious it is. */
.rail-note[b-jba5v1qkb5] {
    margin-top: var(--cpd-space-xs);
    font-size: var(--cpd-text-0);
}

.rail-note--muted[b-jba5v1qkb5] {
    color: var(--cpd-text-muted);
}

.rail-hero[b-jba5v1qkb5] {
    display: grid;
}

.rail-hero-label[b-jba5v1qkb5] {
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-subtle);
}

/* The full figure, its size stepping down with its length so it never wraps or abbreviates: the tile
   is the query container (SummaryTile), --rail-figure-length the figure's characters. */
.rail-hero-figure[b-jba5v1qkb5] {
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1.15;
    font-size: clamp(var(--cpd-text-1), calc(100cqi / (var(--rail-figure-length, 10) * 0.62)), var(--cpd-text-4));
}

.rail-hero-caption[b-jba5v1qkb5] {
    font-size: var(--cpd-text-0);
    font-weight: 500;
    letter-spacing: 0.06em;
    color: var(--cpd-text-subtle);
}

.rail-more[b-jba5v1qkb5] {
    margin-top: var(--cpd-space-sm);
    padding-top: var(--cpd-space-xs);
    border-top: 1px solid var(--cpd-border);
}

.rail-more summary[b-jba5v1qkb5] {
    cursor: pointer;
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-muted);
}

.rail-more-grid[b-jba5v1qkb5] {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.1em var(--cpd-space-sm);
    margin-top: var(--cpd-space-xs);
    font-size: var(--cpd-text-0);
}

.rail-more-label[b-jba5v1qkb5] {
    color: var(--cpd-text-muted);
}

.rail-more-value[b-jba5v1qkb5] {
    text-align: right;
}
/* /Components/Pages/Analytics/LensScopePicker.razor.rz.scp.css */
/* The dropdown row: the identifier, and the muted trade count beneath it. The row template exists
   because the detail must not reach the box after a pick — see LensScopeCandidate — so these two rules are what make the second line read as a caption
   rather than as part of the name.

   Scoped, not global, for the reason DECISIONS.md #50 gives for `@Assets`: a component in
   CPStudio.Client must not depend on a host `wwwroot` stylesheet for its own layout. The rest of this
   component's chrome (.scope-picker, .scope-picker-category, .scope-picker-item) is deliberately
   *not* here: those classes are the server ScopePicker's own, served document-wide, and duplicating
   them would make the two pickers drift apart visually while the two components still coexist. */

.scope-picker-option[b-3hiza2xh7y] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.scope-picker-option-label[b-3hiza2xh7y] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.scope-picker-option-detail[b-3hiza2xh7y] {
    font-size: 11px;
    letter-spacing: 0.02em;
    color: var(--cpd-text-subtle);
}
/* /Components/Pages/Analytics/Recon.razor.rz.scp.css */
.recon-card[b-mzgjdjgi11] {
    animation: fadeUp-b-mzgjdjgi11 0.3s cubic-bezier(0.16, 1, 0.3, 1) both 0.04s;
}

@keyframes fadeUp-b-mzgjdjgi11 {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

.recon-topbar[b-mzgjdjgi11] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 20px;
    gap: 12px;
    flex-wrap: wrap;
}

.recon-title-group[b-mzgjdjgi11] {
    display: flex;
    align-items: center;
    gap: 14px;
    min-height: 32px;
    flex-wrap: wrap;
}

.recon-title-block[b-mzgjdjgi11] {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.recon-page-title[b-mzgjdjgi11] {
    font-size: 20px;
    font-weight: 700;
    color: var(--cpd-contrast);
    letter-spacing: -0.03em;
}

/* Matches the secondary-coloured subtitle every Page-DU analytics lens gets for free from
   PageRenderer's Typo.body2/Color.Secondary title row — this file already uses the same
   rgba(255, 255, 255, *) scale for muted text elsewhere (.recon-date-label, .recon-empty-hint), so
   this follows that established convention rather than introducing a new token. */
.recon-page-subtitle[b-mzgjdjgi11] {
    font-size: 13px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale)));
}

.recon-status-chip[b-mzgjdjgi11] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    background: rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.06);
    border: 1px solid rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.25);
    border-radius: 6px;
    font-family: var(--cpd-font-mono);
    font-size: 12px;
    color: var(--cpd-contrast);
}

.recon-status-chip i[b-mzgjdjgi11] {
    color: var(--cpd-gold);
    font-size: 13px;
}

.recon-status-count[b-mzgjdjgi11] {
    color: rgba(var(--cpd-contrast-rgb), calc(0.5 * var(--cpd-text-alpha-scale)));
}

.recon-scope-clear[b-mzgjdjgi11] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: inherit;
    opacity: 0.6;
    cursor: pointer;
    padding: 0;
    margin-left: 2px;
    font-size: 11px;
}

.recon-scope-clear:hover[b-mzgjdjgi11] {
    opacity: 1;
    color: var(--cpd-gold);
}

.recon-meta-group[b-mzgjdjgi11] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.recon-date-label[b-mzgjdjgi11] {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.45 * var(--cpd-text-alpha-scale)));
    margin: 0;
}

.recon-tolerance-group[b-mzgjdjgi11] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0 6px 0 0;
    border-right: 1px solid rgba(var(--cpd-contrast-rgb), 0.08);
    margin-right: 2px;
}

.recon-tolerance-value[b-mzgjdjgi11] {
    background: rgba(var(--cpd-contrast-rgb), 0.04);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.12);
    color: var(--cpd-contrast);
    border-radius: 6px;
    padding: 6px 8px;
    font-family: var(--cpd-font-mono);
    font-size: 13px;
    width: 90px;
}

.recon-tolerance-mode[b-mzgjdjgi11] {
    background: rgba(var(--cpd-contrast-rgb), 0.04);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.12);
    color: var(--cpd-contrast);
    border-radius: 6px;
    padding: 6px 8px;
    font-family: var(--cpd-font-mono);
    font-size: 13px;
}

.recon-tolerance-value:focus[b-mzgjdjgi11],
.recon-tolerance-mode:focus[b-mzgjdjgi11] {
    outline: none;
    border-color: var(--cpd-gold);
    box-shadow: 0 0 0 2px rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.15);
}

.recon-table-card[b-mzgjdjgi11] {
    background: linear-gradient(135deg, rgba(var(--cpd-dark-rgb), 0.95) 0%, rgba(var(--cpd-panel-sheen-rgb), 0.95) 100%);
    border: 1px solid var(--cpd-gold-strong);
    border-radius: var(--cpd-radius-xl);
    box-shadow: var(--cpd-shadow-card);
    padding: 0.5rem 0;
    overflow-x: auto;
}

.recon-table[b-mzgjdjgi11] {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.recon-table thead th[b-mzgjdjgi11] {
    background: rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.05);
    color: var(--cpd-gold);
    font-weight: 600;
    text-transform: uppercase;
    font-size: 0.78rem;
    letter-spacing: 0.5px;
    border-bottom: 2px solid var(--cpd-gold-border);
    padding: 0;
    white-space: nowrap;
    text-align: left;
}

.recon-table thead th:first-child[b-mzgjdjgi11] { padding-left: 0.4rem; }
.recon-table thead th:last-child[b-mzgjdjgi11]  { padding-right: 0.4rem; }

.recon-sort-btn[b-mzgjdjgi11] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 0.7rem 0.85rem;
    background: transparent;
    border: none;
    color: inherit;
    font: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    cursor: pointer;
    text-align: left;
}

.recon-sort-btn.num[b-mzgjdjgi11] {
    justify-content: flex-end;
    text-align: right;
}

/* ::deep is required here. The sort icon is rendered from Recon.razor.cs rather than
   from this component's .razor markup, so it never receives the scope attribute that
   scoped CSS rewrites these selectors to expect — without ::deep these three rules
   match nothing, which is why the sort indicators were previously unstyled.
   Sizing is width/height rather than font-size because the icon is now inline SVG. */
.recon-sort-btn:hover[b-mzgjdjgi11]  .recon-sort-icon {
    color: var(--cpd-gold);
    opacity: 1;
}

.recon-sort-btn[b-mzgjdjgi11]  .recon-sort-icon {
    width: 14px;
    height: 14px;
    color: var(--cpd-gold);
    opacity: 0.85;
}

.recon-sort-btn[b-mzgjdjgi11]  .recon-sort-icon.recon-sort-idle {
    opacity: 0.25;
}

.recon-table tbody td[b-mzgjdjgi11] {
    color: var(--cpd-text);
    background: transparent;
    border-bottom: 1px solid var(--cpd-border-subtle);
    padding: 0.55rem 0.85rem;
    font-family: var(--cpd-font-mono);
    font-size: 13px;
}

.recon-table tbody tr:hover td[b-mzgjdjgi11] {
    background: var(--cpd-gold-faint);
}

.recon-table tbody td:first-child[b-mzgjdjgi11],
.recon-table thead th:first-child[b-mzgjdjgi11] { padding-left: 1.25rem; }

.recon-table tbody td:last-child[b-mzgjdjgi11],
.recon-table thead th:last-child[b-mzgjdjgi11]  { padding-right: 1.25rem; }

.recon-table .col-text[b-mzgjdjgi11]  { width: 1%; white-space: nowrap; }
.recon-table .col-date[b-mzgjdjgi11]  { width: 1%; white-space: nowrap; }
.recon-table .col-ccy[b-mzgjdjgi11]   { width: 1%; white-space: nowrap; }
.recon-table .col-action[b-mzgjdjgi11]{ width: 1%; white-space: nowrap; text-align: right; }
.recon-table .num[b-mzgjdjgi11]       { text-align: right; white-space: nowrap; }

.recon-ccy-cell[b-mzgjdjgi11] {
    font-family: var(--cpd-font-mono);
    font-size: 12px;
    letter-spacing: 0.05em;
    color: rgba(var(--cpd-contrast-rgb), calc(0.7 * var(--cpd-text-alpha-scale)));
}

.recon-ccy-cell.ccy-multi[b-mzgjdjgi11] {
    color: var(--cpd-gold);
    cursor: help;
    border-bottom: 1px dotted rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.4);
}

.recon-chevron-btn[b-mzgjdjgi11] {
    background: transparent;
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.10);
    color: rgba(var(--cpd-contrast-rgb), calc(0.5 * var(--cpd-text-alpha-scale)));
    width: 28px;
    height: 28px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background .15s, color .15s, border-color .15s;
}

.recon-chevron-btn:hover[b-mzgjdjgi11] {
    background: rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.10);
    border-color: rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.5);
    color: var(--cpd-gold);
}

.recon-table tfoot tr.recon-total-foot td[b-mzgjdjgi11] {
    border-top: 2px solid var(--cpd-gold-border);
    background: rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.05);
    color: var(--cpd-contrast);
    font-family: var(--cpd-font-mono);
    font-size: 14px;
    font-weight: 600;
    padding: 0.85rem 0.85rem;
}

.recon-table tfoot tr.recon-total-foot + tr.recon-total-foot td[b-mzgjdjgi11] {
    border-top: 1px solid var(--cpd-gold-border);
}

.recon-table tfoot td.recon-total-label[b-mzgjdjgi11] {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--cpd-gold);
}

.recon-empty-row td[b-mzgjdjgi11] {
    padding: 0 !important;
}

.recon-empty-state[b-mzgjdjgi11] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 3rem 1rem;
    text-align: center;
}

.recon-empty-icon[b-mzgjdjgi11] {
    font-size: 32px;
    color: rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.35);
}

.recon-empty-title[b-mzgjdjgi11] {
    font-size: 15px;
    font-weight: 600;
    color: var(--cpd-contrast);
}

.recon-empty-hint[b-mzgjdjgi11] {
    font-size: 13px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.45 * var(--cpd-text-alpha-scale)));
    max-width: 480px;
}

.recon-error[b-mzgjdjgi11] {
    margin-bottom: 14px;
    padding: 10px 14px;
    background: var(--token-position-bg);
    border: 1px solid var(--token-position-border);
    border-radius: 8px;
    color: var(--token-position);
    font-size: 13px;
}

.recon-error-cell[b-mzgjdjgi11] {
    font-family: var(--cpd-font-sans);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--token-position);
    padding: 2px 8px;
    background: var(--token-position-bg);
    border-radius: 10px;
    border: 1px solid var(--token-position-border);
    cursor: help;
}

.recon-total-note[b-mzgjdjgi11] {
    margin-top: 10px;
    padding: 8px 14px;
    font-size: 12px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale)));
    border-left: 2px solid rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.3);
    background: rgba(var(--cpd-contrast-rgb), 0.02);
    border-radius: 4px;
}

.recon-total-note strong[b-mzgjdjgi11] {
    color: var(--cpd-contrast);
    font-weight: 600;
}

.val-zero[b-mzgjdjgi11]          { color: rgba(var(--cpd-contrast-rgb), calc(0.45 * var(--cpd-text-alpha-scale))); }
.val-within-tolerance[b-mzgjdjgi11] { color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale))); }
.val-breach[b-mzgjdjgi11]        { color: var(--token-position); font-weight: 600; }
.val-neutral[b-mzgjdjgi11]       { color: rgba(var(--cpd-contrast-rgb), calc(0.45 * var(--cpd-text-alpha-scale))); }

/* Added by W4.7b, with the move into the browser: a three-state status line (#53). The page's own
   date select that W4.7b also added here is gone — the shell's top bar is the date control again
   (DECISIONS.md #106). */

/* The same rule as .recon-status, .hedges-status, .test-defaults-status and .instrument-status, and a
   deliberate fifth copy rather than a shared global class for the reason Hedges.razor.css records:
   scoped CSS is per-component here, and a global .cpd-status-line would make five WebAssembly pages
   depend on a host asset for their own layout. Five copies is where that trade stops being obvious —
   consolidating them is a follow-up, and it is one sweep across five files rather than a fifth of one. */
.recon-list-status[b-mzgjdjgi11] {
    margin: 12px 0 0;
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var(--cpd-text-subtle);
}
/* /Components/Pages/Analytics/ReconTrade.razor.rz.scp.css */
.recon-card[b-aehpfswsl6] {
    animation: fadeUp-b-aehpfswsl6 0.3s cubic-bezier(0.16, 1, 0.3, 1) both 0.04s;
}

@keyframes fadeUp-b-aehpfswsl6 {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

.recon-topbar[b-aehpfswsl6] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 20px;
    gap: 12px;
    flex-wrap: wrap;
}

.recon-title-group[b-aehpfswsl6] {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 32px;
}

.recon-page-title[b-aehpfswsl6] {
    font-size: 20px;
    font-weight: 700;
    color: var(--cpd-contrast);
    letter-spacing: -0.03em;
}

.recon-back-link[b-aehpfswsl6] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 6px;
    background: rgba(var(--cpd-contrast-rgb), 0.04);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.10);
    color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale)));
    font-size: 14px;
    text-decoration: none;
    transition: background .15s, color .15s, border-color .15s;
}

.recon-back-link:hover[b-aehpfswsl6] {
    background: var(--cpd-gold-ring);
    border-color: rgba(var(--cpd-gold-rgb), 0.5);
    color: var(--cpd-gold);
}

.recon-meta-group[b-aehpfswsl6] {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.recon-chip[b-aehpfswsl6] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    background: rgba(var(--cpd-contrast-rgb), 0.03);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.10);
    border-radius: 8px;
}

.recon-chip-label[b-aehpfswsl6] {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--cpd-text-subtle);
}

.recon-chip-value[b-aehpfswsl6] {
    font-family: var(--cpd-font-mono);
    font-size: 13px;
    font-weight: 500;
    color: var(--cpd-contrast);
}

.recon-detail-card[b-aehpfswsl6] {
    background: linear-gradient(135deg, rgba(var(--cpd-dark-rgb), 0.95) 0%, rgba(var(--cpd-panel-sheen-rgb), 0.95) 100%);
    border: 1px solid var(--cpd-gold-strong);
    border-radius: var(--cpd-radius-xl);
    padding: var(--cpd-space-lg) 1.25rem;
    box-shadow: var(--cpd-shadow-card);
    overflow-x: auto;
}

.recon-table[b-aehpfswsl6] {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.recon-table thead th[b-aehpfswsl6] {
    background: rgba(var(--cpd-gold-rgb), 0.05);
    color: var(--cpd-gold);
    font-weight: 600;
    text-transform: uppercase;
    font-size: 0.85rem;
    letter-spacing: 0.5px;
    border-bottom: 2px solid var(--cpd-gold-border);
    padding: 0.85rem var(--cpd-space-lg);
    text-align: left;
}

.recon-table th.num[b-aehpfswsl6],
.recon-table td.num[b-aehpfswsl6] {
    text-align: right;
    white-space: nowrap;
}

.recon-table tbody td[b-aehpfswsl6] {
    padding: 0.7rem 1rem;
    color: var(--cpd-contrast);
    border-bottom: 1px solid rgba(var(--cpd-contrast-rgb), 0.05);
    font-family: var(--cpd-font-mono);
    font-size: 13px;
}

.recon-table tbody tr:hover td[b-aehpfswsl6] {
    background: var(--cpd-gold-faint);
}

.recon-table .col-date[b-aehpfswsl6] { white-space: nowrap; width: 1%; }
.recon-table .col-match[b-aehpfswsl6] { white-space: nowrap; width: 1%; }
.recon-table .col-ccy[b-aehpfswsl6] { white-space: nowrap; width: 1%; color: rgba(var(--cpd-contrast-rgb), calc(0.6 * var(--cpd-text-alpha-scale))); letter-spacing: 0.05em; }

.recon-empty[b-aehpfswsl6] {
    text-align: center;
    padding: 2.5rem 1rem;
    color: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
    font-style: italic;
    font-family: inherit;
}

.recon-total-foot td[b-aehpfswsl6] {
    padding: 0.85rem var(--cpd-space-lg);
    border-top: 2px solid var(--cpd-gold-border);
    background: var(--cpd-gold-faint);
    color: var(--cpd-text);
    font-family: var(--cpd-font-mono);
    font-size: 14px;
    font-weight: 600;
}

.recon-total-foot td.num[b-aehpfswsl6] {
    text-align: right;
}

.recon-total-foot-diff[b-aehpfswsl6] {
    margin-right: 12px;
}

.recon-total-foot-label[b-aehpfswsl6] {
    font-family: var(--cpd-font-sans);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--cpd-gold);
}

.val-positive[b-aehpfswsl6] { color: var(--token-rate); }
.val-negative[b-aehpfswsl6] { color: var(--token-position); }
.val-neutral[b-aehpfswsl6]  { color: rgba(var(--cpd-contrast-rgb), calc(0.45 * var(--cpd-text-alpha-scale))); }
.val-zero[b-aehpfswsl6]          { color: rgba(var(--cpd-contrast-rgb), calc(0.45 * var(--cpd-text-alpha-scale))); }
.val-within-tolerance[b-aehpfswsl6] { color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale))); }
.val-breach[b-aehpfswsl6]        { color: var(--token-position); font-weight: 600; }

.recon-view-trade-link[b-aehpfswsl6] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    background: rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.06);
    border: 1px solid rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.25);
    border-radius: 6px;
    color: var(--cpd-contrast);
    font-size: 12px;
    text-decoration: none;
    transition: background .15s, border-color .15s, color .15s;
}

.recon-view-trade-link:hover[b-aehpfswsl6] {
    background: rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.12);
    border-color: var(--cpd-gold);
    color: var(--cpd-gold);
}

.recon-view-trade-link i[b-aehpfswsl6] {
    font-size: 12px;
    color: var(--cpd-gold);
}

.recon-tolerance-group[b-aehpfswsl6] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    background: rgba(var(--cpd-contrast-rgb), 0.03);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.10);
    border-radius: 8px;
}

.recon-tolerance-value[b-aehpfswsl6] {
    background: rgba(var(--cpd-contrast-rgb), 0.04);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.12);
    color: var(--cpd-contrast);
    border-radius: 6px;
    padding: 4px 8px;
    font-family: var(--cpd-font-mono);
    font-size: 13px;
    width: 80px;
}

.recon-tolerance-mode[b-aehpfswsl6] {
    background: rgba(var(--cpd-contrast-rgb), 0.04);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.12);
    color: var(--cpd-contrast);
    border-radius: 6px;
    padding: 4px 8px;
    font-family: var(--cpd-font-mono);
    font-size: 13px;
}

.recon-tolerance-value:focus[b-aehpfswsl6],
.recon-tolerance-mode:focus[b-aehpfswsl6] {
    outline: none;
    border-color: var(--cpd-gold);
    box-shadow: 0 0 0 2px rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.15);
}

.recon-fuzzy-banner[b-aehpfswsl6] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-bottom: 14px;
    padding: 10px 14px;
    background: rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.06);
    border: 1px solid rgba(var(--cpd-gold-rgb, 246, 212, 107), 0.3);
    border-radius: 8px;
    color: var(--cpd-contrast);
    font-size: 13px;
}

.recon-fuzzy-banner i[b-aehpfswsl6] {
    color: var(--cpd-gold);
    font-size: 14px;
}

.recon-fuzzy-banner strong[b-aehpfswsl6] {
    color: var(--cpd-gold);
}

.recon-fuzzy-banner-hint[b-aehpfswsl6] {
    color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale)));
}

.recon-date-stack[b-aehpfswsl6] {
    display: inline-flex;
    flex-direction: column;
    line-height: 1.25;
}

.recon-date-stack .recon-date-stored[b-aehpfswsl6] {
    font-size: 12px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale)));
}

.recon-date-stack .recon-date-live[b-aehpfswsl6] {
    font-size: 13px;
    color: var(--cpd-contrast);
}

.match-exact[b-aehpfswsl6],
.match-fuzzy[b-aehpfswsl6],
.match-stored[b-aehpfswsl6],
.match-live[b-aehpfswsl6] {
    display: inline-block;
    font-family: var(--cpd-font-sans);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 2px 8px;
    border-radius: 10px;
    border: 1px solid transparent;
}

.match-exact[b-aehpfswsl6]   { color: var(--token-rate);     background: var(--token-rate-bg);     border-color: var(--token-rate-border); }
.match-fuzzy[b-aehpfswsl6]   { color: var(--cpd-gold);       background: var(--cpd-gold-soft); border-color: var(--cpd-gold-border); }
.match-stored[b-aehpfswsl6]  { color: rgba(var(--cpd-contrast-rgb), calc(.55 * var(--cpd-text-alpha-scale))); background: rgba(var(--cpd-contrast-rgb),.04);    border-color: rgba(var(--cpd-contrast-rgb),.10); }
.match-live[b-aehpfswsl6]    { color: var(--token-position); background: var(--token-position-bg); border-color: var(--token-position-border); }

.recon-error[b-aehpfswsl6] {
    margin-bottom: 14px;
    padding: 10px 14px;
    background: var(--token-position-bg);
    border: 1px solid var(--token-position-border);
    border-radius: 8px;
    color: var(--token-position);
    font-size: 13px;
}

.recon-warn[b-aehpfswsl6] {
    margin-bottom: 14px;
    padding: 10px 14px;
    background: var(--cpd-gold-soft);
    border: 1px solid var(--cpd-gold-border);
    border-radius: var(--cpd-radius-lg);
    color: var(--cpd-text);
    font-size: 13px;
}

.recon-warn strong[b-aehpfswsl6] { color: var(--cpd-gold); }
.recon-warn-detail[b-aehpfswsl6] { color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale))); }

/* The three-state load line (DECISIONS.md #36). Quiet by design — it is a status, not a heading —
   and it is also the element the W4.6 browser smoke run measures a computed style on, so a
   CPStudio.Client.styles.css that stopped being linked (DECISIONS.md #39) shows up as
   `font-size: 16px` rather than as a page that merely looks a little different. */
.recon-status[b-aehpfswsl6] {
    margin: 12px 0 0;
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var(--cpd-text-subtle);
}
/* /Components/Pages/Analytics/RegCalcs.razor.rz.scp.css */
/* The FRTB | Initial margin measure switch. .trade-mode-btn (trade-mode-switcher.css, global) is a fixed square
   sized for single-glyph icon buttons; these carry words, so each button sizes to its label — the rule
   the Sensitivities and Margin panes apply to their own switchers. A size up from theirs: the measure
   is the page's first choice, not a view of a pane. */
.reg-calcs-measure[b-gzb850i0qy] {
    width: fit-content;
}

.reg-calcs-measure .trade-mode-btn[b-gzb850i0qy] {
    width: auto;
    height: auto;
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    font-size: var(--cpd-text-1);
    white-space: nowrap;
}
/* /Components/Pages/Analytics/Sensitivities.razor.rz.scp.css */
/* The three-state load line (DECISIONS.md #53). The same rule as `.recon-status`, `.recon-list-status`,
   `.hedges-status`, `.test-defaults-status` and `.instrument-status`, and a deliberate further copy
   rather than a shared global class for the reason Hedges.razor.css records: scoped CSS is per-component
   here, and a global `.cpd-status-line` would make every migrated page depend on a host `wwwroot` asset
   for its own layout — the coupling DECISIONS.md #50 argues against for `@Assets`. Consolidating the
   copies is recorded in DECISIONS.md #65. */
.sensitivities-status[b-u6qgqlv3mf] {
    margin: var(--cpd-space-md) 0 0;
    font-size: var(--cpd-text-0);
    letter-spacing: 0.04em;
    color: var(--cpd-text-subtle);
}

/* The Ladder | By Trade | Table switch. .trade-mode-btn (trade-mode-switcher.css, global) is a fixed
   square sized for single-glyph icon buttons; these carry words, so each button sizes to its label —
   the rule SensitivitySection.razor.css applies to its own switchers, scoped there. */
.sensitivities-view-switcher[b-u6qgqlv3mf] {
    width: fit-content;
    margin-bottom: var(--cpd-space-md);
}

.sensitivities-view-switcher .trade-mode-btn[b-u6qgqlv3mf] {
    width: auto;
    height: auto;
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    font-size: var(--cpd-text-0);
    white-space: nowrap;
}

.sensitivities-contributors-more[b-u6qgqlv3mf] {
    margin: var(--cpd-space-xs) 0 0;
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-subtle);
}
/* /Components/Pages/Analytics/Valuation.razor.rz.scp.css */
/* The three-state load line (DECISIONS.md #53) — see Sensitivities.razor.css for why this rule is
   written once per page rather than once for the app, and for the follow-up that would fix it. */
.valuation-status[b-sylxtrdayy] {
    margin: 12px 0 0;
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var(--cpd-text-subtle);
}
/* /Components/Pages/Conventions/AffectedTradesPopover.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). Wide enough for the six columns at 1280 without the
   table's own horizontal scroll; narrower viewports scroll inside the popover, never the page. */

.affected-trades[b-71eoby73h6] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    width: min(56rem, calc(100vw - 4 * var(--cpd-space-xl)));
}
/* /Components/Pages/Conventions/ConventionDocumentEditor.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). */

.doc-editor-header[b-jpv79wooq6] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--cpd-space-md);
}

.doc-editor-actions[b-jpv79wooq6] {
    display: flex;
    gap: var(--cpd-space-sm);
}

.doc-editor-note[b-jpv79wooq6] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
    margin-top: 0;
}

.doc-editor-status[b-jpv79wooq6] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.doc-editor-readonly-note[b-jpv79wooq6] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.doc-editor-readonly[b-jpv79wooq6] {
    background: var(--cpd-surface-1);
    border-radius: var(--cpd-radius-md);
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    font-size: var(--cpd-text-1);
    white-space: pre-wrap;
    word-break: break-word;
}

.doc-editor-used-by-empty[b-jpv79wooq6] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.doc-editor-leg-case[b-jpv79wooq6] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
}

.doc-editor-leg-case-row[b-jpv79wooq6] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-xs) 0;
    border-bottom: 1px solid var(--cpd-border);
}

.doc-editor-leg-case-label[b-jpv79wooq6] {
    color: var(--cpd-text-muted);
}

.doc-editor-row-readonly-field[b-jpv79wooq6] {
    display: flex;
    justify-content: space-between;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-xs) 0;
    border-bottom: 1px solid var(--cpd-border);
}

.doc-editor-row-readonly-label[b-jpv79wooq6] {
    color: var(--cpd-text-muted);
}
/* /Components/Pages/Conventions/ConventionHistory.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). */

.convention-history-status[b-x56vy0vl2p] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.convention-history-readonly-note[b-x56vy0vl2p] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
    margin-bottom: var(--cpd-space-md);
}

.convention-history-entry-header[b-x56vy0vl2p] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--cpd-space-md);
    margin-bottom: var(--cpd-space-sm);
}

.convention-history-summary[b-x56vy0vl2p] {
    font-weight: 600;
}

.convention-history-meta[b-x56vy0vl2p] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.convention-history-diff[b-x56vy0vl2p] {
    width: 100%;
    border-collapse: collapse;
}

.convention-history-diff td[b-x56vy0vl2p] {
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    font-size: var(--cpd-text-1);
    border-bottom: 1px solid var(--cpd-border);
}

.convention-history-diff-field[b-x56vy0vl2p] {
    color: var(--cpd-text-muted);
    white-space: nowrap;
}

.convention-history-diff-before[b-x56vy0vl2p] {
    color: var(--cpd-text-muted);
}

.convention-history-diff-absent[b-x56vy0vl2p] {
    color: var(--cpd-text-muted);
}
/* /Components/Pages/Conventions/ConventionRuleEditor.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). */

.rule-editor-header[b-2ptu3ziwbr] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--cpd-space-md);
}

.rule-editor-actions[b-2ptu3ziwbr] {
    display: flex;
    gap: var(--cpd-space-sm);
}

.rule-editor-note[b-2ptu3ziwbr] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
    margin-top: 0;
}

.rule-editor-status[b-2ptu3ziwbr] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.rule-editor-grid[b-2ptu3ziwbr] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--cpd-space-lg);
    align-items: start;
    margin-bottom: var(--cpd-space-lg);
}

@media (max-width: 1023.98px) {
    .rule-editor-grid[b-2ptu3ziwbr] {
        grid-template-columns: 1fr;
    }
}

.rule-editor-column[b-2ptu3ziwbr] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-md);
}

.strength-conflict[b-2ptu3ziwbr] {
    --cpd-tone-neutral: var(--cpd-text-muted);
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    border-radius: var(--cpd-radius-md);
    margin-bottom: var(--cpd-space-sm);
    background: var(--cpd-surface-1);
}

.strength-conflict.tone-attention[b-2ptu3ziwbr] {
    background: var(--cpd-gold-soft);
}

.strength-conflict-actions[b-2ptu3ziwbr] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    flex-wrap: wrap;
}

.strength-ok[b-2ptu3ziwbr] {
    padding: var(--cpd-space-sm) var(--cpd-space-md);
}

/* The left column's text boxes take the whole card width, as the Sets card's own fields do. */
.rule-card-input[b-2ptu3ziwbr] {
    width: 100%;
    box-sizing: border-box;
    font-family: inherit;
}

textarea.rule-card-input[b-2ptu3ziwbr] {
    resize: vertical;
}

.strength-conflict-actions > .rule-card-input[b-2ptu3ziwbr] {
    flex: 1 1 12rem;
    width: auto;
}

/* The Sets card's convention panel fills the card rather than sitting at its intrinsic width. */
.rule-card-sets[b-2ptu3ziwbr] {
    min-width: 0;
}

/* A stored priority's reason: a labelled text box inside the Strength card, the Author's Note's
   own control. */
.strength-priority-reason[b-2ptu3ziwbr] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

.strength-priority-reason > span[b-2ptu3ziwbr] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-0);
}
/* /Components/Pages/Conventions/Conventions.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). The chips themselves, and their tone colours, live in
   HealthPopover.razor.css; the popover surface in RulesPopover.razor.css. What is here is the
   page's own layout and the popover bodies this page authors (their scoped attribute is this
   page's, wherever the popover provider renders them). */

.conventions-json[b-n99ixio3lb] {
    padding: var(--cpd-space-md);
    background: var(--cpd-surface-inset);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-md);
    overflow: auto;
    font-family: var(--cpd-font-mono);
    font-size: var(--cpd-text-1);
}

/* ---- Health strip ------------------------------------------------------------------------- */

.conventions-health[b-n99ixio3lb] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
    margin-bottom: var(--cpd-space-lg);
}

.conventions-health-end[b-n99ixio3lb] {
    margin-left: auto;
}

.health-gap-example[b-n99ixio3lb] {
    color: var(--cpd-text-muted);
}

/* ---- Health popover bodies ---------------------------------------------------------------- */

/* A health popover's body sets its own width, a reading measure the popover surface fits (as the
   Affected Trades body does), never wider than the viewport. Not a page width (docs/ux-shape.md §18). */
.health-intro[b-n99ixio3lb],
.health-list[b-n99ixio3lb] {
    width: min(36rem, calc(100vw - 4 * var(--cpd-space-xl)));
}

.health-intro[b-n99ixio3lb] {
    margin: 0;
    color: var(--cpd-text-muted);
}

.health-list[b-n99ixio3lb] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    margin: 0;
    padding: 0;
    list-style: none;
}

.health-entry[b-n99ixio3lb] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-sm);
    background: var(--cpd-surface-2);
}

.health-entry-row[b-n99ixio3lb] {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--cpd-space-md);
}

.health-entry-main[b-n99ixio3lb] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--cpd-space-xs) var(--cpd-space-sm);
}

/* .health-entry-main also sits on an <li> (mirrored pairs), which must keep the entry's frame. */
li.health-entry-main[b-n99ixio3lb] {
    flex-direction: row;
}

.health-entry-muted[b-n99ixio3lb] {
    color: var(--cpd-text-muted);
}

.health-entry-action[b-n99ixio3lb] {
    flex: none;
}

.health-rule-link[b-n99ixio3lb] {
    padding: 0;
    border: none;
    background: none;
    color: var(--cpd-gold);
    font: inherit;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.health-rule-link:hover[b-n99ixio3lb] {
    text-decoration: underline;
}

.health-rule-link:focus-visible[b-n99ixio3lb] {
    outline: 2px solid var(--cpd-focus);
    outline-offset: 2px;
}

/* ---- Body: tree + detail panel ------------------------------------------------------------ */

.conventions-body[b-n99ixio3lb] {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: var(--cpd-space-lg);
    align-items: start;
}

@media (max-width: 1023.98px) {
    .conventions-body[b-n99ixio3lb] {
        grid-template-columns: 1fr;
    }
}

.conventions-groupby[b-n99ixio3lb] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    margin-bottom: var(--cpd-space-md);
}

.conventions-groupby-select[b-n99ixio3lb] {
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-sm);
    background: var(--cpd-surface-1);
    color: var(--cpd-text);
}

.conventions-tree[b-n99ixio3lb] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    padding: var(--cpd-space-md);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-1);
    overflow-x: auto;
}

/* Each nesting level is indented rather than laid out as a literal side-by-side column — the same
   root-to-leaf information the plan's "columns" describes, in the form a single-file page (no
   second component for the recursive node) can build against a manual RenderTreeBuilder walk. */
[b-n99ixio3lb] .tree-node {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

[b-n99ixio3lb] .tree-root {
    gap: var(--cpd-space-sm);
}

[b-n99ixio3lb] .tree-constraint {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

[b-n99ixio3lb] .tree-leaves {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-xs);
}

[b-n99ixio3lb] .tree-leaf {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-sm);
    background: var(--cpd-surface-2);
    color: var(--cpd-text);
    font-size: var(--cpd-text-1);
    cursor: pointer;
    text-align: left;
    scroll-margin: var(--cpd-space-2xl);
}

[b-n99ixio3lb] .tree-leaf.selected {
    border-color: var(--cpd-gold);
    background: var(--cpd-gold-soft);
}

[b-n99ixio3lb] .tree-leaf:focus-visible {
    outline: 2px solid var(--cpd-focus);
    outline-offset: 2px;
}

[b-n99ixio3lb] .tree-leaf-name {
    font-weight: 600;
}

[b-n99ixio3lb] .tree-leaf-sets {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-0);
}

[b-n99ixio3lb] .tree-leaf-mirrored {
    color: var(--cpd-text-subtle);
    font-size: var(--cpd-text-0);
}

[b-n99ixio3lb] .tree-children {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    padding-left: var(--cpd-space-lg);
    border-left: 1px solid var(--cpd-border);
}

/* ---- Detail panel ------------------------------------------------------------------------- */

/* The panel is a raised card and When / Sets / Reach are each an inset block on it, so the three
   read as separate surfaces in both themes (owner, 2026-10-06: "contrast of layout is lost in dark
   mode" — the old panel was --cpd-surface-1, a 2% tint, on the dark page). --cpd-surface-raised is
   the opaque per-theme pair (a step above the navy page in dark, white over ivory in light);
   --cpd-surface-2 is the contrast-flipping tint, darker than white in light and lighter than the
   raised card in dark. */
.conventions-detail[b-n99ixio3lb] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-md);
    padding: var(--cpd-space-lg);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-raised);
}

.detail-head[b-n99ixio3lb] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

.detail-name[b-n99ixio3lb] {
    margin: 0;
    font-size: var(--cpd-text-3);
}

.detail-explanation[b-n99ixio3lb],
.detail-comment[b-n99ixio3lb] {
    margin: 0;
}

.detail-comment[b-n99ixio3lb] {
    color: var(--cpd-text-muted);
}

.detail-section[b-n99ixio3lb] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-md);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-sm);
    background: var(--cpd-surface-2);
}

.detail-section-title[b-n99ixio3lb] {
    margin: 0;
    color: var(--cpd-gold);
    font-size: var(--cpd-text-0);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* The priority line sits under the When sentence, in the sentence's own size and the muted tone
   the sentence's operator words use — a reading note, not a second heading. */
.detail-priority[b-n99ixio3lb] {
    margin: 0;
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

/* One readable line per field, the same type size as the When sentence: the field in the
   sentence's bold field weight, then what the rule writes there in plain words. A shared piece's
   bindings sit under their line, indented, in the muted tone. */
.detail-sets[b-n99ixio3lb] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    font-size: var(--cpd-text-1);
}

.detail-sets-item[b-n99ixio3lb] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--cpd-space-xs) var(--cpd-space-sm);
}

.detail-sets-label[b-n99ixio3lb] {
    font-weight: 600;
}

.detail-sets-label[b-n99ixio3lb]::after {
    content: ":";
}

.detail-sets-bindings[b-n99ixio3lb] {
    flex-basis: 100%;
    list-style: none;
    margin: 0;
    padding: 0 0 0 var(--cpd-space-lg);
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    color: var(--cpd-text-muted);
}

.detail-sets-binding[b-n99ixio3lb] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-xs) var(--cpd-space-sm);
}

.detail-sets-binding-label[b-n99ixio3lb]::after {
    content: ":";
}

.detail-reach[b-n99ixio3lb] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

.detail-reach-loading[b-n99ixio3lb] {
    color: var(--cpd-text-muted);
}

.detail-actions[b-n99ixio3lb] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
}
/* /Components/Pages/Conventions/ConventionsHeader.razor.rz.scp.css */
.conventions-header[b-ikl4okli1x] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-md);
    margin-bottom: var(--cpd-page-header-mb);
}

.conventions-header-row[b-ikl4okli1x] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--cpd-space-md);
}

.conventions-header-controls[b-ikl4okli1x] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-md);
}

.conventions-tabs[b-ikl4okli1x] {
    display: flex;
    gap: var(--cpd-space-xs);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-md);
    padding: var(--cpd-space-xs);
    background: var(--cpd-surface-1);
}

.conventions-tab[b-ikl4okli1x] {
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    border-radius: var(--cpd-radius-sm);
    color: var(--cpd-text-muted);
    text-decoration: none;
}

.conventions-tab.active[b-ikl4okli1x] {
    color: var(--cpd-gold);
    background: var(--cpd-gold-soft);
}

.conventions-kind-select[b-ikl4okli1x] {
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-sm);
    background: var(--cpd-surface-1);
    color: var(--cpd-text);
}

.conventions-view-toggle[b-ikl4okli1x] {
    display: flex;
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-md);
    overflow: hidden;
}

.conventions-view-toggle button[b-ikl4okli1x] {
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    border: none;
    background: var(--cpd-surface-1);
    color: var(--cpd-text-muted);
    cursor: pointer;
}

.conventions-view-toggle button.active[b-ikl4okli1x] {
    color: var(--cpd-gold);
    background: var(--cpd-gold-soft);
}
/* /Components/Pages/Conventions/ConventionTrade.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3), mirroring Conventions.razor.css's own tone-* reuse of
   the shared --mud-palette-* variables PageRenderer.razor.css's scoped stylesheet already defines. */

/* Inputs before results, top to bottom: the mode switch, then the mode's own input, then the
   result (owner feedback, 2026-10-06). */
.convention-trade-source[b-c62fm3cya2] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--cpd-space-md);
    margin-bottom: var(--cpd-space-lg);
}

.convention-trade-source-tabs[b-c62fm3cya2] {
    display: inline-flex;
    gap: var(--cpd-space-xs);
    padding: var(--cpd-space-xs);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-surface-1);
}

.convention-trade-source-tabs button[b-c62fm3cya2] {
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    border: none;
    border-radius: var(--cpd-radius-pill);
    background: transparent;
    color: var(--cpd-text-muted);
    cursor: pointer;
}

.convention-trade-source-tabs button.active[b-c62fm3cya2] {
    background: var(--cpd-gold-soft);
    color: var(--cpd-text);
    font-weight: 600;
}

.convention-trade-source-input[b-c62fm3cya2] {
    width: 100%;
}

/* A status line, not a control: no border, no pill, no background, no pointer. The tone colours
   the icon and the words; the icon carries the state without colour. The tone colour comes from
   app.css's .tone-* rules. */
.convention-trade-status[b-c62fm3cya2] {
    --cpd-tone-neutral: var(--cpd-text-muted);
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    margin: 0 0 var(--cpd-space-xs);
    font-size: var(--cpd-text-3);
    font-weight: 600;
}

.convention-trade-hint[b-c62fm3cya2] {
    margin: 0 0 var(--cpd-space-md);
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.convention-trade-fields[b-c62fm3cya2] {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: var(--cpd-space-lg);
}

.convention-trade-fields th[b-c62fm3cya2] {
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    border-bottom: 1px solid var(--cpd-border-strong);
    color: var(--cpd-text-subtle);
    font-size: var(--cpd-text-0);
    font-weight: 600;
    text-align: left;
    text-transform: uppercase;
}

/* The whole row opens the field; the chevron and the hover say so. */
[b-c62fm3cya2] .convention-trade-field-row {
    cursor: pointer;
    transition: background var(--cpd-transition-fast);
}

[b-c62fm3cya2] .convention-trade-field-row:hover,
[b-c62fm3cya2] .convention-trade-field-row.expanded {
    background: var(--cpd-surface-hover);
}

[b-c62fm3cya2] .convention-trade-field-row td {
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    border-bottom: 1px solid var(--cpd-border);
    vertical-align: top;
}

[b-c62fm3cya2] .field-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    border: none;
    background: transparent;
    color: var(--cpd-text);
    font-weight: 600;
    text-align: left;
    cursor: pointer;
    padding: 0;
}

[b-c62fm3cya2] .field-toggle-icon {
    color: var(--cpd-text-muted);
}

[b-c62fm3cya2] .convention-trade-field-value {
    font-family: var(--cpd-font-mono);
}

[b-c62fm3cya2] .convention-trade-field-source {
    color: var(--cpd-text-muted);
}

[b-c62fm3cya2] .convention-trade-field-expanded td {
    padding: var(--cpd-space-md);
    background: var(--cpd-surface-inset);
    border-bottom: 1px solid var(--cpd-border);
}

[b-c62fm3cya2] .convention-trade-override-note {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    margin-bottom: var(--cpd-space-md);
    color: var(--mud-palette-warning);
}

[b-c62fm3cya2] .convention-trade-json-stages pre {
    padding: var(--cpd-space-md);
    background: var(--cpd-surface-inset);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-md);
    overflow: auto;
    font-family: var(--cpd-font-mono);
    font-size: var(--cpd-text-1);
}

.convention-trade-why-not[b-c62fm3cya2] {
    margin-top: var(--cpd-space-lg);
}

[b-c62fm3cya2] .convention-trade-why-not-rule {
    color: var(--cpd-gold);
    font-weight: 600;
}
/* /Components/Pages/Conventions/CriteriaSentence.razor.rz.scp.css */
.criteria-sentence[b-1h99tcky2i] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--cpd-space-xs) var(--cpd-space-sm);
    font-size: var(--cpd-text-1);
}

.criteria-any[b-1h99tcky2i] {
    color: var(--cpd-text-muted);
    font-style: italic;
}

.criteria-clause[b-1h99tcky2i] {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--cpd-space-xs);
}

.criteria-conj[b-1h99tcky2i] {
    color: var(--cpd-text-subtle);
    text-transform: uppercase;
    font-size: var(--cpd-text-0);
    letter-spacing: 0.04em;
}

.criteria-field[b-1h99tcky2i] {
    font-weight: 600;
}

.criteria-op[b-1h99tcky2i] {
    color: var(--cpd-text-muted);
}

.criteria-chip[b-1h99tcky2i] {
    padding: 0 var(--cpd-space-sm);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-surface-2);
}
/* /Components/Pages/Conventions/EditorCard.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). The Sets card's own look, generalised: what a
   `.json-section` panel is to one field, this is to one card. */

.editor-card[b-t994ubuzq3] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    min-width: 0;
    padding: var(--cpd-space-md) var(--cpd-space-lg) var(--cpd-space-lg);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-lg);
    background: var(--cpd-surface-1);
}

.editor-card-heading[b-t994ubuzq3] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    padding-bottom: var(--cpd-space-xs);
    border-bottom: 1px solid var(--cpd-gold-border);
}

.editor-card-title[b-t994ubuzq3] {
    margin: 0;
    color: var(--cpd-gold);
    font-size: var(--cpd-text-0);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
/* /Components/Pages/Conventions/FixedByCpdPopover.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). */

/* The body sets its own width, which the popover surface fits (as the Affected Trades body does),
   never wider than the viewport: the note and the entries share one measure. */
.fixed-by-cpd-note[b-fppag8we83],
.fixed-by-cpd-list[b-fppag8we83] {
    width: min(32rem, calc(100vw - 4 * var(--cpd-space-xl)));
}

.fixed-by-cpd-note[b-fppag8we83] {
    margin: 0;
    color: var(--cpd-text-muted);
}

.fixed-by-cpd-list[b-fppag8we83] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    margin: 0;
}

.fixed-by-cpd-entry[b-fppag8we83] {
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-sm);
    background: var(--cpd-surface-2);
}

.fixed-by-cpd-entry dt[b-fppag8we83] {
    font-weight: 600;
}

.fixed-by-cpd-entry dd[b-fppag8we83] {
    margin: var(--cpd-space-xs) 0 0;
}
/* /Components/Pages/Conventions/HealthPopover.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). The tone colour comes from app.css's .tone-* rules. */

.health-chip[b-7vzrrvq59l] {
    --cpd-tone-neutral: var(--cpd-text-muted);
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-surface-2);
    font-size: var(--cpd-text-1);
    cursor: pointer;
}

.health-chip:hover:not(:disabled)[b-7vzrrvq59l] {
    background: var(--cpd-surface-hover);
}

.health-chip:focus-visible[b-7vzrrvq59l] {
    outline: 2px solid var(--cpd-focus);
    outline-offset: 2px;
}

.health-chip:disabled[b-7vzrrvq59l] {
    cursor: default;
    opacity: 0.7;
}

/* The glyph sits in the same outlined badge on every chip, so "!", "✓" and "⇄" read as one
   family of status marks rather than one of them as a stray letter. */
.health-icon[b-7vzrrvq59l] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 var(--cpd-space-xs);
    border: 1px solid currentColor;
    border-radius: var(--cpd-radius-pill);
    font-size: var(--cpd-text-0);
    font-weight: 700;
    line-height: 1.4;
}

/* /Components/Pages/Conventions/ImpactPanel.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). */

.impact-panel[b-xg03e1defj] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-md);
}

.impact-tier-tag[b-xg03e1defj] {
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-surface-2);
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-0);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.impact-empty[b-xg03e1defj] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.impact-instrument-groups[b-xg03e1defj] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

.impact-instrument-example[b-xg03e1defj] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-0);
}

/* The Curves tier's chooser: one pill per reached curve, its state beside its name; the pressed
   one is the curve drawn below. */
.impact-curve-list[b-xg03e1defj] {
    list-style: none;
    margin: 0 0 var(--cpd-space-md);
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-sm);
}

.impact-curve-pick[b-xg03e1defj] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-surface-1);
    color: var(--cpd-text);
    font: inherit;
    font-size: var(--cpd-text-1);
    cursor: pointer;
    transition: border-color var(--cpd-transition-fast), background var(--cpd-transition-fast);
}

.impact-curve-pick:hover[b-xg03e1defj] {
    background: var(--cpd-surface-hover);
}

.impact-curve-pick:focus-visible[b-xg03e1defj] {
    outline: 2px solid var(--cpd-focus);
    outline-offset: 2px;
}

.impact-curve-pick[aria-pressed="true"][b-xg03e1defj] {
    border-color: var(--cpd-gold-border);
    background: var(--cpd-gold-soft);
}

.impact-curve-state[b-xg03e1defj] {
    --cpd-tone-neutral: var(--cpd-text-muted);
    font-size: var(--cpd-text-0);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.impact-curve-detail[b-xg03e1defj] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
}

.impact-curve-summary[b-xg03e1defj] {
    margin: 0;
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.impact-curve-chart[b-xg03e1defj] {
    padding: var(--cpd-space-sm) var(--cpd-space-sm) 0;
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-inset);
}

.impact-reach-counts[b-xg03e1defj] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-md);
    margin-bottom: var(--cpd-space-md);
    font-size: var(--cpd-text-1);
}

.impact-progress[b-xg03e1defj] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.impact-pv-actions[b-xg03e1defj] {
    display: flex;
    gap: var(--cpd-space-sm);
    margin: var(--cpd-space-md) 0;
}

.impact-as-of[b-xg03e1defj] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
    margin: 0 0 var(--cpd-space-sm);
}

.impact-failure-reasons[b-xg03e1defj] {
    margin: var(--cpd-space-xs) 0 0;
    padding-left: var(--cpd-space-lg);
}
/* /Components/Pages/Conventions/Lineage.razor.rz.scp.css */
.lineage[b-u3e7mgl2bm] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
    font-size: var(--cpd-text-1);
}

.lineage-rule[b-u3e7mgl2bm] {
    display: flex;
    align-items: baseline;
    gap: var(--cpd-space-sm);
}

.lineage-rule-label[b-u3e7mgl2bm],
.lineage-hop-label[b-u3e7mgl2bm],
.lineage-under-label[b-u3e7mgl2bm] {
    color: var(--cpd-text-subtle);
    text-transform: uppercase;
    font-size: var(--cpd-text-0);
    letter-spacing: 0.04em;
}

.lineage-hop[b-u3e7mgl2bm] {
    display: flex;
    align-items: baseline;
    gap: var(--cpd-space-sm);
    padding-left: var(--cpd-space-md);
}

.lineage-var[b-u3e7mgl2bm] {
    padding-left: var(--cpd-space-lg);
    color: var(--cpd-text-muted);
}

.lineage-under[b-u3e7mgl2bm] {
    margin-top: var(--cpd-space-sm);
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xs);
}

.lineage-struck[b-u3e7mgl2bm] {
    text-decoration: line-through;
    color: var(--cpd-text-subtle);
}

.lineage-default[b-u3e7mgl2bm] {
    color: var(--token-type);
}
/* /Components/Pages/Conventions/MatcherEditor.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). One block per condition, so each reads as its own
   "If · field · op · values" sentence rather than a run of controls. */

.matcher-editor[b-04bmm0y0rw] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--cpd-space-sm);
}

.matcher-caption[b-04bmm0y0rw] {
    margin: 0;
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
}

.matcher-rows[b-04bmm0y0rw] {
    list-style: none;
    margin: 0;
    padding: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
}

.matcher-row[b-04bmm0y0rw] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    padding: var(--cpd-space-sm) var(--cpd-space-md);
    border: 1px solid var(--cpd-border-strong);
    border-left: 3px solid var(--cpd-gold-border);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-1);
    min-width: 0;
}

.matcher-row:focus-within[b-04bmm0y0rw] {
    border-color: var(--cpd-gold-border);
    border-left-color: var(--cpd-gold);
}

.matcher-row-head[b-04bmm0y0rw] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
    min-width: 0;
}

.matcher-conj[b-04bmm0y0rw] {
    min-width: var(--cpd-space-2xl);
    color: var(--cpd-gold);
    font-size: var(--cpd-text-0);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* `width: auto` over the global `.form-input { width: 100% }` (sandbox-page-base.css): these sit
   in one row, not one per line. */
.matcher-field[b-04bmm0y0rw] {
    width: auto;
    flex: 1 1 12rem;
    min-width: 0;
}

.matcher-op[b-04bmm0y0rw] {
    width: auto;
    flex: 0 0 auto;
    min-width: 0;
}

.matcher-row-head[b-04bmm0y0rw]  .matcher-row-remove {
    margin-left: auto;
}

.matcher-values[b-04bmm0y0rw] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-xs) var(--cpd-space-sm);
    padding-left: calc(var(--cpd-space-2xl) + var(--cpd-space-sm));
    min-width: 0;
}

.matcher-chip[b-04bmm0y0rw] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
    padding: var(--cpd-space-xs) var(--cpd-space-sm);
    border: 1px solid var(--cpd-gold-border);
    border-radius: var(--cpd-radius-pill);
    background: var(--cpd-gold-soft);
    color: var(--cpd-text);
    font-size: var(--cpd-text-1);
    white-space: nowrap;
}

.matcher-chip-remove[b-04bmm0y0rw] {
    border: none;
    background: transparent;
    color: var(--cpd-text-muted);
    cursor: pointer;
    font-size: var(--cpd-text-2);
    line-height: 1;
    padding: 0;
}

.matcher-chip-remove:hover[b-04bmm0y0rw],
.matcher-chip-remove:focus-visible[b-04bmm0y0rw] {
    color: var(--cpd-text);
}

/* Its longest option's width; `min-width: 0` lets the wrapping row shrink it to the line when that is
   wider than the row, so no cap of its own is written. */
.matcher-value-picker[b-04bmm0y0rw] {
    width: auto;
    min-width: 0;
}

.matcher-raw-fallback[b-04bmm0y0rw] {
    padding-left: calc(var(--cpd-space-2xl) + var(--cpd-space-sm));
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-0);
}

.matcher-raw-fallback > summary[b-04bmm0y0rw] {
    cursor: pointer;
    width: fit-content;
}

.matcher-raw-entry[b-04bmm0y0rw] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    padding-top: var(--cpd-space-xs);
}

.matcher-raw-entry > input[b-04bmm0y0rw] {
    width: auto;
    flex: 1 1 auto;
    min-width: 0;
}
/* /Components/Pages/Conventions/RulesPopover.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). The surface is the opaque "raised" token, so it reads
   off the page in both themes: a step above the navy page in dark, white over ivory in light. */

.rules-popover-anchor[b-rqwqtjriul] {
    position: relative;
    display: inline-flex;
}

.rules-popover[b-rqwqtjriul] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
    /* Fits its body: each body sets its own viewport-bounded width (health, Fixed by CPD, Affected
       Trades), so the shell writes no cap of its own (docs/ux-shape.md §18). */
    min-width: 18rem;
    max-height: 70vh;
    overflow: auto;
    padding: var(--cpd-space-md) var(--cpd-space-lg);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-raised);
    color: var(--cpd-text);
    font-size: var(--cpd-text-1);
}

.rules-popover:focus[b-rqwqtjriul] {
    outline: none;
}

.rules-popover:focus-visible[b-rqwqtjriul] {
    box-shadow: 0 0 0 2px var(--cpd-focus);
}

.rules-popover-head[b-rqwqtjriul] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--cpd-space-md);
}

.rules-popover-title[b-rqwqtjriul] {
    margin: 0;
    font-size: var(--cpd-text-2);
    font-weight: 600;
}
/* /Components/Pages/Conventions/TradeBookedPicker.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md rules 1-3). */

.trade-booked-picker[b-wsgemjhly9] {
    /* The field's own width, two field measures at most; not a page width (docs/ux-shape.md §18). */
    width: min(100%, calc(2 * var(--cpd-field-max)));
}

/* The option rows render in MudPopoverProvider's portal, outside .trade-booked-picker, but they are
   this component's own markup (ItemTemplate) and so carry its scope attribute: plain selectors, no
   ::deep, which would demand a scoped ancestor the portal does not have. */
.trade-booked-option[b-wsgemjhly9] {
    display: flex;
    align-items: baseline;
    gap: var(--cpd-space-sm);
}

.trade-booked-reference[b-wsgemjhly9] {
    font-weight: 600;
}

.trade-booked-counterparty[b-wsgemjhly9],
.trade-booked-more[b-wsgemjhly9] {
    color: var(--cpd-text-muted);
}
/* /Components/Pages/CPStudioBasePage.razor.rz.scp.css */
/* Scoped styles for CPStudioBasePage's own template (header, loading overlay).
   Page-level layout primitives (.page-container, .page-title, .summary-*,
   buttons) live in wwwroot/common-page-styles.css so child pages can share
   them. */

.page-container[b-m1pfm3ys3l] {
    position: relative;
}

.loading-overlay[b-m1pfm3ys3l] {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(var(--cpd-dark-rgb), 0.95);
    backdrop-filter: blur(10px);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
}

.loading-content[b-m1pfm3ys3l] {
    text-align: center;
}

.spinner-container[b-m1pfm3ys3l] {
    margin-bottom: var(--cpd-space-2xl);
}

.spinner[b-m1pfm3ys3l] {
    width: 60px;
    height: 60px;
    border: 4px solid rgba(var(--cpd-gold-rgb), 0.2);
    border-top-color: var(--cpd-gold);
    border-radius: 50%;
    animation: spin-b-m1pfm3ys3l 1s linear infinite;
    margin: 0 auto;
}

.loading-text[b-m1pfm3ys3l] {
    color: var(--cpd-text);
    font-size: 1.1rem;
}

@keyframes spin-b-m1pfm3ys3l {
    to {
        transform: rotate(360deg);
    }
}

.option-select[b-m1pfm3ys3l] {
    padding: var(--cpd-space-sm) var(--cpd-space-lg);
    background: var(--cpd-surface-2);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-md);
    color: var(--cpd-text);
    min-width: 150px;
    transition: all var(--cpd-transition-slow);
}

.option-select:focus[b-m1pfm3ys3l] {
    outline: none;
    border-color: var(--cpd-gold);
    background: var(--cpd-surface-3);
    box-shadow: 0 0 0 3px var(--cpd-gold-ring);
}
/* /Components/Pages/Hedging/Hedges.razor.rz.scp.css */
/* The three-state load line (DECISIONS.md #53). Identical to `.recon-status` and
   `.instrument-status`, and deliberately a fourth copy rather than a shared global class: scoped CSS
   is per-component by design here, and a `.cpd-status-line` in the host's global stylesheet would
   make four WebAssembly pages depend on a host asset for their own layout — the coupling
   DECISIONS.md #50 has just finished arguing against for `@Assets`. Worth revisiting if a fifth
   page wants it; recorded as a follow-up rather than hidden. */
.hedges-status[b-sdxvaeksx2] {
    margin: 12px 0 0;
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var(--cpd-text-subtle);
}
/* /Components/Pages/Hedging/MacroHedgeDetail.razor.rz.scp.css */
/* The three-state load line (DECISIONS.md #53) — see Hedges.razor.css for why this rule is
   repeated per page rather than hoisted into a global class. */
.macro-hedge-detail-status[b-fiwv0la2r6] {
    margin: 12px 0 0;
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var(--cpd-text-subtle);
}
/* /Components/Pages/Hedging/TestDefaults.razor.rz.scp.css */
/* The three-state load line (DECISIONS.md #53) — see Hedges.razor.css for why this rule is
   repeated per page rather than hoisted into a global class. */
.test-defaults-status[b-wasil5h6ol] {
    margin: 12px 0 0;
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var(--cpd-text-subtle);
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* Tokens only (docs/ux-shape.md §1-2). The width, centring and gutter are the skeleton's
   (CPStudioBasePage Layout="Feed", entry 18); each group's card and title are PageRenderer's tile. */
.home[b-h7umtctk9b] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-xl);
}

/* .page-title (common-page-styles.css) is a centred flex row with a gap, built for an icon beside
   the title; this title is one word in two spans, left-aligned with the groups below it. */
.home .page-title[b-h7umtctk9b] {
    justify-content: flex-start;
    gap: 0;
    margin: 0;
    font-size: var(--cpd-text-4);
    font-weight: 600;
}

.home .logo-accent[b-h7umtctk9b] {
    color: var(--cpd-gold);
}

/* A group's tasks across the tile's width, as many columns as fit: a tile is the feed's full width,
   which one column of short links would leave mostly empty. */
.home-group ul[b-h7umtctk9b] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
    gap: var(--cpd-space-sm) var(--cpd-tile-gap);
}

.home-group li[b-h7umtctk9b] {
    display: flex;
    flex-direction: column;
}

.home-group a[b-h7umtctk9b] {
    color: var(--cpd-gold);
    font-weight: 500;
    text-decoration: none;
}

.home-group a:hover[b-h7umtctk9b],
.home-group a:focus-visible[b-h7umtctk9b] {
    text-decoration: underline;
}

.home-task-what[b-h7umtctk9b] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-2);
}
/* /Components/Pages/Market/InstrumentQuoteChart.razor.rz.scp.css */
.quote-chart[b-arvnr6qm0m] {
    min-height: 18rem;
    border: 1px solid var(--cpd-gold-strong);
    border-radius: var(--cpd-radius-xl);
    background: linear-gradient(135deg, rgba(var(--cpd-dark-rgb), 0.92), rgba(var(--cpd-panel-sheen-rgb), 0.92));
    padding: var(--cpd-space-md);
}

.quote-chart svg[b-arvnr6qm0m] {
    display: block;
    width: 100%;
    height: auto;
}

.axis[b-arvnr6qm0m] {
    stroke: var(--cpd-border-strong);
    stroke-width: 1;
}

.quote-line[b-arvnr6qm0m] {
    fill: none;
    stroke: var(--cpd-gold);
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.quote-point[b-arvnr6qm0m] {
    fill: var(--cpd-dark);
    stroke: var(--cpd-gold);
    stroke-width: 2;
}

.axis-label[b-arvnr6qm0m] {
    fill: var(--cpd-accent);
    font-size: 0.75rem;
}

.chart-empty[b-arvnr6qm0m] {
    min-height: 15rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    color: var(--cpd-accent);
}

.chart-empty i[b-arvnr6qm0m] {
    color: var(--cpd-gold);
}
/* /Components/Pages/Market/InstrumentSwitchOptions.razor.rz.scp.css */
.instrument-switch-options[b-j4ao4pvqrz] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-md);
    margin-bottom: var(--cpd-space-xl);
}

.instrument-switch-card[b-j4ao4pvqrz] {
    background: linear-gradient(135deg, rgba(var(--cpd-dark-rgb), 0.94), rgba(var(--cpd-panel-sheen-rgb), 0.94));
    border: 1px solid var(--cpd-gold-border);
    border-radius: var(--cpd-radius-lg);
    padding: var(--cpd-space-md);
}

.switch-label[b-j4ao4pvqrz] {
    display: block;
    color: var(--cpd-accent);
    font-size: 0.76rem;
    font-weight: 600;
    margin-bottom: var(--cpd-space-xs);
    text-transform: uppercase;
}

.hero-select[b-j4ao4pvqrz] {
    display: grid;
    grid-template-columns: minmax(12rem, 1fr) minmax(16rem, 24rem);
    gap: var(--cpd-space-md);
    align-items: center;
    border-left: 4px solid var(--cpd-gold);
}

.switch-copy[b-j4ao4pvqrz] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.switch-copy strong[b-j4ao4pvqrz] {
    color: var(--cpd-contrast);
    font-size: 1.15rem;
}

.switch-copy span:last-child[b-j4ao4pvqrz] {
    color: var(--cpd-gold);
    font-size: 0.85rem;
}

.instrument-select[b-j4ao4pvqrz] {
    width: 100%;
    min-height: 2.6rem;
    border: 1px solid var(--cpd-gold-border);
    border-radius: var(--cpd-radius-md);
    background: rgba(var(--cpd-dark-rgb), 0.88);
    color: var(--cpd-contrast);
    padding: 0.45rem 0.65rem;
}

.instrument-select-hero[b-j4ao4pvqrz] {
    border-color: var(--cpd-gold);
    box-shadow: 0 0 0 3px var(--cpd-gold-ring);
}

.instrument-select:focus-visible[b-j4ao4pvqrz] {
    outline: 2px solid var(--cpd-gold);
    outline-offset: 2px;
}

@media (max-width: 767.98px) {
    .hero-select[b-j4ao4pvqrz] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/Market/InstrumentView.razor.rz.scp.css */
.history-table[b-fj0pge35lv] {
    width: auto;
}

.history-table-container[b-fj0pge35lv] {
    background: linear-gradient(135deg, rgba(var(--cpd-dark-rgb), 0.95) 0%, rgba(var(--cpd-panel-sheen-rgb), 0.95) 100%);
    border: 1px solid var(--cpd-gold-strong);
    border-radius: var(--cpd-radius-xl);
    overflow-x: auto;
    overflow-y: visible;
    box-shadow: var(--cpd-shadow-card);
    padding: var(--cpd-space-md);
}

.history-table-container[b-fj0pge35lv]  .pagination {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 1rem;
    padding: 0.5rem 0;
}

.history-table-container[b-fj0pge35lv]  .page-item .page-link {
    background: transparent !important;
    border: 1px solid rgba(var(--cpd-gold-rgb), 0.4) !important;
    color: var(--cpd-gold) !important;
    font-weight: 500 !important;
    border-radius: var(--cpd-radius-lg) !important;
    padding: 0.4rem 0.8rem !important;
}

.history-table-container[b-fj0pge35lv]  .page-item .page-link:hover {
    background: var(--cpd-gold-ring) !important;
    border-color: var(--cpd-gold) !important;
    color: var(--cpd-contrast) !important;
}

.history-table-container[b-fj0pge35lv]  .page-item.active .page-link {
    background: var(--cpd-gold) !important;
    border-color: var(--cpd-gold) !important;
    color: var(--cpd-dark) !important;
}

.history-table-container[b-fj0pge35lv]  td,
.history-table-container[b-fj0pge35lv]  th {
    padding: 0.75rem 1rem !important;
    border: none !important;
}

.history-table-container[b-fj0pge35lv]  thead th {
    background: var(--cpd-gold-faint) !important;
    color: var(--cpd-gold) !important;
    font-weight: 600 !important;
    text-transform: uppercase !important;
    font-size: 0.85rem !important;
    letter-spacing: 0.5px !important;
    border-bottom: 2px solid var(--cpd-gold-border) !important;
}

.history-table-container[b-fj0pge35lv]  tbody td {
    color: var(--cpd-text) !important;
    background: transparent !important;
    border-bottom: 1px solid var(--cpd-border-subtle) !important;
    vertical-align: top !important;
}

.history-table-container[b-fj0pge35lv]  tbody tr:hover td {
    background: var(--cpd-gold-faint) !important;
}

.history-table-container[b-fj0pge35lv]  table {
    width: 100% !important;
    min-width: 72rem !important;
}

.history-table-container[b-fj0pge35lv]  td:not(:last-child),
.history-table-container[b-fj0pge35lv]  th:not(:last-child) {
    border-right: 1px solid var(--cpd-border-subtle) !important;
}

.history-table-container[b-fj0pge35lv]  .bb-grid-filter.btn-light {
    display: inline-flex !important;
    align-items: center !important;
    gap: 0.35rem !important;
    min-height: 2rem !important;
    border: 1px solid var(--cpd-gold-border) !important;
    border-radius: var(--cpd-radius-md) !important;
    background: rgba(var(--cpd-dark-rgb), 0.82) !important;
    color: var(--cpd-gold) !important;
    box-shadow: none !important;
    padding: 0.25rem 0.55rem !important;
}

.history-table-container[b-fj0pge35lv]  .bb-grid-filter.btn-light:hover,
.history-table-container[b-fj0pge35lv]  .bb-grid-filter.btn-light:focus {
    border-color: var(--cpd-gold) !important;
    background: var(--cpd-gold-ring) !important;
    color: var(--cpd-contrast) !important;
}

.history-table-container[b-fj0pge35lv]  .bb-grid-filter.btn-light::after {
    margin-left: 0.25rem !important;
}

.history-table-container[b-fj0pge35lv]  .dropdown-menu {
    border: 1px solid var(--cpd-gold-border) !important;
    border-radius: var(--cpd-radius-lg) !important;
    background: rgba(var(--cpd-dark-rgb), 0.98) !important;
    box-shadow: var(--cpd-shadow-card) !important;
    color: var(--cpd-text) !important;
}

.history-table-container[b-fj0pge35lv]  .dropdown-item {
    color: var(--cpd-text) !important;
}

.history-table-container[b-fj0pge35lv]  .dropdown-item:hover,
.history-table-container[b-fj0pge35lv]  .dropdown-item:focus {
    background: var(--cpd-gold-faint) !important;
    color: var(--cpd-gold) !important;
}

.quote-value[b-fj0pge35lv] {
    display: block;
    white-space: nowrap;
}

.quote-kind[b-fj0pge35lv] {
    display: inline-block;
    margin-top: 0.2rem;
    padding: 0.15rem 0.4rem;
    border: 1px solid var(--cpd-gold-border);
    border-radius: var(--cpd-radius-sm);
    color: var(--cpd-gold);
    font-size: 0.72rem;
}

.instrument-detail[b-fj0pge35lv] {
    padding: var(--cpd-space-lg);
}

.detail-header[b-fj0pge35lv] {
    display: flex;
    justify-content: space-between;
    gap: var(--cpd-space-md);
    align-items: flex-start;
    margin-bottom: var(--cpd-space-md);
}

.detail-title[b-fj0pge35lv] {
    color: var(--cpd-contrast);
    font-weight: 600;
}

.detail-subtitle[b-fj0pge35lv] {
    color: var(--cpd-accent);
    font-size: 0.85rem;
}

.detail-pill[b-fj0pge35lv] {
    color: var(--cpd-gold);
    border: 1px solid var(--cpd-gold-border);
    background: var(--cpd-gold-faint);
    border-radius: var(--cpd-radius-sm);
    padding: 0.25rem 0.5rem;
    font-size: 0.8rem;
}

.quote-instances[b-fj0pge35lv] {
    margin-top: var(--cpd-space-md);
}

.quote-instances[b-fj0pge35lv]  table {
    min-width: 24rem !important;
}

.quote-instances[b-fj0pge35lv]  .instance-table {
    width: 100%;
}

.quote-instances[b-fj0pge35lv]  td,
.quote-instances[b-fj0pge35lv]  th {
    padding: 0.6rem 0.8rem !important;
}

.quote-instances[b-fj0pge35lv]  tbody td {
    vertical-align: middle !important;
}

/* The three-state load line (DECISIONS.md #36). It is also the element the W4.6 browser smoke run
   measures a computed style on, so a CPStudio.Client.styles.css that stopped being linked
   (DECISIONS.md #39) reads as `font-size: 16px` rather than as a page that looks slightly off. */
.instrument-status[b-fj0pge35lv] {
    margin: 12px 0 0;
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var(--cpd-text-subtle);
}
/* /Components/Pages/Market/MarketView.razor.rz.scp.css */
/* The table's filters: the type chips, then the currency select, on one wrapping line in the
   table's header, left of its export cluster (CurvesView.Filters). */
.curves-filters[b-qqf77beatf] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
}

.curves-filters[b-qqf77beatf]  .curves-currency-filter {
    min-width: var(--cpd-field-min);
}
/* /Components/Pages/Market/ScheduledImports.razor.rz.scp.css */
/* MudSimpleTable's dense mode still pads cells looser than the compact
   file-listing look this page needs. Keep the 4px padding Bootstrap's
   table-sm used to give us, and restore the table's bottom margin now
   that MudBlazor renders the table inside its own container div. */
.table-responsive[b-2taem7vp0y]  .sandbox-files-table th,
.table-responsive[b-2taem7vp0y]  .sandbox-files-table td {
    padding: 4px;
}

/* Bootstrap's .table gave th font-weight 700; MudSimpleTable uses 500. These are
   dense file listings where bold headers carry the scan, so hold the old weight. */
.table-responsive[b-2taem7vp0y]  .sandbox-files-table th {
    font-weight: 700;
}

.table-responsive[b-2taem7vp0y]  .sandbox-files-table {
    margin-bottom: var(--cpd-space-lg);
}
/* /Components/Pages/Trades/Capture.razor.rz.scp.css */
.trade-topbar[b-tdw4mm6j66] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 20px;
    gap: 12px;
    flex-wrap: wrap;
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--cpd-surface-0);
    padding: 8px 0;
}

.trade-title-group[b-tdw4mm6j66] {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 32px;
}

.trade-page-title[b-tdw4mm6j66] {
    font-size: 20px;
    font-weight: 700;
    color: var(--cpd-text);
    letter-spacing: -0.03em;
}

.trade-badge[b-tdw4mm6j66] {
    font-family: var(--cpd-font-mono);
    font-size: 12px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--cpd-text-subtle);
    padding: 3px 8px;
    background: rgba(var(--cpd-contrast-rgb), 0.03);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.10);
    border-radius: 4px;
}

.trade-type-switcher[b-tdw4mm6j66] {
    display: inline-flex;
    gap: 1px;
    padding: 2px;
    background: rgba(var(--cpd-contrast-rgb), 0.03);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.08);
    border-radius: 6px;
}

.trade-type-btn[b-tdw4mm6j66] {
    font-family: var(--cpd-font-mono);
    font-size: 12px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--cpd-text-subtle);
    padding: 4px 12px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.1s, color 0.1s, border-color 0.1s;
}

.trade-type-btn:hover[b-tdw4mm6j66] {
    color: rgba(var(--cpd-contrast-rgb), calc(0.6 * var(--cpd-text-alpha-scale)));
}

.trade-type-btn.active[b-tdw4mm6j66] {
    color: var(--cpd-contrast);
    background: rgba(var(--cpd-contrast-rgb), 0.06);
    border-color: rgba(var(--cpd-contrast-rgb), 0.10);
}

.trade-meta-group[b-tdw4mm6j66] {
    display: flex;
    gap: 8px;
    align-items: center;
}

.trade-btn-go[b-tdw4mm6j66] {
    flex: 1;
    height: 44px;
    border-radius: 8px;
    background: var(--cpd-gold);
    border: none;
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--cpd-dark);
    cursor: pointer;
    transition: background 0.15s, box-shadow 0.15s, transform 0.1s;
    box-shadow: 0 2px 12px rgba(246, 212, 107, 0.15);
    position: relative;
    overflow: hidden;
}

/* Gloss sheen on the gold Go button. Deliberately a literal white, NOT
   rgba(var(--cpd-contrast-rgb), …) like every other overlay in this file: the
   button's background is --cpd-gold, which is the same gold in both themes, so
   the highlight has to lighten it in both. The contrast token would flip to a
   dark overlay in light mode and shade the button instead of glossing it. */
.trade-btn-go[b-tdw4mm6j66]::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.10) 0%, transparent 55%);
    pointer-events: none;
}

.trade-btn-go:hover[b-tdw4mm6j66] {
    background: #fad96f;
    box-shadow: 0 4px 20px rgba(246, 212, 107, 0.30);
    transform: translateY(-1px);
}

.trade-btn-go:active[b-tdw4mm6j66] {
    transform: scale(0.99);
}

.trade-btn-save[b-tdw4mm6j66] {
    height: 44px;
    padding: 0 18px;
    border-radius: 8px;
    background: transparent;
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.12);
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    color: rgba(var(--cpd-contrast-rgb), calc(0.6 * var(--cpd-text-alpha-scale)));
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
    white-space: nowrap;
}

.trade-btn-save:hover[b-tdw4mm6j66] {
    background: rgba(var(--cpd-contrast-rgb), 0.04);
    border-color: rgba(var(--cpd-contrast-rgb), 0.22);
    color: var(--cpd-contrast);
}

@media (prefers-reduced-motion: reduce) {
    *[b-tdw4mm6j66], *[b-tdw4mm6j66]::before, *[b-tdw4mm6j66]::after {
        animation: none !important;
        transition: none !important;
    }
}

.parties-group[b-tdw4mm6j66] {
    display: flex;
    gap: 8px;
    align-items: center;
}

.party-input[b-tdw4mm6j66] {
    font-family: var(--cpd-font-mono);
    font-size: 13px;
    color: var(--cpd-text);
    background: rgba(var(--cpd-contrast-rgb), 0.03);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.10);
    border-radius: 6px;
    padding: 5px 10px;
    outline: none;
    width: clamp(105px, 9.7vw, 140px);
    transition: border-color 0.15s;
}

.party-input:focus[b-tdw4mm6j66] {
    border-color: rgba(var(--cpd-contrast-rgb), 0.3);
}

.party-input[b-tdw4mm6j66]::placeholder {
    color: rgba(var(--cpd-contrast-rgb), calc(0.2 * var(--cpd-text-alpha-scale)));
}

/* The .trade-form-card block that used to sit here — every rule styling the JsonComponent
   tree inside the card — moved to wwwroot/json-form-card.css. It was scoped css applying to
   this page alone, and CurveSpecDetail renders the same markup contract. See that file. */

/* The "Trade" tile's collapsed preview: the colourised compact-grammar repr text (Phase 9 B7).
   Colours come from the global repr.css token classes; this wrapper only sets the typography. */
.trade-summary-repr[b-tdw4mm6j66] {
    font-family: var(--cpd-font-mono);
    font-size: 0.8rem;
    line-height: 1.4;
    overflow-wrap: anywhere;
}
/* /Components/Pages/Trades/Import.razor.rz.scp.css */
.import-kind-row[b-trgrfvuvxr] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-sm);
    margin-top: var(--cpd-space-md);
}

.import-kind-button[b-trgrfvuvxr] {
    border: 1px solid var(--cpd-border-strong);
    background: var(--cpd-surface-2);
    color: var(--cpd-text);
    border-radius: var(--cpd-radius-pill);
    padding: 0.45rem 0.9rem;
    transition: border-color var(--cpd-transition-fast), background var(--cpd-transition-fast), color var(--cpd-transition-fast);
}

.import-kind-button:hover:not(:disabled)[b-trgrfvuvxr] {
    border-color: var(--cpd-gold);
    background: var(--cpd-gold-tint);
}

.import-kind-button:disabled[b-trgrfvuvxr] {
    opacity: var(--cpd-disabled-opacity);
    cursor: not-allowed;
}

.import-kind-button-selected[b-trgrfvuvxr] {
    border-color: var(--cpd-gold);
    background: var(--cpd-gold-soft);
    color: var(--cpd-gold);
}

.extension-select[b-trgrfvuvxr],
.saved-script-select[b-trgrfvuvxr] {
    background: var(--cpd-surface-2);
    color: var(--cpd-text);
    border-color: var(--cpd-border-strong);
}

.extension-select[b-trgrfvuvxr] {
    max-width: 120px;
}

.extension-select:focus[b-trgrfvuvxr],
.saved-script-select:focus[b-trgrfvuvxr] {
    background: var(--cpd-surface-3);
    color: var(--cpd-text);
}

.schema-collapsible[b-trgrfvuvxr] {
    margin-top: var(--cpd-space-sm);
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-2);
}

.schema-collapsible summary[b-trgrfvuvxr] {
    cursor: pointer;
    padding: 0.5rem 0.75rem;
    color: var(--cpd-text-muted);
    font-weight: 600;
    user-select: none;
}

.schema-collapsible summary:hover[b-trgrfvuvxr] {
    color: var(--cpd-text);
}

.schema-collapsible-body[b-trgrfvuvxr] {
    border-top: 1px solid var(--cpd-border-subtle);
    padding: 0.6rem 0.75rem;
}

.schema-collapsible-body a[b-trgrfvuvxr] {
    word-break: break-word;
}

/* .sandbox-output paints --cpd-surface-2, the same colour .schema-collapsible paints, so inside this
   block the example needs the inset surface to read as a document rather than as more panel. */
.schema-example[b-trgrfvuvxr] {
    margin-top: 0;
    margin-bottom: 0;
    background: var(--cpd-surface-inset);
    font-family: var(--cpd-font-mono);
}

.schema-example-label[b-trgrfvuvxr] {
    margin: var(--cpd-space-sm) 0 0.25rem;
    color: var(--cpd-text-muted);
    font-family: var(--cpd-font-mono);
    font-size: 0.78rem;
}

.schema-caption[b-trgrfvuvxr] {
    margin: 0 0 var(--cpd-space-sm);
    color: var(--cpd-text-muted);
    font-size: 0.85rem;
}

.schema-actions[b-trgrfvuvxr] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
}

.schema-action[b-trgrfvuvxr] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    text-decoration: none;
}

/* The clipboard helper copies the value of the element data-copy-target names, and only an input or
   textarea has one. This carries the same text as the <pre> beside it and is never seen or focused. */
.schema-example-source[b-trgrfvuvxr] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
}

.python-script-hero[b-trgrfvuvxr] {
    border: 1px solid rgba(var(--cpd-gold-rgb), 0.4);
    background: linear-gradient(180deg, rgba(var(--cpd-gold-rgb), 0.14) 0%, rgba(var(--cpd-gold-rgb), 0.03) 100%);
    box-shadow: 0 0 0 1px rgba(var(--cpd-gold-rgb), 0.15), 0 12px 26px rgba(0, 0, 0, 0.18);
}

.python-script-hero > label[b-trgrfvuvxr] {
    font-size: 1.06rem;
}

.btn-execute-hero[b-trgrfvuvxr] {
    padding: 0.65rem 1.2rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    border-color: rgba(var(--cpd-gold-rgb), 0.8);
    box-shadow: 0 0 0 1px rgba(var(--cpd-gold-rgb), 0.25);
}

.output-collapse-toggle[b-trgrfvuvxr] {
    margin-top: var(--cpd-space-sm);
    margin-bottom: var(--cpd-space-sm);
}

.output-tabs[b-trgrfvuvxr] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--cpd-space-sm);
    margin-bottom: var(--cpd-space-sm);
}

.output-tab-button[b-trgrfvuvxr] {
    border: 1px solid var(--cpd-border-strong);
    background: var(--cpd-surface-2);
    color: var(--cpd-text);
    border-radius: var(--cpd-radius-pill);
    padding: 0.4rem 0.8rem;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.output-tab-button-selected[b-trgrfvuvxr] {
    border-color: var(--cpd-gold);
    background: var(--cpd-gold-soft);
    color: var(--cpd-gold);
}

.output-tab-pill[b-trgrfvuvxr] {
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    font-size: 0.7rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.output-tab-pill-error[b-trgrfvuvxr] {
    background: rgba(var(--cpd-error-rgb), 0.9);
    color: #fff;
}

.output-summary[b-trgrfvuvxr] {
    border: 1px solid var(--cpd-border-strong);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-2);
    padding: 0.65rem 0.8rem;
    margin-bottom: var(--cpd-space-sm);
}

.output-summary-title[b-trgrfvuvxr] {
    color: var(--cpd-text);
}

.output-summary-counts[b-trgrfvuvxr] {
    color: var(--cpd-text-muted);
    margin-top: 0.2rem;
}

.output-summary-messages[b-trgrfvuvxr] {
    margin: 0.45rem 0 0 1rem;
    color: var(--cpd-text);
}

.output-failed-list[b-trgrfvuvxr] {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
}

.output-failed-item[b-trgrfvuvxr] {
    border: 1px solid rgba(var(--cpd-error-rgb), 0.35);
    border-radius: var(--cpd-radius-md);
    background: rgba(var(--cpd-error-rgb), 0.08);
    padding: 0.55rem 0.7rem;
}

.output-failed-item-header[b-trgrfvuvxr] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--cpd-space-sm);
}

/* The saved-script picker (#71). It shares .extension-select's dark treatment above; what differs
   is width - a script name needs far more room than that control's 120px file-extension cap, and
   both the picker and the name field should take the row's slack rather than leave the buttons
   floating. */
.saved-script-row[b-trgrfvuvxr] {
    margin-top: var(--cpd-space-md);
}

.saved-script-select[b-trgrfvuvxr],
.saved-script-name[b-trgrfvuvxr] {
    flex: 1 1 18rem;
    min-width: 12rem;
    max-width: 32rem;
}
/* /Components/Pages/Trades/ImportGenerator.razor.rz.scp.css */
/* The row-count field that doubles as the notice that cell values go to OpenAI
   (docs/import-generator-shape.md, shape 4's 2026-09-23 amendment): label, input and notice
   stacked, with the input only as wide as a 1-25 count needs (.form-input is full-width
   everywhere else). */
.import-generator-rows[b-8o8ippu5r1] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--cpd-space-xs);
    margin: var(--cpd-space-md) 0;
}

.import-generator-rows .form-input[b-8o8ippu5r1] {
    width: auto;
}
/* /Components/Pages/Trades/View.razor.rz.scp.css */
/* The column-group switches on one line above the grid, wrapping on a narrow page rather than
   overflowing it. Tokens only (docs/ux-shape.md rules 1-3). */
.trades-run[b-m6dmpp5g0r] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm) var(--cpd-space-xl);
    margin-bottom: var(--cpd-space-lg);
}

.trades-columns[b-m6dmpp5g0r] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm) var(--cpd-space-lg);
}
/* /Components/Shared/LegalLinks.razor.rz.scp.css */
.legal-links[b-aes1xlolgi] {
    display: flex;
    gap: var(--cpd-space-xl);
    flex-wrap: wrap;
}

.legal-links-vertical[b-aes1xlolgi] {
    flex-direction: column;
    gap: 0.35rem;
}

/* Muted until hover: these are reference documents, and on every surface they appear on they
   are secondary to whatever the primary action is (signing in, navigating the app). */
.legal-links a[b-aes1xlolgi] {
    color: var(--cpd-text-muted);
    font-size: 0.8125rem;
    text-decoration: none;
    transition: color var(--cpd-transition);
}

.legal-links a:hover[b-aes1xlolgi],
.legal-links a:focus-visible[b-aes1xlolgi] {
    color: var(--cpd-gold);
    text-decoration: underline;
}
/* /Components/Tables/DataTable.razor.rz.scp.css */
/* The title row. Its shape is deliberately the same as PageRenderer's `.page-tile-header`, but it
   cannot BE that rule: PageRenderer's stylesheet is component-scoped without ::deep, so it matches
   only elements compiled into PageRenderer.razor itself. A header drawn here would simply go
   unstyled. That is the reason the header is the table's to draw rather than the caller's. */
.data-table-header[b-7gmm85ulgc] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    /* A table only as wide as its content (CRIF Files) brings the title and the actions together:
       keep them apart. */
    gap: var(--cpd-space-xl);
    margin-bottom: 0.75rem;
}

/* No title means the parent already drew one and this row carries only the cluster, which then
   belongs at the right-hand end rather than stranded at the left. */
.data-table-header-actions-only[b-7gmm85ulgc] {
    justify-content: flex-end;
}

.data-table-header-actions[b-7gmm85ulgc] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.data-table-subtitle[b-7gmm85ulgc] {
    color: var(--cpd-text-subtle);
}

/* The clipboard status line, under the table where the design puts it. It is empty until a copy
   succeeds, so it must not reserve a line of height; aria-live announces it when it fills. */
.data-table-status[b-7gmm85ulgc] {
    display: block;
    margin-top: 0.375rem;
    font-size: 0.75rem;
    color: var(--cpd-text-subtle);
}

/* ------------------------------------------------------------------
   The grid rules below are copies of PageRenderer.razor.css's, for the same reason the header rules
   are: those are scoped to PageRenderer and a DataTable rendered anywhere else - a page that draws
   its own table rather than a Page description - would lose them. Inside PageRenderer both sets
   match and agree, so the duplication is inert there. Keep the two in step. */

[b-7gmm85ulgc] .page-grid {
    width: 100%;
    border-collapse: collapse;
}

/* The row's icon buttons are one horizontal cluster, never a stack: without nowrap they wrap inside
   the content-sized sticky column and quadruple every row's height. */
[b-7gmm85ulgc] .page-grid-row-controls {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.125rem;
}

/* A sticky column floats over the cells it covers and needs its own opaque background, and the
   selector has to repeat MudBlazor's own shape (0,4,0 beats its 0,3,0) or its grey default wins on
   specificity regardless of source order. Don't shorten this. */
[b-7gmm85ulgc] .mud-data-grid .mud-table-cell.sticky-right.page-grid-controls-header,
[b-7gmm85ulgc] .mud-data-grid .mud-table-cell.sticky-right.page-grid-controls-cell {
    background-color: var(--cpd-surface-table);
    border-left: 1px solid var(--mud-palette-table-lines);
}

/* A row state's tint is translucent (the hover wash is gold at 6%), so painting it alone would let
   the cells scrolled under the column show through (Workspaces' Created, 2026-10-14). It is layered
   as an image over the opaque surface above, which stays: a new row state adds its tint here the
   same way, never as a background-color. */
[b-7gmm85ulgc] .mud-table-row:hover .mud-table-cell.sticky-right.page-grid-controls-cell {
    background-image: linear-gradient(var(--cpd-row-hover), var(--cpd-row-hover));
}

/* The add-row affordance sits directly under the grid it grows, not centred with it and not flush
   against its own top border — a small gap and left alignment read as "belongs to the table above",
   the same relationship the status line has to the export cluster. */
.data-table-add-row[b-7gmm85ulgc] {
    margin-top: 0.375rem;
    text-align: left;
}

/* A cell that carries a reason (TableColumn.Hint): a dotted underline says "there is more here"
   without a second glyph competing with the figure. The span is focusable, so it gets a visible
   focus ring of its own. ::deep because the span sits inside MudDataGrid's own markup. */
[b-7gmm85ulgc] .cpd-cell-hint {
    text-decoration: underline dotted;
    text-underline-offset: 0.2em;
    cursor: help;
}

[b-7gmm85ulgc] .cpd-cell-hint:focus-visible {
    outline: 2px solid var(--cpd-gold);
    outline-offset: 2px;
    border-radius: var(--cpd-radius-sm);
}

/* A tinted column (TableColumn.Tint): the tile family's class on its header, body and total cells
   points --tile-tint and --tile-tint-edge at the family's pair (app.css), so one rule here styles
   every family — the tint behind the cell and its edge inset down the left — and the cell's content
   is the table's own, a failed figure's reason included (docs/ux-shape.md §10, §22). The figures
   take weight, as the tile's own do. ::deep because the cells are MudDataGrid's own markup. */
[b-7gmm85ulgc] .mud-table-cell[class*="tile-tint--"] {
    background: var(--tile-tint);
    box-shadow: inset 2px 0 0 var(--tile-tint-edge);
}

[b-7gmm85ulgc] .mud-table-body .mud-table-cell[class*="tile-tint--"] {
    font-weight: 600;
}

/* The total row (DataTable.Total): in the grid's footer, so no sort or filter moves it, and set off
   from the rows above it by a rule and weight rather than a colour, which stays the column's tone.
   ::deep because the cell is MudDataGrid's own markup. */
[b-7gmm85ulgc] .mud-table-foot .mud-table-cell.data-table-total-cell {
    border-top: 2px solid var(--mud-palette-table-lines);
    font-weight: 600;
}
/* /Components/Tables/TableCompactView.razor.rz.scp.css */
/* Every colour here is a --cpd-* token rather than the mock's literal hex: the app is already
   tokenised and renders in both light and dark, and a hard-coded panel colour is invisible in one
   of the two. */

.table-compact-text[b-jjhjfdkdsf] {
    display: block;
    width: 100%;
    min-height: 290px;
    box-sizing: border-box;
    padding: 12px 14px;
    font-family: var(--cpd-font-mono);
    font-size: 13px;
    line-height: 1.6;
    color: var(--cpd-text);
    background: rgba(var(--cpd-contrast-rgb), 0.03);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.1);
    border-radius: 6px;
    /* pre, not pre-wrap: a wrapped CSV row stops looking like a row, and the whole reason to show
       the text is that its shape is readable. It scrolls sideways instead. */
    white-space: pre;
    overflow: auto;
    resize: vertical;
}

.table-compact-text:focus[b-jjhjfdkdsf] {
    outline: none;
    /* The mock's gold focus ring, taken from the token rather than its literal hex. */
    border-color: var(--cpd-gold-border);
    box-shadow: 0 0 0 2px var(--cpd-gold-ring);
}

.table-compact-footer[b-jjhjfdkdsf] {
    margin-top: 0.5rem;
    font-size: 0.75rem;
    color: var(--cpd-text-subtle);
}
/* /Components/Tables/TableToolbar.razor.rz.scp.css */
/* Layout only. Every button in here is styled by wwwroot/trade-mode-switcher.css, which App.razor
   loads globally, beside the shared DetailSlider (detail-slider.css) - the cluster has to look like
   every other toolbar cluster, and the way to guarantee that is to share the rules rather than
   echo them. */

.table-toolbar[b-bolsuz8uhy] {
    display: flex;
    align-items: center;
    gap: 8px;
}

.table-toolbar-status[b-bolsuz8uhy] {
    font-size: 0.75rem;
    color: var(--cpd-text-subtle);
}
/* /Components/TileRunState.razor.rz.scp.css */
/* The disabled button takes no pointer events; the wrapper is what shows its title. */
.tile-run-state-run[b-gjz5pqs4k5] {
    display: inline-flex;
}
/* /Components/Tiles/DetailPane.razor.rz.scp.css */
/* Heading / inner-container look lifted from XvaSection.razor.css. */
.detail-pane[b-75l95eko29] {
    margin-bottom: 24px;
}

.detail-pane-header[b-75l95eko29] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

/* A tinted pane (TileTints.CssClass on the root; the .tile-tint--* rules in app.css set
   --tile-tint and --tile-tint-edge): its tile's edge down the left, and its tint as a band behind
   the header, so the open tile and its pane read as one family (docs/ux-shape.md §22). An untinted
   pane matches neither rule and keeps the plain look. */
.detail-pane[class*="tile-tint--"][b-75l95eko29] {
    border-left: 3px solid var(--tile-tint-edge);
    padding-left: var(--cpd-space-sm);
}

.detail-pane[class*="tile-tint--"] .detail-pane-header[b-75l95eko29] {
    background: var(--tile-tint);
    border-radius: 0 var(--cpd-radius-lg) var(--cpd-radius-lg) 0;
    padding: var(--cpd-space-sm) var(--cpd-space-md);
}

.detail-pane-title[b-75l95eko29] {
    font-size: 14px;
    font-weight: 600;
    color: rgba(var(--cpd-contrast-rgb), calc(0.8 * var(--cpd-text-alpha-scale)));
    margin: 0 0 4px;
}

.detail-pane-subtitle[b-75l95eko29] {
    font-size: 11px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
    margin: 0;
}

.detail-pane-header-actions[b-75l95eko29] {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

.detail-pane-close[b-75l95eko29] {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.12);
    border-radius: var(--cpd-radius-lg);
    color: rgba(var(--cpd-contrast-rgb), calc(0.5 * var(--cpd-text-alpha-scale)));
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.detail-pane-close:hover[b-75l95eko29] {
    color: var(--cpd-contrast);
    border-color: rgba(var(--cpd-contrast-rgb), 0.25);
    background: rgba(var(--cpd-contrast-rgb), 0.04);
}

/* min-width:0 + overflow-x lets wide MudDataGrids scroll instead of stretching the column. */
.detail-pane-body[b-75l95eko29] {
    min-width: 0;
    overflow-x: auto;
    background: rgba(var(--cpd-contrast-rgb), 0.02);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.07);
    border-radius: var(--cpd-radius-lg);
    padding: var(--cpd-tile-pad);
}

/* A pane opened by the reader takes focus (tabindex="-1", cpdScrollIntoView.reveal). After a mouse
   open that needs no ring; after a keyboard open it gets the same gold ring a focusable table cell
   has (DataTable.razor.css, .cpd-cell-hint). */
.detail-pane:focus:not(:focus-visible)[b-75l95eko29] {
    outline: none;
}

.detail-pane:focus-visible[b-75l95eko29] {
    outline: 2px solid var(--cpd-gold);
    outline-offset: 2px;
    border-radius: var(--cpd-radius-sm);
}
/* /Components/Tiles/MissingMarketData.razor.rz.scp.css */
.missing-data-msg[b-2mgzgn5nls] {
    font-size: 12px;
    color: var(--cpd-text-subtle);
}

.missing-data-title[b-2mgzgn5nls] {
    margin-bottom: 8px;
}

.missing-data-list[b-2mgzgn5nls] {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.missing-data-list li[b-2mgzgn5nls] {
    display: flex;
    gap: 8px;
}

.missing-data-tag[b-2mgzgn5nls] {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
    white-space: nowrap;
}

.missing-data-items[b-2mgzgn5nls] {
    font-family: var(--cpd-font-mono);
    color: rgba(var(--cpd-contrast-rgb), calc(0.55 * var(--cpd-text-alpha-scale)));
}
/* /Components/Tiles/SummaryTile.razor.rz.scp.css */
/* Card base lifted from Capture's .results-card; hover + chevron from XvaTile.
   The left border is the active-tile indicator: the tile family's edge, gold for an untinted tile. */
.summary-tile[b-vpw0b5g3nf] {
    background: rgba(var(--cpd-contrast-rgb), 0.03);
    border: 1px solid rgba(var(--cpd-contrast-rgb), 0.07);
    border-left: 3px solid transparent;
    border-radius: var(--cpd-radius-lg);
    padding: var(--cpd-tile-pad);
    cursor: pointer;
    /* The tile is the query container its BODY components size themselves against: XvaTile's and
       SensitivityTile's stat grids drop from two columns to one below ~240px of tile width
       (@container rules in their own stylesheets). A container query rather than a media query
       because what changes here is the tile's width - the right rail narrows when the density
       preference flips, and the whole page reflows when the sidebar expands over it - neither of
       which the viewport width can see. inline-size, not size: the tile's height is its
       content's, and `container-type: size` would make it depend on an unset height instead. */
    container-type: inline-size;
    transition: border-color 0.15s, background 0.15s;
    user-select: none;
    /* The state band is drawn against the tile's own box, and clipped to its rounded corners. */
    position: relative;
    overflow: hidden;
}

.summary-tile:hover[b-vpw0b5g3nf] {
    background: rgba(var(--cpd-contrast-rgb), 0.06);
    border-color: rgba(var(--cpd-contrast-rgb), 0.14);
}

/* Declared after :hover so the active edge persists while hovering. A tinted tile's class
   (TileTints.CssClass, the .tile-tint--* rules in app.css) sets --tile-tint and --tile-tint-edge;
   an untinted tile has neither and keeps the gold edge and its plain background. */
.summary-tile.active[b-vpw0b5g3nf] {
    border-left-color: var(--tile-tint-edge, var(--cpd-gold));
}

.summary-tile.active[class*="tile-tint--"][b-vpw0b5g3nf] {
    background: var(--tile-tint);
}

.summary-tile-header[b-vpw0b5g3nf] {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.summary-tile-title[b-vpw0b5g3nf] {
    flex: 1;
    min-width: 0;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--cpd-text-subtle);
}

.summary-tile-chevron[b-vpw0b5g3nf] {
    font-size: 12px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.3 * var(--cpd-text-alpha-scale)));
    transition: transform 0.2s;
}

.summary-tile-chevron.active[b-vpw0b5g3nf] {
    transform: rotate(180deg);
}

.summary-tile-body[b-vpw0b5g3nf] {
    margin-top: 12px;
}

/* Optional header controls (e.g. XvaTile's simulation-settings gear), sitting between the title and
   the chevron. `margin-left: auto` keeps the title left and this cluster hard against the chevron
   even though the header is a space-between flex row. Carries no padding of its own, so a caller
   that renders nothing into the slot leaves the header pixel-identical. */
.summary-tile-actions[b-vpw0b5g3nf] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: auto;
}

/* ---------- Tile state (docs/ux-shape.md §6, "Tile style") ----------
   One colour role per state, from the status tokens: running is the gold of work in flight, stale and
   incomplete the warning amber, failed the error red. Every state also has words in the header and a
   band pattern, so it is never colour alone. */
.tile-state--running[b-vpw0b5g3nf] {
    --tile-state-ink: var(--cpd-gold);
}

.tile-state--stale[b-vpw0b5g3nf],
.tile-state--incomplete[b-vpw0b5g3nf] {
    --tile-state-ink: var(--cpd-warning);
}

.tile-state--failed[b-vpw0b5g3nf] {
    --tile-state-ink: var(--cpd-error);
}

/* The 4px band along the top edge: a sweep while running, hatching when stale, a fill to the
   computed share when incomplete, solid when failed. */
.tile-band[b-vpw0b5g3nf] {
    position: absolute;
    inset: 0 0 auto 0;
    height: 4px;
    background: var(--tile-state-ink);
}

.tile-state--running .tile-band[b-vpw0b5g3nf] {
    background:
        linear-gradient(90deg, transparent, var(--tile-state-ink), transparent) no-repeat,
        color-mix(in srgb, var(--tile-state-ink) 15%, transparent);
    background-size: 50% 100%, 100% 100%;
    animation: tile-sweep-b-vpw0b5g3nf 1.4s linear infinite;
}

.tile-state--stale .tile-band[b-vpw0b5g3nf] {
    background: repeating-linear-gradient(135deg, var(--tile-state-ink) 0 5px, transparent 5px 9px);
}

.tile-state--incomplete .tile-band[b-vpw0b5g3nf] {
    background: linear-gradient(90deg, var(--tile-state-ink) var(--tile-progress, 50%), color-mix(in srgb, var(--tile-state-ink) 20%, transparent) var(--tile-progress, 50%));
}

@keyframes tile-sweep-b-vpw0b5g3nf {
    from {
        background-position: -50% 0, 0 0;
    }

    to {
        background-position: 150% 0, 0 0;
    }
}

.tile-state-word[b-vpw0b5g3nf] {
    flex: none;
    margin-left: var(--cpd-space-sm);
    font-size: var(--cpd-text-0);
    font-weight: 600;
    white-space: nowrap;
    color: var(--tile-state-ink);
}

@media (prefers-reduced-motion: reduce) {
    .tile-band[b-vpw0b5g3nf] {
        animation: none !important;
    }
}
/* /Components/Trades/CashFlowGrid.razor.rz.scp.css */
.history-table-container[b-um9q8b8rx0] {
    margin: 2rem 0;
}

.history-table-container[b-um9q8b8rx0]  .pagination {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 1rem;
    padding: 0.5rem 0;
}

.history-table-container[b-um9q8b8rx0]  .page-item .page-link {
    background: transparent !important;
    border: 1px solid rgba(var(--cpd-gold-rgb), 0.4) !important;
    color: var(--cpd-gold) !important;
    font-weight: 500 !important;
    border-radius: var(--cpd-radius-lg) !important;
    padding: 0.4rem 0.8rem !important;
    transition: all 0.2s ease-in-out;
}

.history-table-container[b-um9q8b8rx0]  .page-item .page-link:hover {
    background: var(--cpd-gold-ring) !important;
    border-color: var(--cpd-gold) !important;
    color: var(--cpd-contrast) !important;
}

.history-table-container[b-um9q8b8rx0]  .page-item.active .page-link {
    background: var(--cpd-gold) !important;
    border-color: var(--cpd-gold) !important;
    color: var(--cpd-dark) !important;
    font-weight: 600 !important;
}

.history-table-container[b-um9q8b8rx0]  .page-item.disabled .page-link {
    opacity: 0.4 !important;
    cursor: not-allowed !important;
}

.history-table-container[b-um9q8b8rx0]  td,
.history-table-container[b-um9q8b8rx0]  th {
    padding: 0.75rem 1rem !important;
    border: none !important;
}

.history-table-container[b-um9q8b8rx0]  td:first-child,
.history-table-container[b-um9q8b8rx0]  th:first-child {
    padding-left: 1.25rem !important;
}

.history-table-container[b-um9q8b8rx0]  td:last-child,
.history-table-container[b-um9q8b8rx0]  th:last-child {
    padding-right: 1.25rem !important;
}

.history-table-container[b-um9q8b8rx0]  thead th {
    background: var(--cpd-dark) !important;
    color: var(--cpd-gold) !important;
    font-weight: 600 !important;
    text-transform: uppercase !important;
    font-size: 0.9rem !important;
    letter-spacing: 0.5px !important;
    border-bottom: 2px solid var(--cpd-gold-border) !important;
    padding-top: 0.85rem !important;
    padding-bottom: 0.85rem !important;
    position: sticky !important;
    top: 0 !important;
    z-index: 10 !important;
}

.history-table-container[b-um9q8b8rx0]  tbody td {
    color: var(--cpd-text) !important;
    background: transparent !important;
    border-bottom: 1px solid var(--cpd-border-subtle) !important;
    padding-top: 0.2rem !important;
    padding-bottom: 0.2rem !important;
}

.history-table-container[b-um9q8b8rx0]  tbody tr:hover td {
    background: rgba(var(--cpd-gold-rgb), 0.05) !important;
}

.history-table-container[b-um9q8b8rx0]  table {
    width: 100% !important;
}

/* Notional and Expected Value: a figure and its currency, and the value's ƒx trigger, on one line. */
.history-table-container[b-um9q8b8rx0]  td:nth-child(3),
.history-table-container[b-um9q8b8rx0]  th:nth-child(3),
.history-table-container[b-um9q8b8rx0]  td:nth-child(4),
.history-table-container[b-um9q8b8rx0]  th:nth-child(4) {
    white-space: nowrap !important;
}

.history-table-container[b-um9q8b8rx0]  .cash-flow-value {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
}

.history-table-container[b-um9q8b8rx0]  td:not(:last-child),
.history-table-container[b-um9q8b8rx0]  th:not(:last-child) {
    border-right: 1px solid var(--cpd-border-subtle) !important;
    padding-right: 1rem !important;
}

.history-table-container[b-um9q8b8rx0]  .action-buttons {
    display: flex !important;
    gap: 0.5rem !important;
}

.history-table-container[b-um9q8b8rx0]  .table-sm > :not(caption) > * > * {
    padding: 0.75rem 1rem !important;
}

.history-table-container[b-um9q8b8rx0]  .bb-grid-row > div,
.history-table-container[b-um9q8b8rx0]  .grid-row > div {
    padding: 0.75rem 1rem !important;
}

.history-table-container[b-um9q8b8rx0]  .bb-grid table td,
.history-table-container[b-um9q8b8rx0]  .bb-grid table th {
    padding: 0.75rem 1rem !important;
}
/* /Components/Trades/ClientXvaSimSettingsDialog.razor.rz.scp.css */
/* "Simulation settings": the dialog's Body is drawn by BodyView (XvaSimSettingsView), which lays out
   its control groups (BodyView.razor.css). What is the dialog's own: its parts one under the other
   with a gap between them (a page's Stack sits in a tile that spaces it), and, because the dialog is
   narrower than a page pane, a settings row's fields share the row equally instead of wrapping at the
   field's minimum width. ::deep because BodyView's markup is its own file's. */

.sim-settings-body[b-tp66baylzf]  .page-stack {
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-md);
}

.sim-settings-body[b-tp66baylzf]  .page-control-group > * {
    flex-basis: 0;
    min-width: 0;
}

/* The accrual-rule editor (a plain JsonComponent, not Mud), set apart as the rule's own panel. */
.sim-rule-panel[b-tp66baylzf] {
    padding: var(--cpd-space-md);
    background: var(--cpd-surface-inset);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-sm);
}
/* /Components/Trades/FormulaDialog.razor.rz.scp.css */
/* The descend dialog for an explorable cash-flow formula (docs/formula-shape.md). No colour,
   spacing or font-size literal here — only var(--cpd-*) / var(--formula-*) references and 0. */

/* Title, then Back/Forward beside it: history is navigation of the whole dialog, so it sits in the
   dialog's own header rather than above the formula it moves. */
.formula-dialog-title[b-mqz5ie70tu] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-xs);
}

/* The equation is centred while it fits and scrolls from its left edge once it does not: an auto
   inline margin centres a flex child but, unlike `justify-content: center`, never pushes its start
   out of the scroll range. */
.formula-dialog-equation[b-mqz5ie70tu] {
    display: flex;
    align-items: center;
    gap: var(--cpd-space-sm);
    width: max-content;
    margin-inline: auto;
}

/* The value carries `class="num"` and nothing else: the app-wide figure shape (one formatter plus
   a `.num` class carrying tabular figures, the mono face and right alignment) does not exist yet
   and is principle-tier work, so the class is written to pick the real `.num` up on the day it
   lands. The symbol table's value column is the one marked exception (docs/formula-shape.md). */

/* A deep formula scrolls inside this container and never widens the dialog (ux rule 9). The block
   padding is room for MathML's ink: a fraction bar and its descenders extend a pixel past the math
   box, and a container that scrolls sideways must also scroll vertically (CSS forbids `visible`
   beside `auto`), so without it a one-pixel vertical scrollbar appeared beside every fraction. */
.formula-dialog-formula-scroll[b-mqz5ie70tu] {
    display: flex;
    overflow-x: auto;
    padding-block: var(--cpd-space-xs);
    margin-bottom: var(--cpd-space-md);
}

/* The formula this dialog exists to show is display maths, at every depth. Inline MathML is
   `math-style: compact`, which shrinks each nested fraction a step, so a forward rate — a fraction
   inside a fraction — drew its discount factors at 5px in the browser pass (2026-09-22). `normal`
   on the root alone protects only the outermost fraction: MathML makes each fraction's children
   compact again, so it is set on every descendant. Subscripts and superscripts still shrink, as
   they should; only fractions stop shrinking. The symbol table's formulas are studied the same way,
   so they get it too. The grid keeps compact inline maths: its rows are dense, and a row formula is
   read at a glance, not studied. */
.formula-dialog-formula-scroll[b-mqz5ie70tu]  math,
.formula-dialog-formula-scroll[b-mqz5ie70tu]  math *,
.formula-dialog-symbols[b-mqz5ie70tu]  math,
.formula-dialog-symbols[b-mqz5ie70tu]  math * {
    math-style: normal;
}

/* The symbol table: Symbol and Value shrink to their widest entry and the formula takes the rest.
   `width: 0` plus `nowrap` is the auto-table-layout idiom for "as narrow as the content allows".
   Anchored through `.mud-table-root … .mud-table-cell` because MudBlazor's own cell rule is three
   classes deep and a shorter selector loses to it. */
.formula-dialog-symbols[b-mqz5ie70tu]  .mud-table-root .mud-table-cell:nth-child(1),
.formula-dialog-symbols[b-mqz5ie70tu]  .mud-table-root .mud-table-cell:nth-child(2) {
    width: 0;
    white-space: nowrap;
}

/* MudBlazor's dense cell pads 24px on the right and 16px on the left, so two narrow columns side by
   side sat 40px apart, a gap wider than most symbols. Between Symbol and Value only the small step
   remains. */
.formula-dialog-symbols[b-mqz5ie70tu]  .mud-table-root .mud-table-cell:nth-child(1) {
    padding-inline-end: var(--cpd-space-sm);
}

.formula-dialog-symbols[b-mqz5ie70tu]  .mud-table-root .mud-table-cell:nth-child(2) {
    padding-inline-start: var(--cpd-space-sm);
}

/* Values are padded to a common tail (FormulaDialog.AlignOnPoint), so in a fixed-width face the
   right-aligned column lines up on the decimal point. Exception: a local figure face, see
   docs/formula-shape.md. */
.formula-dialog-symbols[b-mqz5ie70tu]  .formula-dialog-figure {
    font-family: var(--cpd-font-mono);
    font-variant-numeric: tabular-nums;
    white-space: pre;
}

/* The line a fetched formula shows until it arrives (ShowPendingAsync): quiet, in the muted text
   colour, where the equation will be. */
.formula-dialog-pending[b-mqz5ie70tu] {
    margin: 0;
    padding: var(--cpd-space-md) 0;
    color: var(--cpd-text-muted);
}
/* /Components/Trades/FormulaView.razor.rz.scp.css */
/* Explorable cash-flow formulas (docs/formula-shape.md). The formula's own symbols come from a
   `MarkupString` (Real.FormatHtml), so they never get the `b-xxxxxxxxxx` scope attribute Blazor's
   CSS isolation stamps onto Razor-emitted elements — only the root `<span data-formula-view>` does.
   Every rule below therefore reaches through `::deep`, anchored on that root, rather than matching
   `[data-symbol]`/`[data-kind]` directly. */

.formula-view[b-zl92lypsde]  [data-symbol][data-descend] {
    cursor: pointer;
}

.formula-view[b-zl92lypsde]  [data-symbol][data-descend]:hover,
.formula-view[b-zl92lypsde]  [data-symbol][data-descend]:focus {
    text-decoration: underline dotted;
}

.formula-view[b-zl92lypsde]  [data-kind="i"],
.formula-view[b-zl92lypsde]  [data-kind="f"],
.formula-view[b-zl92lypsde]  [data-kind="r"],
.formula-view[b-zl92lypsde]  [data-kind="s"] {
    color: rgb(var(--formula-rate-rgb));
}

.formula-view[b-zl92lypsde]  [data-kind="V"] {
    color: rgb(var(--formula-discount-rgb));
}

.formula-view[b-zl92lypsde]  [data-kind="N"],
.formula-view[b-zl92lypsde]  [data-kind="amount"],
.formula-view[b-zl92lypsde]  [data-kind="pv"] {
    color: rgb(var(--formula-amount-rgb));
}

.formula-view[b-zl92lypsde]  [data-kind="Q"],
.formula-view[b-zl92lypsde]  [data-kind="S₀"],
.formula-view[b-zl92lypsde]  [data-kind="X"] {
    color: rgb(var(--formula-quote-rgb));
}

.formula-view[b-zl92lypsde]  [data-kind="∂"],
.formula-view[b-zl92lypsde]  [data-kind="date"],
.formula-view[b-zl92lypsde]  [data-kind="from"],
.formula-view[b-zl92lypsde]  [data-kind="to"],
.formula-view[b-zl92lypsde]  [data-kind="holiday"] {
    color: rgb(var(--formula-time-rgb));
}

.formula-view[b-zl92lypsde]  [data-kind="σ²"] {
    color: rgb(var(--formula-variance-rgb));
}

.formula-view[b-zl92lypsde]  [data-kind="k"],
.formula-view[b-zl92lypsde]  [data-kind="w"],
.formula-view[b-zl92lypsde]  [data-kind="given"],
.formula-view[b-zl92lypsde]  [data-kind="residual"] {
    color: rgb(var(--formula-structure-rgb));
}

/* The margin engines' symbols (CPDelta.Simm.Label, CPDelta.Frtb.Label): a CRIF input as an amount,
   a correlation as structure, every other calibration entry as a quote, and the working as the
   discount token, a quadratic form's rows (`ρ·WS`, Labeller.RowPrefix) included. FormulaViewTests fails when an engine kind has no rule here. */
.formula-view[b-zl92lypsde]  [data-kind="crif"] {
    color: rgb(var(--formula-amount-rgb));
}

.formula-view[b-zl92lypsde]  [data-kind="ρ"],
.formula-view[b-zl92lypsde]  [data-kind="φ"],
.formula-view[b-zl92lypsde]  [data-kind="γ"],
.formula-view[b-zl92lypsde]  [data-kind="ψ"] {
    color: rgb(var(--formula-structure-rgb));
}

.formula-view[b-zl92lypsde]  [data-kind="RW"],
.formula-view[b-zl92lypsde]  [data-kind="T"],
.formula-view[b-zl92lypsde]  [data-kind="VRW"],
.formula-view[b-zl92lypsde]  [data-kind="HVR"],
.formula-view[b-zl92lypsde]  [data-kind="SF"],
.formula-view[b-zl92lypsde]  [data-kind="VS"],
.formula-view[b-zl92lypsde]  [data-kind="α"],
.formula-view[b-zl92lypsde]  [data-kind="LGD"],
.formula-view[b-zl92lypsde]  [data-kind="Grid"] {
    color: rgb(var(--formula-quote-rgb));
}

.formula-view[b-zl92lypsde]  [data-kind="WS"],
.formula-view[b-zl92lypsde]  [data-kind="CVR"],
.formula-view[b-zl92lypsde]  [data-kind="CR"],
.formula-view[b-zl92lypsde]  [data-kind="K"],
.formula-view[b-zl92lypsde]  [data-kind="Σ"],
.formula-view[b-zl92lypsde]  [data-kind="S"],
.formula-view[b-zl92lypsde]  [data-kind="θ"],
.formula-view[b-zl92lypsde]  [data-kind="λ"],
.formula-view[b-zl92lypsde]  [data-kind="margin"],
.formula-view[b-zl92lypsde]  [data-kind="IM"],
.formula-view[b-zl92lypsde]  [data-kind="MS"],
.formula-view[b-zl92lypsde]  [data-kind="AddIM"],
.formula-view[b-zl92lypsde]  [data-kind="SIMM"],
.formula-view[b-zl92lypsde]  [data-kind="M"],
.formula-view[b-zl92lypsde]  [data-kind="JTD"],
.formula-view[b-zl92lypsde]  [data-kind="JTDnet"],
.formula-view[b-zl92lypsde]  [data-kind="HBR"],
.formula-view[b-zl92lypsde]  [data-kind="WtL"],
.formula-view[b-zl92lypsde]  [data-kind="WtS"],
.formula-view[b-zl92lypsde]  [data-kind="SBM"],
.formula-view[b-zl92lypsde]  [data-kind="DRC"],
.formula-view[b-zl92lypsde]  [data-kind="RRAO"],
.formula-view[b-zl92lypsde]  [data-kind="FRTB"],
.formula-view[b-zl92lypsde]  [data-kind="GIM"],
.formula-view[b-zl92lypsde]  [data-kind="GRC"],
.formula-view[b-zl92lypsde]  [data-kind="NRC"],
.formula-view[b-zl92lypsde]  [data-kind="NGR"],
.formula-view[b-zl92lypsde]  [data-kind="ScheduleIM"],
.formula-view[b-zl92lypsde]  [data-kind^="ρ·"] {
    color: rgb(var(--formula-discount-rgb));
}
/* /Components/Trades/PricingDetail.razor.rz.scp.css */
.pricing-rows[b-mutnb3b6ju] {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.pricing-row[b-mutnb3b6ju] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 4px 0;
}

.pricing-row-emphasis[b-mutnb3b6ju] {
    margin-top: 4px;
    padding-top: 10px;
    border-top: 1px solid rgba(var(--cpd-contrast-rgb), 0.08);
}

.pricing-label[b-mutnb3b6ju] {
    font-size: 11px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--cpd-text-subtle);
}

.pricing-value[b-mutnb3b6ju] {
    font-family: var(--cpd-font-mono);
    font-size: 1.1rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.val-positive[b-mutnb3b6ju] { color: var(--token-rate); }
.val-negative[b-mutnb3b6ju] { color: var(--token-position); }

.pricing-ccy-table[b-mutnb3b6ju] {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
    margin-top: 20px;
    font-size: 11px;
}

.pricing-ccy-table th[b-mutnb3b6ju] {
    font-size: 9px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
    padding: 5px 8px;
    border-bottom: 1px solid rgba(var(--cpd-contrast-rgb), 0.08);
    text-align: right;
}

.pricing-ccy-table th:first-child[b-mutnb3b6ju] { text-align: left; }

.pricing-header-hint[b-mutnb3b6ju] {
    cursor: help;
    text-decoration: underline dotted;
    text-underline-offset: 2px;
}

.pricing-ccy-table td[b-mutnb3b6ju] {
    padding: 4px 8px;
    color: rgba(var(--cpd-contrast-rgb), calc(0.65 * var(--cpd-text-alpha-scale)));
    border-bottom: 1px solid rgba(var(--cpd-contrast-rgb), 0.03);
    font-family: var(--cpd-font-mono);
    text-align: right;
}

.pricing-ccy-table td.ccy-cell[b-mutnb3b6ju] {
    text-align: left;
    color: rgba(var(--cpd-contrast-rgb), calc(0.45 * var(--cpd-text-alpha-scale)));
}

.pricing-ccy-table td.date-cell[b-mutnb3b6ju] { white-space: nowrap; }
/* /Components/Trades/SensitivitySection.razor.rz.scp.css */
/* The risk ladder pane: controls, notes line, view switch, one DataTable per section. DetailPane
   provides the surrounding heading and card; DataTable brings its own table treatment, and the sign
   colour comes from the shared tone-* classes (ToneMapping), so nothing here colours a figure. */

.sensitivity-controls[b-z1kt4497a5] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-md);
    margin-bottom: var(--cpd-space-lg);
}

.sensitivity-control-label[b-z1kt4497a5] {
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-subtle);
}

.sensitivity-measure-switcher[b-z1kt4497a5],
.sensitivity-view-switcher[b-z1kt4497a5] {
    width: fit-content;
}

.sensitivity-view-switcher[b-z1kt4497a5] {
    margin-bottom: var(--cpd-space-md);
}

/* .trade-mode-btn (trade-mode-switcher.css, global) is a fixed square sized for single-glyph icon
   buttons. These switchers carry words ("Par", "Zero", "Ladder", "Table"), so each button sizes to
   its label instead, without touching the shared icon-button sizing other switchers depend on. */
.sensitivity-measure-switcher .trade-mode-btn[b-z1kt4497a5],
.sensitivity-view-switcher .trade-mode-btn[b-z1kt4497a5] {
    width: auto;
    height: auto;
    padding: var(--cpd-space-xs) var(--cpd-space-md);
    font-size: var(--cpd-text-0);
    white-space: nowrap;
}

.sensitivity-notes[b-z1kt4497a5] {
    margin-bottom: var(--cpd-space-md);
    font-size: var(--cpd-text-0);
}

.sensitivity-notes > summary[b-z1kt4497a5] {
    cursor: pointer;
}

.sensitivity-notes-list[b-z1kt4497a5] {
    margin: var(--cpd-space-xs) 0 var(--cpd-space-sm);
    padding-left: var(--cpd-space-lg);
    color: var(--cpd-text-subtle);
}

.sensitivity-notes-explain[b-z1kt4497a5] {
    margin: 0;
    color: var(--cpd-text-subtle);
}

.sensitivity-theta-definition[b-z1kt4497a5] {
    margin: 0 0 var(--cpd-space-md);
    font-size: var(--cpd-text-0);
    color: var(--cpd-text-subtle);
}

.sensitivity-group-title[b-z1kt4497a5] {
    font-size: var(--cpd-text-0);
    font-weight: 600;
    margin: var(--cpd-space-sm) 0 var(--cpd-space-xs);
}

.sensitivity-group[b-z1kt4497a5] {
    margin-bottom: var(--cpd-space-lg);
}

.sensitivity-line-detail[b-z1kt4497a5] {
    margin-top: var(--cpd-space-sm);
}

.sensitivity-cross-gamma > summary[b-z1kt4497a5] {
    cursor: pointer;
    font-size: var(--cpd-text-1);
}

.sensitivity-share[b-z1kt4497a5] {
    display: inline-flex;
    align-items: center;
    gap: var(--cpd-space-xs);
}

.sensitivity-share-value[b-z1kt4497a5] {
    color: var(--cpd-text-subtle);
}

.sensitivity-bar-track[b-z1kt4497a5] {
    display: inline-block;
    width: 5rem;
    height: var(--cpd-space-xs);
    background: rgba(var(--cpd-contrast-rgb), 0.06);
    border-radius: var(--cpd-radius-sm);
    overflow: hidden;
}

.sensitivity-bar-fill[b-z1kt4497a5] {
    display: block;
    height: 100%;
    background: currentcolor;
}

.sensitivity-not-run[b-z1kt4497a5] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-md);
}

.sensitivity-missing-msg[b-z1kt4497a5] {
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-subtle);
}
/* /Components/Trades/XvaExposureChart.razor.rz.scp.css */
/* Series colours for the EE/EPE/ENE exposure profile.
   Kept as channel triplets rather than hexes so every stroke and fill that
   names a series derives from one value each — an earlier version spelled
   every colour twice (#a78bfa and rgba(167, 139, 250, …)) and the two had to
   be kept in step by hand.

   Both themes are written out because these are different colours, not a flip
   of one: the dark set is the pastel Tailwind-400 family, which lands at
   1.7:1–2.6:1 against the ivory light background (--cpd-dark in light mode) and
   reads as barely-there wash. The light set is the -700 family, 4.6:1–5.6:1.
   3:1 is the floor for graphical objects, so the dark set is not merely
   unattractive in light mode, it's below contrast minimum.

   These are local to this component on purpose — no other chart in the app
   uses this palette (checked), so there's nothing to share with. */
.xva-chart[b-k088jml0oe] {
    --xva-ee-rgb: 167, 139, 250;
    --xva-epe-rgb: 52, 211, 153;
    --xva-ene-rgb: 248, 113, 113;

    /* The frame is the shared chart block's (.cpd-chart, app.css); this chart keeps its own
       spacing, which predates the spacing scale. */
    padding: 0.6rem;
    margin-top: 16px;
    margin-bottom: 16px;
}

:root[data-cpd-theme="light"] .xva-chart[b-k088jml0oe] {
    --xva-ee-rgb: 109, 40, 217;
    --xva-epe-rgb: 4, 120, 87;
    --xva-ene-rgb: 185, 28, 28;
}

/* Series differ by dash as well as colour, so a reader who cannot tell the
   colours apart still can: EE solid, EPE dashed, ENE dotted. The legend's
   samples carry these same classes. */
.series-line[b-k088jml0oe] {
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.series-line.ee[b-k088jml0oe] { stroke: rgb(var(--xva-ee-rgb)); }
.series-line.epe[b-k088jml0oe] { stroke: rgb(var(--xva-epe-rgb)); stroke-dasharray: 8 5; }
.series-line.ene[b-k088jml0oe] { stroke: rgb(var(--xva-ene-rgb)); stroke-dasharray: 1 5; }

/* Expected IM to collect and to post: the chart's own slots (--cpd-series-im-*, app.css, validated
   with EE, EPE and ENE), a step thinner than the exposures, and each with a dash of its own — long
   dash and dash-dot — so no two of the five lines share a stroke. */
.series-line.im-collect[b-k088jml0oe] { stroke: var(--cpd-series-im-collect); stroke-width: 1.5; stroke-dasharray: 14 4; }
.series-line.im-post[b-k088jml0oe] { stroke: var(--cpd-series-im-post); stroke-width: 1.5; stroke-dasharray: 8 3 2 3; }

/* The before-the-flow and interval columns of the readout, quieter than the value. */
.xva-readout-quiet[b-k088jml0oe] {
    fill: var(--cpd-text-subtle);
}

.chart-hover-dot.ee[b-k088jml0oe] { fill: rgb(var(--xva-ee-rgb)); }
.chart-hover-dot.epe[b-k088jml0oe] { fill: rgb(var(--xva-epe-rgb)); }
.chart-hover-dot.ene[b-k088jml0oe] { fill: rgb(var(--xva-ene-rgb)); }
.chart-hover-dot.im-collect[b-k088jml0oe] { fill: var(--cpd-series-im-collect); }
.chart-hover-dot.im-post[b-k088jml0oe] { fill: var(--cpd-series-im-post); }

.legend-label[b-k088jml0oe] {
    fill: rgba(var(--cpd-contrast-rgb), calc(0.6 * var(--cpd-text-alpha-scale)));
    font-size: var(--cpd-text-0);
}
