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

/* The optional two-column flat-tile layout (PageRenderer.RailTileIds): a fixed-width capture rail
   beside a column that takes whatever is left. minmax(0, 1fr) rather than 1fr on the main column so
   a wide child that cannot shrink (a schedule grid, an SVG chart) scrolls inside its own tile
   instead of forcing the whole grid wider and pushing the rail off-screen — the classic
   grid-blowout. The rail collapses to a full-width row on narrow viewports, where a 330px gutter
   plus a results column is unreadable; 1100px is where the results column stops fitting a
   twelve-column schedule grid. */
.page-renderer-rail-layout[b-hj3k3nuptm] {
    display: grid;
    grid-template-columns: 330px minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
}

.page-renderer-rail[b-hj3k3nuptm],
.page-renderer-rail-main[b-hj3k3nuptm] {
    min-width: 0;
}

@media (max-width: 1100px) {
    .page-renderer-rail-layout[b-hj3k3nuptm] {
        grid-template-columns: minmax(0, 1fr);
    }
}

.page-tile-pane-layout[b-hj3k3nuptm] {
    display: flex;
    gap: var(--cpd-tile-gap);
    align-items: flex-start;
}

.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] {
    flex: 0 0 var(--cpd-pane-rail-w);
    display: flex;
    flex-direction: column;
    gap: var(--cpd-tile-gap);
}

/* When the pane layout has under ~1000px the 280px rail plus a detail pane no longer fit:
   the summary tiles become a wrapping strip ABOVE the detail pane instead. This is a
   container query, not a media query, so it also fires when the sidebar expands. */
@container page-renderer (max-width: 999.98px) {
    /* align-items has to be overridden, not just the direction. The row layout sets
       `flex-start` so the rail does not stretch to the detail pane's height; in COLUMN mode that
       same value is a cross-axis WIDTH constraint, so both children shrink-to-fit and the strip
       of summary tiles collapsed to ~28px wide - one word per line. Stretch is the column
       equivalent of what flex-start meant in a row. */
    .page-tile-pane-layout[b-hj3k3nuptm] { flex-direction: column; align-items: stretch; }
    .page-tile-pane-right[b-hj3k3nuptm]  { order: -1; flex: none; flex-direction: row; flex-wrap: wrap; }

    /* SummaryTile's root .summary-tile, 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; }
}

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

.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/SummaryTile.razor.rz.scp.css */
/* Card base lifted from Capture's .results-card; hover + chevron from XvaTile.
   The gold left border is the active-tile indicator. */
.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 gold left border persists while hovering. */
.summary-tile.active[b-vpw0b5g3nf] {
    border-left-color: var(--cpd-gold);
}

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