@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);
}

.margin-header[b-r1zd08fz8v] {
    display: flex;
    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-spacer[b-r1zd08fz8v] {
    flex: 1 1 auto;
}

.margin-header-label[b-r1zd08fz8v] {
    font-size: var(--cpd-text-0);
    text-transform: uppercase;
    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] {
    display: flex;
    align-items: baseline;
    gap: var(--cpd-space-sm);
    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] {
    flex-shrink: 0;
    width: var(--cpd-space-lg);
    text-align: center;
    color: var(--cpd-text-muted);
}

.margin-label[b-r1zd08fz8v] {
    flex: 1 1 auto;
    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);
}
/* /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;
}
/* /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. */

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

.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)));
}

/* A partial total: some trades are not in the figures. The headline is rendered outside the page
   renderer too (trade capture), where the renderer's ::deep tone classes do not reach, so the
   attention colour is stated here for this one use. */
.xva-stat-se.tone-attention[b-8c5a526d9p] {
    color: var(--cpd-warning);
}
/* /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/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%;
}

.save-bar-unsaved[b-3f84yurr4j] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-2);
    white-space: nowrap;
}

.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/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 derived counterpart sits beside the input on its text baseline, muted: it is read-only and
   comes from the typed term (docs/ux-shape.md entry 19). */
.term-input[b-madfggbf9a] {
    display: flex;
    align-items: baseline;
    gap: var(--cpd-space-sm);
}

.term-input-derived[b-madfggbf9a] {
    color: var(--cpd-text-muted);
    font-size: var(--cpd-text-1);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* /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 with its calendar button, 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]  .date-field {
    min-width: 17ch;
}

.deal-leg[b-eiq0weu1i4]  .date-field 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 with its calendar button, 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]  .date-field {
    min-width: 17ch;
}

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

.deal-leg[b-1x06w2pc35]  input.form-input.deal-number {
    width: 16ch;
    min-width: 16ch;
    text-align: right;
}
/* /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. Its fields flow
   below it like any section's. */
.leg-adjust > summary[b-xx6p5lm9yn] {
    cursor: pointer;
    font-size: var(--cpd-text-1);
    color: var(--cpd-text-muted);
}

.leg-adjust[open] > summary[b-xx6p5lm9yn] {
    margin-bottom: var(--cpd-space-sm);
}
/* /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/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/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 MainLayout.razor.css's, 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 .top-row, 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 (MainLayout.razor.css names .top-row "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/Layout/ValuationDateBar.razor.rz.scp.css */
/* The disabled bar's reason, for assistive technology: MudBlazor points the picker's
   aria-describedby at its helper text, and sighted users get the same sentence as the bar's tooltip
   (title). Visually hidden rather than display:none, which would drop it from the accessibility tree
   too — and hidden at all so the top bar keeps its one-line height. */
.valuation-date-bar--unused[b-r8kin8c4j3]  .mud-input-helper-text {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}
/* /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;
}

.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;
}

/* 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-draft-notice[b-uzh1xax85z] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--cpd-space-sm);
}

.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;
}
/* /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);
}

.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/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/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/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;
}

/* 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. */
.page-tile[b-hj3k3nuptm] {
    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);
}

.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 (`article.content` in MainLayout.razor.css) 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/flat tiles 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-key-values-row {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
}

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

/* Body.ControlGroup is a short field set (a Designation pane's three fields, a Details pane's
   legal name + recovery rate) — it had no CSS at all, so its MudTextField/MudSelect/MudNumericField
   children stacked one per line like a long form instead of sitting together as the short row they
   are. A wrapping flex row is the fix everywhere at once: fields sit side by side on a normal
   desktop width, and drop to their own line only when the row genuinely runs out of room, rather
   than every page hand-rolling its own MudStack/MudGrid wrapper for this. This is now the layout
   contract for every form section in the app — no per-page CSS should be needed on top of it. */
[b-hj3k3nuptm] .page-control-group {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--cpd-tile-gap);
}

/* --cpd-field-min matches .page-field-select's own min-width 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), so the pair keeps that relationship at either density. */
[b-hj3k3nuptm] .page-control-group > * {
    flex: 1 1 var(--cpd-field-min);
    max-width: var(--cpd-field-max);
}

[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(--mud-palette-surface);
    border-left: 1px solid var(--mud-palette-table-lines);
}

[b-hj3k3nuptm] .mud-table-row:hover .mud-table-cell.sticky-right.page-grid-controls-cell {
    background-color: var(--mud-palette-table-hover);
}

[b-hj3k3nuptm] .tone-good {
    color: var(--mud-palette-success, #2e7d32);
}

[b-hj3k3nuptm] .tone-attention {
    color: var(--mud-palette-warning, #ed6c02);
}

[b-hj3k3nuptm] .tone-bad {
    color: var(--mud-palette-error, #d32f2f);
}

[b-hj3k3nuptm] .tone-neutral {
    color: inherit;
}

/* 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/Pages/Admin/Environments.razor.rz.scp.css */
/* The comparison is a second table under the first: the page's tile gap between them, so the two
   read as two things rather than one table continuing. */
.environments-comparison[b-3wesffr3t5] {
    margin-top: var(--cpd-tile-gap);
}
/* /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-date-input[b-aehpfswsl6] {
    background: transparent;
    border: none;
    color: var(--cpd-contrast);
    padding: 0;
    font-family: var(--cpd-font-mono);
    font-size: 13px;
}

.recon-date-input:focus[b-aehpfswsl6] {
    outline: none;
}

.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/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/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). */
.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);
}

.home-groups[b-h7umtctk9b] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
    gap: var(--cpd-tile-gap);
}

.home-group[b-h7umtctk9b] {
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-md);
    background: var(--cpd-surface-1);
    padding: var(--cpd-tile-pad);
}

.home-group-title[b-h7umtctk9b] {
    margin: 0 0 var(--cpd-space-sm);
    font-size: var(--cpd-text-0);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--cpd-text-muted);
}

.home-group ul[b-h7umtctk9b] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--cpd-space-sm);
}

.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);
}

.home-empty[b-h7umtctk9b] {
    color: var(--cpd-text-muted);
}
/* /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 Add curve. */
.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);
}

.extension-select option[b-trgrfvuvxr],
.saved-script-select option[b-trgrfvuvxr] {
    background: rgba(6, 18, 33);
    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/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(--mud-palette-surface);
    border-left: 1px solid var(--mud-palette-table-lines);
}

[b-7gmm85ulgc] .mud-table-row:hover .mud-table-cell.sticky-right.page-grid-controls-cell {
    background-color: var(--mud-palette-table-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);
}
/* /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;
}

/* The clipboard source elements. Off-screen rather than display:none, because the Clipboard path
   reads `.value` from the live element and a control that is not laid out at all is a weaker
   guarantee than one that is simply somewhere nobody looks. Fixed positioning keeps them out of
   every ancestor's scroll extent, so they can never widen a table or produce a stray scrollbar. */
.table-toolbar-source[b-bolsuz8uhy] {
    position: fixed;
    top: 0;
    left: -10000px;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.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);
}
/* /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;
}

.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] {
    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;
}
/* /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;
    min-width: 900px !important;
}

.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]  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" — design handoff §5. The dialog shell and fields are MudBlazor; only the
   disclosed accrual-rule panel (a plain JsonComponent, not Mud) still needs its own styling. Same
   rule as CPStudio.FrontEnd's XvaSimSettingsDialog.razor.css, for the same panel. */

.sim-rule-panel[b-tp66baylzf] {
    /* Indented past the checkbox so the rule reads as that row's detail. */
    margin-left: 25px;
    padding: 12px;
    background: var(--cpd-surface-inset);
    border: 1px solid var(--cpd-border);
    border-radius: var(--cpd-radius-sm);
}

/* StoppingRuleCaption is injected as raw HTML via @((MarkupString)...), so it never gets this
   file's scope attribute — ::deep drops the scoping restriction to reach it anyway. */
[b-tp66baylzf] .sim-caption-value {
    font-family: var(--cpd-font-mono);
    font-weight: 600;
    color: var(--cpd-gold);
}
/* /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;
}
/* /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],
.formula-view[data-whole][b-zl92lypsde] {
    cursor: pointer;
}

/* A whole-view control fills its cell, so the click target is the cell rather than the ink. */
.formula-view[data-whole][b-zl92lypsde] {
    display: block;
}

.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));
}
/* /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-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-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-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 the solid strokes and the
   0.4-alpha error bars/whiskers derive from one value each — the previous
   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;

    border: 1px solid var(--cpd-gold-border);
    border-radius: var(--cpd-radius-lg);
    background: rgba(var(--cpd-contrast-rgb), 0.03);
    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;
}

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

.axis[b-k088jml0oe] {
    stroke: rgba(var(--cpd-contrast-rgb), 0.12);
    stroke-width: 1;
}

.zero-line[b-k088jml0oe] {
    stroke: rgba(var(--cpd-contrast-rgb), 0.15);
    stroke-width: 1;
    stroke-dasharray: 4 4;
}

.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)); }
.series-line.ene[b-k088jml0oe] { stroke: rgb(var(--xva-ene-rgb)); }

.err-bar[b-k088jml0oe] {
    stroke-width: 1;
}

.err-bar.ee[b-k088jml0oe] { stroke: rgba(var(--xva-ee-rgb), 0.4); }
.err-bar.epe[b-k088jml0oe] { stroke: rgba(var(--xva-epe-rgb), 0.4); }
.err-bar.ene[b-k088jml0oe] { stroke: rgba(var(--xva-ene-rgb), 0.4); }

.err-whisker[b-k088jml0oe] {
    stroke-width: 1;
}

.err-whisker.ee[b-k088jml0oe] { stroke: rgba(var(--xva-ee-rgb), 0.4); }
.err-whisker.epe[b-k088jml0oe] { stroke: rgba(var(--xva-epe-rgb), 0.4); }
.err-whisker.ene[b-k088jml0oe] { stroke: rgba(var(--xva-ene-rgb), 0.4); }

.series-pt[b-k088jml0oe] {
    fill: var(--cpd-dark, #0f1117);
    stroke-width: 1.5;
}

.series-pt.ee[b-k088jml0oe] { stroke: rgb(var(--xva-ee-rgb)); }
.series-pt.epe[b-k088jml0oe] { stroke: rgb(var(--xva-epe-rgb)); }
.series-pt.ene[b-k088jml0oe] { stroke: rgb(var(--xva-ene-rgb)); }

/* Cum-flow markers (left limit V(tᵢ⁻)) are filled to distinguish them from the hollow ex-flow points. */
.series-pt.cum.ee[b-k088jml0oe] { fill: rgb(var(--xva-ee-rgb)); }
.series-pt.cum.epe[b-k088jml0oe] { fill: rgb(var(--xva-epe-rgb)); }
.series-pt.cum.ene[b-k088jml0oe] { fill: rgb(var(--xva-ene-rgb)); }

.axis-label[b-k088jml0oe] {
    fill: rgba(var(--cpd-contrast-rgb), calc(0.35 * var(--cpd-text-alpha-scale)));
    font-size: 0.65rem;
}

.legend-swatch[b-k088jml0oe] {
    rx: 2;
}

.legend-swatch.ee[b-k088jml0oe] { fill: rgb(var(--xva-ee-rgb)); }
.legend-swatch.epe[b-k088jml0oe] { fill: rgb(var(--xva-epe-rgb)); }
.legend-swatch.ene[b-k088jml0oe] { fill: rgb(var(--xva-ene-rgb)); }

.legend-label[b-k088jml0oe] {
    fill: rgba(var(--cpd-contrast-rgb), calc(0.5 * var(--cpd-text-alpha-scale)));
    font-size: 0.65rem;
}
