/* /Breakdown/Components/StatBreakdown.razor.rz.scp.css */
/* Stat breakdown renderer — the per-stat decomposition tree.
   Ported from project/frontend/src/components/StatBreakdown.vue.
   See openspec/changes/archive/ (search "blazor-stat-breakdown-ui"; design D12).

   Layout only — colours, delta accents, and tabular-nums come from global
   utility classes / design tokens. Descendant selectors use ::deep because the
   tree's rows are rendered by child components. The --depth custom property
   carries each row's nesting level for indentation. */

.stat-breakdown[b-1ey8k0n6if] {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    height: 100%;
    overflow-y: auto;
    padding: 0.75rem;
    font-size: 0.8125rem;

    /* Fade the top and bottom edges so rows dissolve into the card border while
       scrolling instead of clipping hard against it. */
    --scroll-fade: 0.75rem;
    mask-image: linear-gradient(
        to bottom,
        transparent 0,
        black var(--scroll-fade),
        black calc(100% - var(--scroll-fade)),
        transparent 100%
    );
}

/* ── Rows ───────────────────────────────────────────────────────────────── */

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row {
    display: flex;
    align-items: center;
    width: 100%;
    gap: 0.25rem;
    padding: 0.1875rem 0.5rem;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--header {
    background: none;
    border: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--header:hover {
    background: var(--color-surface-sunken);
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--cluster {
    background: var(--color-surface-sunken);
    border-radius: var(--radius);
    font-family: var(--font-display);
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--cluster:hover {
    filter: brightness(1.1);
}

/* ── Node framing ───────────────────────────────────────────────────────── */

.stat-breakdown[b-1ey8k0n6if]  .breakdown-node--cluster > .breakdown-node__body {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.25rem;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-node--stat {
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-node--stat > .breakdown-node__body {
    border-top: 1px solid var(--color-line);
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--stat.is-expanded {
    background: var(--color-surface-sunken);
}

/* ── Label cell ─────────────────────────────────────────────────────────── */

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row__label {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding-left: calc(var(--depth, 0) * 0.75rem);
}

/* Rows with no chevron pad to align their text under header-row text. */
.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--leaf .breakdown-row__label,
.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--summary .breakdown-row__label,
.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--group-label .breakdown-row__label {
    padding-left: calc(var(--depth, 0) * 0.75rem + 1.125rem);
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-chevron {
    display: inline-block;
    width: 0.875rem;
    flex-shrink: 0;
    font-size: 0.6875rem;
    color: var(--color-content-subtle);
}

/* ── Value cells ────────────────────────────────────────────────────────── */

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row__trailing {
    display: flex;
    flex-shrink: 0;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-cell {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.1875rem;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-cell--left {
    width: 5rem;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-cell--right {
    width: 6.5rem;
    padding-right: 0.25rem;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-delta {
    font-size: 0.625rem;
    font-weight: 700;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-count {
    margin-right: 0.25rem;
    color: var(--color-content-subtle);
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-instance-toggle {
    padding: 0;
    background: none;
    border: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-instance-toggle:hover {
    text-decoration: underline;
}

/* ── Subordinate stats ──────────────────────────────────────────────────── */

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--subordinate {
    font-size: 0.75rem;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--subordinate .breakdown-row__label {
    padding-left: calc((var(--depth, 0) + 1) * 0.75rem);
    color: var(--color-content-muted);
}

/* ── Accents ────────────────────────────────────────────────────────────── */

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--ghost,
.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--instance {
    color: var(--color-content-subtle);
    font-style: italic;
}

.stat-breakdown[b-1ey8k0n6if]  .breakdown-row--group-label {
    color: var(--color-content-muted);
    font-weight: 600;
}
/* /DesignSystem/Chip.razor.rz.scp.css */
/* Chip — labelled token with a trailing remove control. */

.chip[b-jumesp2bi9] {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0 0.25rem;
    border-radius: var(--radius-md);
    background: var(--color-surface-muted);
    border: 1px solid var(--color-line-strong);
    color: var(--color-content);
    font-size: 0.75rem;
    line-height: 1.25rem;
}

.chip__label[b-jumesp2bi9] {
    white-space: nowrap;
}

.chip__remove[b-jumesp2bi9] {
    flex-shrink: 0;
    padding: 0;
    background: transparent;
    border: none;
    cursor: pointer;
    line-height: 1;
    color: var(--color-content-muted);
}

.chip__remove:hover[b-jumesp2bi9],
.chip__remove:focus-visible[b-jumesp2bi9] {
    color: var(--color-content);
}
/* /DesignSystem/HoverLabel.razor.rz.scp.css */
/* HoverLabel — CSS-only hover reveal of a single-line label, placed above the
   trigger via position:fixed + CSS anchor positioning so it floats clear of any
   overflow-clipping ancestor and flips at the viewport edge. Plain-label chrome
   in tokens — no card elevation (that is Tooltip's job). */

.hover-label[b-un286uvykl] {
    display: inline-flex;
}

.hover-label__text[b-un286uvykl] {
    /* Anchor name is set inline per instance (see HoverLabel.razor); the anchor
       is always this label's own wrapper. Placed above the trigger, flipping
       below / to the side when it would otherwise leave the viewport. */
    position: fixed;
    position-area: top right;
    position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
    z-index: 50;
    margin-bottom: 0.25rem;
    padding: 0.125rem 0.375rem;
    background: var(--color-surface-raised);
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    font-family: var(--font-ui);
    font-size: 0.6875rem;
    line-height: 1.2;
    white-space: nowrap;
    color: var(--color-content);
    /* display toggle (not visibility) so the hidden box contributes no scroll
       width — a visibility:hidden box stays in layout and widens the page. */
    display: none;
    pointer-events: none;
}

.hover-label:hover .hover-label__text[b-un286uvykl] {
    display: block;
}
/* /DesignSystem/SmartEnumTypeahead.razor.rz.scp.css */
/* SmartEnumTypeahead — a typeahead-filtered generic SmartEnum input. The suggestion list overlays
   following content while open; the values selected so far render as chips below it. */

.smart-enum-typeahead[b-woyhox3e1a] {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.relative[b-woyhox3e1a] {
    position: relative;
}

.typeahead-list[b-woyhox3e1a] {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 10;
    margin: 0.125rem 0 0;
    padding: 0.25rem;
    list-style: none;
    max-height: 12rem;
    overflow-y: auto;
    background: var(--color-surface-raised);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}

.typeahead-option[b-woyhox3e1a] {
    display: block;
    width: 100%;
    padding: 0.25rem 0.5rem;
    border-radius: var(--radius-md);
    text-align: left;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--color-content);
}

    .typeahead-option:hover[b-woyhox3e1a],
    .typeahead-option:focus-visible[b-woyhox3e1a] {
        background: var(--color-surface-muted);
    }
/* /DesignSystem/Tooltip.razor.rz.scp.css */
/* Tooltip — CSS-only hover reveal placed above the trigger
   via position:fixed + CSS anchor positioning, so it floats clear of any
   overflow-clipping ancestor and flips at the viewport edge. Surface
   (background, border, radius, elevation) is all tokens. */

.tooltip[b-c7fw40vfm6] {
    display: inline-block;
}

.tooltip__content[b-c7fw40vfm6] {
    /* Anchor name is set inline per instance (see Tooltip.razor); the anchor is
       always this content's own wrapper. Placed above the trigger, flipping below
       / to the side when it would otherwise leave the viewport. */
    position: fixed;
    position-area: top span-left;
    position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
    z-index: 50;
    margin-bottom: 0.25rem;
    min-width: max-content;
    padding: 0.75rem;
    background: var(--color-surface-raised);
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    /* display toggle (not visibility) so the hidden box contributes no scroll
       width — a visibility:hidden box stays in layout and widens the page. */
    display: none;
    pointer-events: none;
}

.tooltip:hover .tooltip__content[b-c7fw40vfm6] {
    display: block;
}
/* /Layout/Planner/LoadoutPicker.razor.rz.scp.css */
/* LoadoutPicker — horizontal strip above the planner body. Two labelled
   dropdowns and a Manage button laid out in a single row. */

.loadout-picker[b-xq3fyk5w7y] {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 1rem;
    flex: 0 0 auto;
    padding: 1rem;          /* card surface needs inner spacing */
}

/* Sizes each dropdown to share the row evenly; the position identifies it. */
.loadout-picker__field[b-xq3fyk5w7y] {
    display: flex;
    flex: 1;
    min-width: 0;
}

.loadout-picker__field > .input[b-xq3fyk5w7y] {
    flex: 1;
    min-width: 0;
}
/* /Layout/Planner/MainArea.razor.rz.scp.css */
/* MainArea — transparent flex region. The gear panel mounts as a child and
   carries its own .card surface. */

.main-area[b-wtfe3ylkoh] {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: auto;
    padding: 0.5rem;        /* gutter so the gear panel's card shadow renders
                               instead of being clipped at this scroll edge */
}
/* /Layout/Planner/PlannerPage.razor.rz.scp.css */
/* PlannerPage — composes the planner's four regions.

   Outer .planner is a flex row containing the rail and the rest. The "rest"
   stacks the top strip above the body row (main area + right column). All
   four regions share the height made available by app-shell__view; the
   footer sits below at app-shell level. */

.planner[b-tijoaa5uj1] {
    display: flex;
    flex-direction: row;
    height: 100%;
    min-height: 0;
}

.planner__right[b-tijoaa5uj1] {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 1rem;          /* matches Vue's <main class="...p-4"> */
    gap: 1rem;              /* matches Vue header's mb-4 separation */
    overflow: hidden;
}

.planner__body[b-tijoaa5uj1] {
    flex: 1;
    min-height: 0;
    width: 100%;
    max-width: 103rem;      /* gear panel (1180px) + per-column shadow gutters
                               (1rem) + gap (0.5rem) + right stack (28rem) — keeps
                               both columns grouped so wider screens grow the
                               outer margins, not the gap */
    margin-inline: auto;
    display: flex;
    flex-direction: row;
    gap: 0.5rem;
    overflow: hidden;
}

/* Right-side stack: the loadout picker sits directly above RightColumn,
   matching its width. MainArea continues from the top of .planner__body
   down to its bottom on the left, parallel to picker + right column. */
.planner__right-stack[b-tijoaa5uj1] {
    width: 28rem;          /* matches RightColumn's width */
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-height: 0;
    padding: 0.5rem;       /* same shadow gutter as .main-area, so this column's
                              cards inset equally and align with the gear panel */
}

.planner__right-stack[b-tijoaa5uj1]  .right-column {
    width: auto;            /* fill stack instead of self-sizing */
    flex: 1;
    min-height: 0;
}

/* ── Load-failure state ────────────────────────────────────────────────────
   Replaces the planner body when no character could be made active: a centred
   prose column plus a legend mapping each status symbol to what it means. The
   symbols carry the same colours as their top-strip counterparts. */
.planner__load-failure[b-tijoaa5uj1] {
    max-width: 44rem;
    max-height: 100%;
    margin-inline: auto;
    align-self: center;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.5rem;
    font-family: var(--font-ui);
    font-size: 0.875rem;
    line-height: 1.6;
    color: var(--color-content-muted);
    overflow-y: auto;
}

.planner__load-failure-intro[b-tijoaa5uj1] {
    color: var(--color-content);
    font-size: 1rem;
    font-weight: 600;
}

.planner__status-legend[b-tijoaa5uj1] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.planner__status-legend-entry[b-tijoaa5uj1] {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
}

.planner__status-icon[b-tijoaa5uj1] {
    display: inline-flex;
    flex-shrink: 0;
    /* Nudge onto the optical centre of the entry's first line (line-height 1.6). */
    margin-top: 0.2em;
}

/* ::deep — the SVG comes from the icon component, so the scope attribute
   never lands on it. */
.planner__status-icon[b-tijoaa5uj1]  svg {
    width: 1.375rem;
    height: 1.375rem;
}

.planner__status-icon--migration[b-tijoaa5uj1] {
    color: var(--color-warning);
}

.planner__status-icon--blocked[b-tijoaa5uj1] {
    color: var(--color-danger-text);
}
/* /Layout/Planner/Rail.razor.rz.scp.css */
/* Rail container — full-height column, 64px wide, planner-scoped.

   Tokens and proportions ported from the rail-only.html prototype in
   openspec/changes/archive/   (search "blazor-planner-shell"; rail-only.html).
   Scoped CSS: rules below apply to elements rendered by Rail itself; the rail
   button's internals are owned by RailButton.razor.css. */

.rail[b-pjf52gqv8y] {
    width: 64px;
    align-self: stretch;
    border-right: 1px solid var(--color-line);
    background: var(--color-surface-raised);
    display: flex;
    flex-direction: column;
    box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.25);
    flex-shrink: 0;
}

.rail-logo[b-pjf52gqv8y] {
    width: 64px;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-bottom: 1px solid var(--color-line);
    background: linear-gradient(180deg, rgba(191, 138, 36, 0.08) 0%, transparent 100%);
    flex-shrink: 0;
}

.rail-logo img[b-pjf52gqv8y] {
    width: 40px;
    height: 40px;
    object-fit: contain;
}

.rail-spacer-top[b-pjf52gqv8y] {
    padding-top: 10px;
}

.rail-nav[b-pjf52gqv8y] {
    /* Empty in this change. Reserved slot for dimension entries. */
}

.rail-divider[b-pjf52gqv8y] {
    height: 1px;
    margin: 8px 12px;
    background: var(--color-line);
}

.rail-foot[b-pjf52gqv8y] {
    margin-top: auto;
}

.rail-foot-spacer[b-pjf52gqv8y] {
    height: 8px;
}
/* /Layout/Planner/RailButton.razor.rz.scp.css */
/* Rail button — icon-only, hover fill, hover tooltip, active accent bar.

   Tokens and proportions ported from the rail-only.html prototype in
   openspec/changes/archive/   (search "blazor-planner-shell"; rail-only.html).
   Scoped CSS: descendant rules apply only to elements rendered by RailButton. */

.rail-btn[b-tsqlnacwuj] {
    position: relative;
    width: 64px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-content-muted);
    cursor: pointer;
    transition: color 0.12s;
    background: none;
    border: 0;
    padding: 0;
}

.rail-btn:hover[b-tsqlnacwuj] {
    color: var(--color-content);
}

.rail-btn:hover .rail-btn-hover-fill[b-tsqlnacwuj] {
    position: absolute;
    inset: 4px 6px;
    background: rgba(255, 255, 255, 0.04);
    border-radius: var(--radius);
    pointer-events: none;
}

.rail-btn.is-active[b-tsqlnacwuj] {
    color: var(--color-primary-emphasis);
}

.rail-btn.is-active .rail-active-bar[b-tsqlnacwuj] {
    background: var(--color-primary);
    box-shadow: 0 0 8px rgba(191, 138, 36, 0.55);
}

.rail-btn.is-active .rail-active-fill[b-tsqlnacwuj] {
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(191, 138, 36, 0.16) 0%, rgba(191, 138, 36, 0.04) 70%, transparent 100%);
    pointer-events: none;
}

.rail-active-bar[b-tsqlnacwuj] {
    position: absolute;
    left: 0;
    top: 6px;
    bottom: 6px;
    width: 3px;
    background: transparent;
}

.rail-icon[b-tsqlnacwuj] {
    position: relative;
    z-index: 1;
    display: flex;
}

/* Tooltip on hover (CSS-only, positioned to the right). */
.rail-btn[data-label]:hover[b-tsqlnacwuj]::after {
    content: attr(data-label);
    position: absolute;
    left: 64px;
    top: 50%;
    transform: translateY(-50%);
    background: var(--color-surface-raised);
    color: var(--color-content);
    border: 1px solid var(--color-line-strong);
    padding: 5px 9px;
    font-size: 12px;
    white-space: nowrap;
    z-index: 50;
    pointer-events: none;
    box-shadow: var(--shadow-card);
    border-radius: var(--radius);
}
/* /Layout/Planner/RightColumn.razor.rz.scp.css */
/* RightColumn — fixed-width sidebar with .card surface treatment.

   Width matches the eventual breakdown panel's resting width in the Vue
   planner. The .card class (from components.css) provides the surface,
   border, radius, and shadow tokens per D9 / D8. */

.right-column[b-oytq8bmrio] {
    width: 22rem;          /* ~352px — matches Vue breakdown panel resting width */
    flex-shrink: 0;
    overflow: auto;
}
/* /Layout/Planner/TopStrip.razor.rz.scp.css */
/* TopStrip — surface treatment ported from the Vue planner header.

   Vue oracle: .build-planner__header { bg-surface-raised, rounded, px-4 py-3,
   --shadow-card, flex justify-between items-center }. Sits to the right of
   the rail (left edge meets the rail's right edge). */

.top-strip[b-ohbeyddvu7] {
    /* Floating card surface ported from Vue's .build-planner__header
       (bg-surface-raised, rounded, --shadow-card, px-4 py-3). The parent
       .planner__right provides the surrounding padding and gap to the body. */
    background: var(--color-surface-raised);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    padding: 0.75rem 1rem;        /* py-3 px-4 */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    flex-shrink: 0;
}

.top-strip__switcher-slot[b-ohbeyddvu7] {
    /* Anchor for the absolutely-positioned dropdown menu. */
    display: flex;
    align-items: center;
    position: relative;
}

.top-strip__switcher[b-ohbeyddvu7] {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    height: 2rem;
    padding: 0.25rem 0.625rem;
    font-family: var(--font-ui);
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--color-content);
    background: var(--color-surface);
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius);
    cursor: pointer;
}

.top-strip__switcher:hover:not(:disabled)[b-ohbeyddvu7] {
    border-color: var(--color-primary);
}

.top-strip__switcher:disabled[b-ohbeyddvu7] {
    color: var(--color-content-muted);
    cursor: not-allowed;
}

.top-strip__switcher-label[b-ohbeyddvu7] {
    white-space: nowrap;
}

.top-strip__switcher-chevron[b-ohbeyddvu7] {
    display: flex;
    color: var(--color-content-subtle);
}

.top-strip__switcher-menu[b-ohbeyddvu7] {
    position: absolute;
    top: calc(100% + 0.25rem);
    left: 0;
    min-width: 100%;
    z-index: 10;
    margin: 0;
    padding: 0.25rem 0;
    list-style: none;
    background: var(--color-surface-raised);
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
}

.top-strip__switcher-item[b-ohbeyddvu7] {
    display: flex;          /* keeps the status icon on the name's line */
    align-items: center;
    gap: 0.375rem;
    width: 100%;
    text-align: left;
    padding: 0.375rem 0.75rem;
    font-family: var(--font-ui);
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--color-content);
    background: transparent;
    border: 0;
    cursor: pointer;
    white-space: nowrap;
}

.top-strip__switcher-item:hover[b-ohbeyddvu7] {
    background: var(--color-surface);
}

.top-strip__switcher-item.is-active[b-ohbeyddvu7] {
    color: var(--color-primary);
    font-weight: 600;
}

/* Per-character load status, trailing the name. Sized to the entry's text
   rather than the SVG's own 24px default; ::deep because the SVG comes from
   the icon component, so the scope attribute never lands on it. */
.top-strip__status-icon[b-ohbeyddvu7] {
    display: inline-flex;
    flex-shrink: 0;
    margin-left: auto;
}

.top-strip__status-icon[b-ohbeyddvu7]  svg {
    width: 0.875rem;
    height: 0.875rem;
}

.top-strip__status-icon--migration[b-ohbeyddvu7] {
    color: var(--color-warning);
}

.top-strip__status-icon--blocked[b-ohbeyddvu7] {
    color: var(--color-danger-text);
}

.top-strip__info[b-ohbeyddvu7] {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--font-ui);
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--color-content-muted);
}

.top-strip__info-separator[b-ohbeyddvu7] {
    color: var(--color-content-subtle);
}

.top-strip__actions[b-ohbeyddvu7] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Inline icons inside .btn — reuse the .btn's existing gap.
   ::deep so the rule reaches the NavLink's child SVGs even though scoped CSS
   normally stops at the component's root. */
[b-ohbeyddvu7] .btn svg {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
}
/* /Layout/Welcome/WelcomePanel.razor.rz.scp.css */
/* WelcomePanel — collage + content, ported verbatim from the Vue source.

   The collage is one piece of hand-placed art, not reusable UI: the stage size,
   screenshot offsets/rotations, radial vignette, and the screenshot box-shadow
   are intentional magic numbers, not tokenisable elevation. The vignette fades
   to --color-surface, which is the app-shell__view (body) background, so the
   full-page takeover shows no seam. */

/* ── Outer layout ──────────────────────────────────────────────────────────── */
.welcome-panel[b-hoe4y8jh5v] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 2rem 1rem;
    gap: 2rem;
}

/* ── Collage ───────────────────────────────────────────────────────────────── */
.welcome-panel__collage[b-hoe4y8jh5v] {
    position: relative;
    width: 100%;
    max-width: 860px;
    height: 540px;
    flex-shrink: 0;
}

/* Vignette — light fade at the very edges only */
.welcome-panel__collage[b-hoe4y8jh5v]::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(
        ellipse 70% 65% at center,
        transparent 55%,
        var(--color-surface) 90%
    );
    z-index: 4;
    pointer-events: none;
}

.welcome-panel__illustration[b-hoe4y8jh5v] {
    position: absolute;
    width: 420px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: var(--radius-lg);
    z-index: 3;
    pointer-events: none;
    user-select: none;
}

.welcome-panel__shot[b-hoe4y8jh5v] {
    position: absolute;
    border-radius: var(--radius-lg);
    /* Exception: decorative screenshot shadow — intentional raw value,
       not a general elevation token. */
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55);
    object-fit: cover;
    object-position: top left;
    pointer-events: none;
    user-select: none;
}

/* Stat breakdown — upper right */
.welcome-panel__shot--1[b-hoe4y8jh5v] {
    width: 210px;
    height: 260px;
    right: 55px;
    top: 30px;
    transform: rotate(3.5deg);
    z-index: 2;
}

/* Import table — upper left */
.welcome-panel__shot--2[b-hoe4y8jh5v] {
    width: 255px;
    height: 200px;
    left: 35px;
    top: 25px;
    transform: rotate(-3deg);
    z-index: 1;
}

/* Item search — lower right */
.welcome-panel__shot--3[b-hoe4y8jh5v] {
    width: 205px;
    height: 255px;
    right: 45px;
    bottom: 28px;
    transform: rotate(-2deg);
    z-index: 2;
}

/* Planner partial — lower left */
.welcome-panel__shot--4[b-hoe4y8jh5v] {
    width: 255px;
    height: 205px;
    left: 28px;
    bottom: 25px;
    transform: rotate(2.5deg);
    z-index: 1;
}

/* ── Content ───────────────────────────────────────────────────────────────── */
.welcome-panel__content[b-hoe4y8jh5v] {
    text-align: center;
    max-width: 420px;
}

.welcome-panel__heading[b-hoe4y8jh5v] {
    font-size: 1.5rem;     /* hero override — larger than heading-panel default */
    margin-bottom: 0.5rem;
}

.welcome-panel__intro[b-hoe4y8jh5v] {
    color: var(--color-content-muted);
    font-size: 0.875rem;
    line-height: 1.6;
    margin-bottom: 1.5rem;
}

.welcome-panel__actions[b-hoe4y8jh5v] {
    display: flex;
    gap: 0.75rem;
    justify-content: center;
}
/* /Loadout/Components/LoadoutViewToggle.razor.rz.scp.css */
/* LoadoutViewToggle — two name-labelled options sharing one bordered pill. The
   panel size sits in a dimension panel's toolbar; the compact size fits the
   tighter ItemCard subheader. Placement (centring, grid column) is the
   consumer's concern, not the toggle's. */

.loadout-view-toggle[b-njoruf4pw9] {
    display: inline-flex;
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius);
    overflow: hidden;
}

.loadout-view-toggle__option[b-njoruf4pw9] {
    background-color: var(--color-surface-muted);
    color: var(--color-content);
    cursor: pointer;
    border: none;
}

.loadout-view-toggle__option:hover[b-njoruf4pw9] {
    background-color: var(--color-surface-muted-strong);
}

.loadout-view-toggle__option.is-active[b-njoruf4pw9] {
    background-color: var(--color-primary);
    color: var(--color-primary-fg);
}

.loadout-view-toggle--panel .loadout-view-toggle__option[b-njoruf4pw9] {
    padding: 0.25rem 0.75rem;
    font-size: 0.875rem;
}

.loadout-view-toggle--compact .loadout-view-toggle__option[b-njoruf4pw9] {
    padding: 0.125rem 0.625rem;
    font-size: 0.8125rem;
}
/* /Loadout/Gear/Components/GearPanel.razor.rz.scp.css */
/* GearPanel — three-column anatomical gear layout. Sizing, ratio and spacing
   are ported from the frozen Vue SlotGrid (openspec/changes/archive/, search
   "blazor-gear-panel"; design D6). The behaviour carries over, not fixed tile
   dimensions: a 1:5:1 column grid, a uniform 0.5rem gap, side tiles that
   flex-share their column clamped 44-160px, a weapon row exactly one side-slot
   row tall, and min-height/min-width 0 throughout so the grid shrinks
   gracefully. Tile sizing reaches the child component via ::deep. */

.gear-panel[b-54kxwts162] {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 600px;
    max-width: 1180px;
    min-height: calc(7 * 50px + 6 * 0.5rem);
    padding: 0.5rem;
    background-color: transparent;   /* blend into the page; keep card border + shadow */
}

.gear-panel__body[b-54kxwts162] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 5fr minmax(0, 1fr);
    gap: 0.5rem;
    align-items: stretch;
    flex: 1;
    min-height: 0;
}

/* ── Side columns: jewellery (left), armour (right) ──────────────────────── */

.gear-panel__column[b-54kxwts162] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-height: 0;
}

.gear-panel__column[b-54kxwts162]  .gear-slot-tile {
    flex: 1;
    min-height: 44px;
    max-height: 160px;
}

/* ── Centre column: view toggle, character figure, weapon row ────────────── */

.gear-panel__centre[b-54kxwts162] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
}

/* The whole-set toggle heads the centre column so the side columns reach the
   panel top and only the figure is pushed down. The shared LoadoutViewToggle
   owns its own pill styling; the column only centres it. */
.gear-panel__centre[b-54kxwts162]  .loadout-view-toggle {
    align-self: center;
}

.gear-panel__figure[b-54kxwts162] {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: 0.5rem;
}

.gear-panel__figure-image[b-54kxwts162] {
    max-height: 100%;
    max-width: 100%;
    object-fit: contain;
}

.gear-panel__weapons[b-54kxwts162] {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 0.5rem;
    flex: 0 0 calc((100% - 3rem) / 7);
    min-height: 44px;
    max-height: 160px;
}

.gear-panel__weapons[b-54kxwts162]  .gear-slot-tile {
    min-height: 0;
}
/* /Loadout/Gear/Components/GearSlotTile.razor.rz.scp.css */
/* GearSlotTile — one gear-panel slot tile. The look is re-expressed from the
   frozen Vue SlotGrid (openspec/changes/archive/, search "blazor-gear-panel";
   design D5, D9) in design tokens. Tile sizing (flex-share, height clamp) is a
   layout concern and lives in GearPanel.razor.css. */

.gear-slot-tile[b-uu6owcpulc] {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    overflow: hidden;
    padding: 0.5rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    background: var(--color-surface-raised);
    box-shadow: var(--shadow-tile);
}

/* Status border: an owned slot (set on the active loadout) reads as a solid
   primary edge; an inherited slot (falling back to the baseline) reads as a
   quieter dashed secondary edge. */
.gear-slot-tile.is-owned[b-uu6owcpulc] {
    border-color: var(--color-primary-border);
}

.gear-slot-tile.is-inherited[b-uu6owcpulc] {
    border-style: dashed;
    border-color: var(--color-secondary-border);
}

/* ── Item display ────────────────────────────────────────────────────────── */

/* Button reset. The body fills the tile so the whole cell is the click
   affordance that opens the ItemCard; content stacks from the top. */
.gear-slot-tile__body[b-uu6owcpulc] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    flex: 1;
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.gear-slot-tile__body:focus-visible[b-uu6owcpulc] {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
    border-radius: var(--radius);
}

/* Slot icon — stands in for the retired slot-name text line. When the tile
   shows an item the icon is a quiet marker pinned to the upper-right corner
   (mirroring the gap badge at the lower-right); when the tile is empty it is the
   prominent, greyed, centred content. The icon's HoverLabel wrapper is rendered
   in the primitive's own scope, so ::deep reaches it (and the glyph's svg). */
.gear-slot-tile[b-uu6owcpulc]  .gear-slot-tile__slot-icon {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    color: var(--color-content-subtle);
    line-height: 1;
}

.gear-slot-tile[b-uu6owcpulc]  .gear-slot-tile__slot-glyph {
    display: inline-flex;
}

.gear-slot-tile[b-uu6owcpulc]  .gear-slot-tile__slot-icon svg {
    width: 1.25rem;
    height: 1.25rem;
}

.gear-slot-tile[b-uu6owcpulc]  .gear-slot-tile__slot-icon--empty {
    position: static;
    align-self: center;
    margin-block: auto;
}

.gear-slot-tile[b-uu6owcpulc]  .gear-slot-tile__slot-icon--empty svg {
    width: 2.5rem;
    height: 2.5rem;
}

/* Reserve a right gutter the width of the corner slot icon (1.25rem glyph +
   its 0.5rem inset) so the name wraps clear of it instead of running under. */
.gear-slot-tile__item-name[b-uu6owcpulc] {
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.35;
    overflow-wrap: anywhere;
    padding-right: 2.25rem;
}

/* Gap badge — at-a-glance "this slot is still incomplete" cue. Pinned to the
   bottom-right so it sits in one place across the grid (D5). */
.gear-slot-tile[b-uu6owcpulc]  .gear-slot-tile__gap {
    position: absolute;
    right: 0.5rem;
    bottom: 0.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    color: var(--color-warning);
}

.gear-slot-tile[b-uu6owcpulc]  .gear-slot-tile__gap-glyph {
    display: inline-flex;
}

.gear-slot-tile[b-uu6owcpulc]  .gear-slot-tile__gap svg {
    width: 0.875rem;
    height: 0.875rem;
}
/* /Loadout/Gear/Components/ItemCard.razor.rz.scp.css */
/* ItemCard — inspection panel chrome. Outer panel, backdrop, sizing, and the
   close × are owned by BaseModal + the dialog-stack host; this stylesheet only
   handles ItemCard's own header row and body. The subheader toggle owns its
   own styling (the shared LoadoutViewToggle). */

.item-card__header[b-66flsn39e3] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.item-card__slot-name[b-66flsn39e3] {
    margin: 0;
}

.item-card__inherited-chip[b-66flsn39e3] {
    font-family: var(--font-ui);
    font-size: 0.6875rem;
    line-height: 1;
    padding: 0.125rem 0.375rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    color: var(--color-content-subtle);
    background: var(--color-surface);
}

/* ── Header verb-trigger row ──────────────────────────────────────────────── */

.item-card__verb-row[b-66flsn39e3] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin-top: 0.375rem;
}

.item-card__verb[b-66flsn39e3] {
    font-family: var(--font-ui);
    font-size: 0.6875rem;
    line-height: 1;
    padding: 0.1875rem 0.4375rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    color: var(--color-content-subtle);
    background: var(--color-surface);
    cursor: pointer;
}

.item-card__verb:hover[b-66flsn39e3] {
    color: var(--color-content);
    border-color: var(--color-line-strong);
}

/* ── Body ────────────────────────────────────────────────────────────────── */

.item-card__empty[b-66flsn39e3] {
    font-size: 0.875rem;
    color: var(--color-content-subtle);
    text-align: center;
    padding: 1rem 0;
}

/* ── Essence sub-slots ───────────────────────────────────────────────────── */

.item-card__essences[b-66flsn39e3] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin-top: 0.5rem;
}

.item-card__essence-tile[b-66flsn39e3] {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.5rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    background: var(--color-surface-raised);
}

/* An unfilled socket reads as a sunken well, not a ghost card: where a filled
   tile is raised, this one is inset. The fill carries the empty state on its
   own, which leaves the border free to carry nothing but the socket type. */
.item-card__essence-tile.is-empty[b-66flsn39e3] {
    background: var(--color-surface);
}

/* Hover lightens the fill rather than the border: the border carries the socket
   type and must keep its tone in every state. A filled tile always has its open
   button, so it is always interactive. No hover value may repeat another
   state's resting value: filled and empty tiles sit next to each other, so a
   collision reads as two tiles in the same state. */
.item-card__essence-tile:not(.is-empty):hover[b-66flsn39e3] {
    background: var(--color-surface-sunken);
}

/* An empty tile rests lighter than a filled one, so it needs its own hover step
   to keep lifting rather than dropping. Restricted to the button form on
   purpose: an unequippable socket renders as a div and must stay inert. */
button.item-card__essence-tile.is-empty:hover[b-66flsn39e3] {
    background: var(--color-surface-muted);
}

/* The socket type is carried by the tile's own border — the same tone
   vocabulary the item preview uses for an item's socket list. Cloak and
   necklace sockets share a tone: they never appear on the same item. Traceries
   have no rule here on purpose — they keep the default line colour and are told
   apart by their glyph's shape instead, the split the game itself makes. */
.item-card__essence-tile[data-socket="BasicEssence"][b-66flsn39e3]    { border-color: var(--color-socket-basic); }
.item-card__essence-tile[data-socket="PrimaryEssence"][b-66flsn39e3]  { border-color: var(--color-socket-primary); }
.item-card__essence-tile[data-socket="VitalEssence"][b-66flsn39e3]    { border-color: var(--color-socket-vital); }
.item-card__essence-tile[data-socket="CloakEssence"][b-66flsn39e3],
.item-card__essence-tile[data-socket="NecklaceEssence"][b-66flsn39e3] { border-color: var(--color-socket-class); }
.item-card__essence-tile[data-socket="EssenceOfWar"][b-66flsn39e3]    { border-color: var(--color-socket-war); }

button.item-card__essence-tile[b-66flsn39e3] {
    width: 100%;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.item-card__essence-open[b-66flsn39e3] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    width: 100%;
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

/* The × is rendered by the DismissButton child component, so the rule must
   cross the scope boundary with ::deep — a plain scoped selector would not
   match it and the button would fall back to normal flow. */
.item-card__essence-tile[b-66flsn39e3]  .item-card__essence-dismiss {
    position: absolute;
    top: 0.25rem;
    right: 0.25rem;
}

.item-card__essence-name[b-66flsn39e3] {
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.3;
}

.item-card__essence-empty[b-66flsn39e3] {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.75rem;
    color: var(--color-content-subtle);
}

/* Glyph and name sit on one line so the socket mark reads as a prefix to the
   essence rather than as its own row. */
.item-card__essence-headline[b-66flsn39e3] {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}
/* /Loadout/Gear/Components/Search/ItemPreview.razor.rz.scp.css */
/* ItemPreview — quality-framed inspect surface. The hover-popover positioning is
   owned by the search panel that mounts it; this stylesheet handles only the
   card's own frame and content rows. */

.item-preview[b-ggg3pgnkqd] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    background: var(--color-surface-raised);
}

/* ── Heading ─────────────────────────────────────────────────────────────── */

.item-preview__name[b-ggg3pgnkqd] {
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

.item-preview__subname[b-ggg3pgnkqd] {
    margin-top: -0.375rem;
    font-size: 0.8125rem;
    line-height: 1.3;
    color: var(--color-content-muted);
    overflow-wrap: anywhere;
}

.item-preview__category[b-ggg3pgnkqd] {
    font-family: var(--font-ui);
    font-size: 0.75rem;
    color: var(--color-content-muted);
}

/* ── Body groups ─────────────────────────────────────────────────────────── */

/* Item level, weapon damage / DPS, and level requirements — the item's own
   facts, quieter than its stats. */
.item-preview__meta[b-ggg3pgnkqd] {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    font-family: var(--font-ui);
    font-size: 0.75rem;
    color: var(--color-content-subtle);
}

/* Whether this group renders anything is only knowable after formatting every
   row, so the guard stays in CSS rather than duplicating that work in a
   condition. Relies on Razor trimming whitespace-only content — an explicit
   whitespace child would defeat :empty and leave a stray gap. */
.item-preview__stats:empty[b-ggg3pgnkqd] {
    display: none;
}

.item-preview__legendary[b-ggg3pgnkqd] {
    font-family: var(--font-ui);
    font-size: 0.75rem;
    color: var(--color-primary-emphasis);
}

/* ── Sockets ─────────────────────────────────────────────────────────────── */

/* Stacked, never wrapped: socket order matches the item's own order in game. */
.item-preview__sockets[b-ggg3pgnkqd] {
    display: flex;
    flex-direction: column;
    gap: 0.1875rem;
}

.item-preview__sockets-label[b-ggg3pgnkqd] {
    font-family: var(--font-ui);
    font-size: 0.75rem;
    color: var(--color-content-subtle);
}

.item-preview__socket[b-ggg3pgnkqd] {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-family: var(--font-ui);
    font-size: 0.75rem;
    line-height: 1.4;
    color: var(--color-content-muted);
}

/* ── Flag ────────────────────────────────────────────────────────────────── */

/* The card is a column flex, so a button would stretch to its full width:
   align-self keeps it to its own text. Outlined rather than filled — a
   borderless button here reads as a line of text. Mirrors the verb buttons on
   ItemCard; scoped stylesheets cannot share the class. */
.item-preview__flag[b-ggg3pgnkqd] {
    align-self: flex-end;
    font-family: var(--font-ui);
    font-size: 0.6875rem;
    line-height: 1;
    padding: 0.1875rem 0.4375rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    color: var(--color-content-subtle);
    background: var(--color-surface);
    cursor: pointer;
}

.item-preview__flag:hover[b-ggg3pgnkqd] {
    color: var(--color-content);
    border-color: var(--color-line-strong);
}
/* /Loadout/Gear/Components/Search/ItemSearchPanel.razor.rz.scp.css */
/* ItemSearchPanel — the search surface. The hover preview floats as a fixed
   sibling beside the centred panel: horizontally past the panel's right edge
   (viewport centre + half of max-w-lg + a gap), vertically anchored to the
   panel's measured top via the inline `top` style. */

.item-search__preview[b-fk7ir9ue81] {
    left: calc(50% + 16rem + 0.75rem);
    width: 18rem;
    max-width: calc(50vw - 17rem);
}

/* During a refetch the previous results stay rendered (height stays stable, no
   collapse-to-loading flicker) but are dimmed and non-interactive. */
.item-search__list--updating[b-fk7ir9ue81] {
    opacity: 0.5;
    pointer-events: none;
}

/* Filter drawer — a bordered container so it reads as a surface that opened.
   Fields flow rather than sitting on a fixed grid: numeric fields size to their
   inputs, only selects and typeaheads stretch, which keeps the drawer short.
   Kind-specific filters sit inset on a sunken fill so they read as revealed by
   the kind switch rather than as further constraints. */

.item-search__filter-drawer[b-fk7ir9ue81] {
    margin-bottom: 0.5rem;
    padding: 0.75rem;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-lg);
}

/* Fixed placement, not flow: quality / class / exclusive on the first row, the
   two level fields on the second. */
.item-search__filter-grid[b-fk7ir9ue81] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
    column-gap: 1rem;
    row-gap: 0.625rem;
    align-items: center;
}

.item-search__levels[b-fk7ir9ue81] {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 1.5rem;
}

.item-search__kind-filters[b-fk7ir9ue81] {
    display: flex;
    flex-wrap: wrap;
    align-items: start;
    gap: 0.625rem 1rem;
}

.item-search__kind[b-fk7ir9ue81] {
    margin-top: 0.75rem;
}

.item-search__kind-filters[b-fk7ir9ue81] {
    margin-top: 0.5rem;
    padding: 0.75rem;
    background-color: var(--color-surface-sunken);
    border-radius: var(--radius-md);
}

.item-search__field[b-fk7ir9ue81] {
    min-width: 0;
}

/* The kind-specific block still flows; only the free-text-ish controls there
   earn horizontal space. */
.item-search__kind-filters .item-search__field:has(select)[b-fk7ir9ue81],
.item-search__kind-filters .item-search__field:has(.smart-enum-typeahead)[b-fk7ir9ue81] {
    flex: 1 1 11rem;
    max-width: 18rem;
}

.item-search__field .input[type="number"][b-fk7ir9ue81] {
    width: 5rem;
}

.item-search__field--inline[b-fk7ir9ue81] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}


.item-search__range[b-fk7ir9ue81] {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}

.item-search__range-sep[b-fk7ir9ue81] {
    flex-shrink: 0;
    color: var(--color-content-muted);
}

.item-search__exclusive[b-fk7ir9ue81] {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    min-height: 2rem;
    font-family: var(--font-ui);
    font-size: 0.8125rem;
    line-height: 1.25rem;
    color: var(--color-content-muted);
    cursor: pointer;
}

.item-search__filter-count[b-fk7ir9ue81] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.375rem;
    border-radius: 999px;
    font-size: 0.6875rem;
    font-weight: 600;
    background: var(--color-primary);
    color: var(--color-primary-fg);
}
/* /Loadout/Gear/Components/Search/TagTypeahead.razor.rz.scp.css */
/* TagTypeahead — a typeahead-filtered tag input. The suggestion list overlays
   following content while open; selected tags surface as chips in the panel's
   summary row, not here. */

.tag-typeahead[b-wwon0zt5e9] {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.relative[b-wwon0zt5e9] {
    position: relative;
}

.typeahead-list[b-wwon0zt5e9] {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 10;
    margin: 0.125rem 0 0;
    padding: 0.25rem;
    list-style: none;
    max-height: 12rem;
    overflow-y: auto;
    background: var(--color-surface-raised);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}

.typeahead-option[b-wwon0zt5e9] {
    display: block;
    width: 100%;
    padding: 0.25rem 0.5rem;
    border-radius: var(--radius-md);
    text-align: left;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--color-content);
}

.typeahead-option:hover[b-wwon0zt5e9],
.typeahead-option:focus-visible[b-wwon0zt5e9] {
    background: var(--color-surface-muted);
}
/* /Loadout/Gear/Components/SocketGlyph.razor.rz.scp.css */
/* SocketGlyph — one socket mark. Sized once here so every surface that shows a
   socket lands on the same mark size. */

.socket-glyph[b-z33nu5jcg9] {
    display: inline-flex;
    flex-shrink: 0;
}

/* The icon is a child component, so the scoped selector has to cross the scope
   boundary to size the SVG it renders. */
.socket-glyph[b-z33nu5jcg9]  svg {
    width: 0.8125rem;
    height: 0.8125rem;
}

/* Tones carry essence socket types. Traceries take the neutral tone and are
   told apart by the glyph's shape instead. */
.socket-glyph.is-basic[b-z33nu5jcg9]   { color: var(--color-socket-basic); }
.socket-glyph.is-primary[b-z33nu5jcg9] { color: var(--color-socket-primary); }
.socket-glyph.is-vital[b-z33nu5jcg9]   { color: var(--color-socket-vital); }
.socket-glyph.is-class[b-z33nu5jcg9]   { color: var(--color-socket-class); }
.socket-glyph.is-war[b-z33nu5jcg9]     { color: var(--color-socket-war); }
.socket-glyph.is-neutral[b-z33nu5jcg9] { color: var(--color-content-subtle); }
/* /Loadout/Gear/Components/StatPreview.razor.rz.scp.css */
/* StatPreview — read-only stat block layout. Two density variants share the
   same row structure; only spacing and type size differ. Colours and tabular
   numeric formatting come from global tokens / utility classes.

   Stat, effect and special-effect labels may carry \n from the corpus (see
   StatFormatter.FormatItemStatRow). pre-line honours those breaks while still
   collapsing incidental whitespace and wrapping long lines normally.
*/

.stat-preview[b-qj3yf4sfpg] {
    display: flex;
    flex-direction: column;
    font-family: var(--font-ui);
    font-size: 0.75rem;
    line-height: 1.35;
    color: var(--color-content-muted);
    white-space: pre-line;
}

.stat-preview--full[b-qj3yf4sfpg] {
    gap: 0.375rem;
}

.stat-preview--compact[b-qj3yf4sfpg] {
    gap: 0.125rem;
}
/* /Loadout/LoadoutManagementDialog.razor.rz.scp.css */
/* LoadoutManagementDialog — list of descriptor rows + a create row. */

.loadout-management__list[b-4yggz2zh2h] {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.loadout-management__row[b-4yggz2zh2h] {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
}

.loadout-management__name[b-4yggz2zh2h] {
    flex: 1;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    text-align: left;
    padding: 0.375rem 0.5rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    color: var(--color-content);
    cursor: pointer;
}

.loadout-management__name:hover[b-4yggz2zh2h] {
    background: var(--color-surface-hover);
    border-color: var(--color-line);
}

.loadout-management__name-pencil[b-4yggz2zh2h] {
    display: inline-flex;
    color: var(--color-content-muted);
    width: 0.875rem;
    height: 0.875rem;
    transform: translateY(-2px);  /* nudge above baseline — Lucide box sits low on the line */
}

.loadout-management__name:hover .loadout-management__name-pencil[b-4yggz2zh2h] {
    color: var(--color-primary);
}

.loadout-management__edit[b-4yggz2zh2h] {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.loadout-management__delete[b-4yggz2zh2h] {
    flex-shrink: 0;
    width: 1.75rem;
    height: 1.75rem;
    line-height: 1;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    color: var(--color-content-muted);
    cursor: pointer;
    font-size: 1rem;
}

.loadout-management__delete:hover[b-4yggz2zh2h] {
    color: var(--color-danger-text);
    border-color: var(--color-line);
}

.loadout-management__create[b-4yggz2zh2h] {
    margin-top: 1rem;
    display: flex;
    flex-direction: row;
    gap: 0.5rem;
}

.loadout-management__create > .input[b-4yggz2zh2h] {
    flex: 1;
    min-width: 0;
}
/* /Loadout/Virtues/Components/VirtuePanel.razor.rz.scp.css */
/* VirtuePanel — a centred active-slot row over a 3×7 column-major passive grid.
   The passive grid fills column-major (down each column, then the next) via
   grid-auto-flow:column over 7 explicit rows, so entry i lands at column i/7,
   row i%7 — the alphabetical-by-key order running top-to-bottom per column. */

.virtue-panel[b-ol9o6ih1eg] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    flex: 1;
    min-width: 600px;
    max-width: 1180px;
    padding: 0.75rem;
}

/* ── Whole-set view toggle ──────────────────────────────────────────────── */

/* The toggle stays centred between two equal flanks; "Max all" sits in the
   right flank so it shares the toggle's line rather than taking a row of its own. */
.virtue-panel__toolbar[b-ol9o6ih1eg] {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
}

/* The shared LoadoutViewToggle owns its own pill styling; the panel only places
   it in the centre column. ::deep reaches the toggle's root in its own scope. */
.virtue-panel__toolbar[b-ol9o6ih1eg]  .loadout-view-toggle {
    grid-column: 2;
    align-self: center;
}

.virtue-panel__max-all[b-ol9o6ih1eg] {
    grid-column: 3;
    justify-self: end;
}

/* ── Active slots: a single centred row ─────────────────────────────────── */

.virtue-panel__active[b-ol9o6ih1eg],
.virtue-panel__passive[b-ol9o6ih1eg] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.virtue-panel__active-row[b-ol9o6ih1eg] {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
}

.virtue-panel__active-row .virtue-tile[b-ol9o6ih1eg] {
    flex: 1 1 0;
    min-width: 0;
}

/* ── Passive virtues: 3 columns × 7 rows, filled column-major ───────────── */

/* Three columns × seven rows is fixed: it mirrors the in-game virtue panel, so
   the order must not reflow. Cap the column width rather than stretching to 1fr,
   so the centred block leaves a margin each side instead of filling the panel. */
.virtue-panel__passive-grid[b-ol9o6ih1eg] {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 19rem));
    grid-template-rows: repeat(7, auto);
    grid-auto-flow: column;
    justify-content: center;
    gap: 0.5rem;
}

/* ── Tile ───────────────────────────────────────────────────────────────── */

.virtue-tile[b-ol9o6ih1eg] {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    /* A fixed minimum height so toggling between loadouts never resizes the tile. */
    min-height: 5rem;
    padding: 0.5rem;
    background-color: var(--color-surface-sunken);
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-tile);
}

.virtue-tile--inherited[b-ol9o6ih1eg] {
    border-style: dashed;
    border-color: var(--color-content-subtle);
}

/* Offensive/defensive classification glyph, passive tiles only — lower-left. */
.virtue-tile__class-icon[b-ol9o6ih1eg] {
    position: absolute;
    left: 0.375rem;
    bottom: 0.375rem;
    display: inline-flex;
    color: var(--color-content-muted);
    line-height: 1;
}

.virtue-tile__class-icon[b-ol9o6ih1eg]  svg {
    width: 1.125rem;
    height: 1.125rem;
}

.virtue-tile__name[b-ol9o6ih1eg] {
    font-family: var(--font-display);
    color: var(--color-content);
    font-size: 0.8125rem;
}

/* Active tiles centre the name; the rank sits as a badge in the lower-left corner
   and the controls in the upper-right, both out of flow so neither shifts the name. */
.virtue-tile--active[b-ol9o6ih1eg] {
    align-items: center;
    justify-content: center;
    text-align: center;
}

/* Passive tiles keep the name at the top-left; the rank badge, class icon and
   controls take the corners. No rank-coloured border here. */
.virtue-tile--passive[b-ol9o6ih1eg] {
    justify-content: flex-start;
}

/* A touch larger than the base name so it stays the tile's focal element next
   to the heavier class icon; truncates rather than overflowing a shrunk tile. */
.virtue-tile--passive .virtue-tile__name[b-ol9o6ih1eg] {
    font-size: 0.9375rem;
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A long name truncates rather than widening the fixed-width tile; the tail of a
   fixed virtue name carries no information. */
.virtue-tile--active .virtue-tile__name[b-ol9o6ih1eg] {
    align-self: stretch;
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 1rem;
}

/* Rank badge, lower-right of every tile; the band classes below colour its text. */
.virtue-tile__rank[b-ol9o6ih1eg] {
    position: absolute;
    right: 0.375rem;
    bottom: 0.375rem;
    padding: 0.0625rem 0.375rem;
    border-radius: var(--radius);
    background-color: var(--color-surface-muted);
    color: var(--color-content-muted);
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.4;
}

/* Three-band rank colour, keyed to the rank band (VirtueRankBands). */
.virtue-tile__rank.virtue-rank--untrained[b-ol9o6ih1eg] {
    color: var(--color-content-subtle);
}

/* Neutral mid-grey, brighter than content-muted but below the gold at-cap. */
.virtue-tile__rank.virtue-rank--trained[b-ol9o6ih1eg] {
    color: var(--color-secondary-text);
}

.virtue-tile__rank.virtue-rank--at-cap[b-ol9o6ih1eg] {
    color: var(--color-primary);
}

/* The active tile carries the same band on its root so its border echoes the
   rank colour — trained / at-cap read at a glance, and an inherited tile keeps
   the dashed style while taking the rank colour. */
.virtue-tile--active.virtue-rank--untrained[b-ol9o6ih1eg] {
    border-color: var(--color-content-subtle);
}

.virtue-tile--active.virtue-rank--trained[b-ol9o6ih1eg] {
    border-color: var(--color-secondary-border);
}

.virtue-tile--active.virtue-rank--at-cap[b-ol9o6ih1eg] {
    border-color: var(--color-primary);
}

/* ── Per-tile rank-edit / clear affordances ─────────────────────────────── */

/* Controls float in the top-right corner and reveal on hover (or keyboard
   focus), so a clearable vs non-clearable tile never reflows. */
.virtue-tile__actions[b-ol9o6ih1eg] {
    position: absolute;
    top: 0.25rem;
    right: 0.25rem;
    display: flex;
    align-items: center;
    gap: 0.125rem;
    opacity: 0;
    transition: opacity 0.12s ease;
}

.virtue-tile:hover .virtue-tile__actions[b-ol9o6ih1eg],
.virtue-tile__actions:focus-within[b-ol9o6ih1eg] {
    opacity: 1;
}

.virtue-tile__actions .virtue-tile__edit[b-ol9o6ih1eg] {
    color: var(--color-content-muted);
}

.virtue-tile__actions .virtue-tile__edit[b-ol9o6ih1eg]  svg {
    width: 0.875rem;
    height: 0.875rem;
}

.virtue-tile__edit[b-ol9o6ih1eg] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.125rem;
    border: none;
    border-radius: var(--radius);
    background: none;
    color: var(--color-content-subtle);
    cursor: pointer;
    line-height: 1;
}

.virtue-tile__edit[b-ol9o6ih1eg]  svg {
    width: 0.75rem;
    height: 0.75rem;
}

.virtue-tile__edit:hover[b-ol9o6ih1eg] {
    color: var(--color-content);
    background: var(--color-surface);
}

/* DismissButton renders in its own scope; reach its root through ::deep to
   bring the × to the pencil's scale. */
.virtue-tile__actions[b-ol9o6ih1eg]  .dismiss-button {
    font-size: 1rem;
}

/* Empty active slot: a single centred add affordance filling the tile body. */
.virtue-tile__assign[b-ol9o6ih1eg] {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    border: none;
    border-radius: var(--radius);
    background: none;
    color: var(--color-content-subtle);
    cursor: pointer;
}

.virtue-tile__assign:hover[b-ol9o6ih1eg] {
    color: var(--color-content);
    background: var(--color-surface);
}

.virtue-tile__assign[b-ol9o6ih1eg]  svg {
    width: 1.25rem;
    height: 1.25rem;
}

/* ── Hover readout wrapper ──────────────────────────────────────────────────
   A filled tile is wrapped in <Tooltip>; that wrapper becomes the grid/flex
   item in the tile's place, so it must carry the tile's sizing. ::deep reaches
   the wrapper because it is rendered in the Tooltip's own scope. */

.virtue-panel__active-row[b-ol9o6ih1eg]  .virtue-tile-readout {
    flex: 1 1 0;
    min-width: 0;
}

.virtue-panel__passive-grid[b-ol9o6ih1eg]  .virtue-tile-readout {
    display: block;
}

/* The readout floats at one fixed width across every virtue, so a short stat
   name (Fate) and a long one (In-Combat Morale Regen) don't yield wildly
   different tooltip widths; long labels wrap rather than stretch the box. The
   primitive's content-sizing min-width is overridden so the width holds. */
.virtue-panel[b-ol9o6ih1eg]  .virtue-tile-readout .tooltip__content {
    width: 15rem;
    min-width: 0;
}

.virtue-panel[b-ol9o6ih1eg]  .virtue-tile-readout .stat-preview {
    font-size: 0.8125rem;
}
/* /Loadout/Virtues/Components/VirtuePicker.razor.rz.scp.css */
/* VirtuePicker — a select list of all 21 virtues, each row marked in place with its
   equip verdict, and a hover-revealed stat preview floated beside the panel.

   The preview floats via position:fixed + CSS anchor positioning. Each row is its
   own anchor (anchor-name set inline per row, since a shared name would pin every
   preview to one element); position-area places the preview beside the hovered row,
   so it tracks the row through the list's scroll without JS-measured offsets. display
   toggle (not visibility) keeps the hidden box out of layout. */

.virtue-picker__list[b-vdmkhok6a9] {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.virtue-picker__row[b-vdmkhok6a9] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.375rem 0.5rem;
    border-radius: var(--radius);
}

.virtue-picker__row:hover[b-vdmkhok6a9] {
    background-color: var(--color-surface-sunken);
}

.virtue-picker__name[b-vdmkhok6a9] {
    font-family: var(--font-display);
    font-size: 0.875rem;
    color: var(--color-content);
}

.virtue-picker__row--disabled .virtue-picker__name[b-vdmkhok6a9] {
    color: var(--color-content-subtle);
}

.virtue-picker__reason[b-vdmkhok6a9] {
    font-size: 0.75rem;
    font-style: italic;
    color: var(--color-content-subtle);
}

.virtue-picker__preview[b-vdmkhok6a9] {
    /* position-anchor is set inline per row (see VirtuePicker.razor). */
    position: fixed;
    position-area: inline-end span-block-end;
    position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
    margin-left: 0.5rem;
    width: 15rem;
    z-index: 50;
    padding: 0.75rem;
    background: var(--color-surface-raised);
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    /* display toggle (not visibility) so the hidden box contributes no layout width. */
    display: none;
    pointer-events: none;
}

.virtue-picker__row:hover .virtue-picker__preview[b-vdmkhok6a9] {
    display: block;
}
/* /Loadout/Virtues/Components/VirtueStatPreview.razor.rz.scp.css */
/* The two-section virtue stat preview: an active section, a divider, then a
   passive section. Each section's rows mirror StatPreview's read-only row layout;
   colours and tabular numeric formatting come from global tokens / utilities. */

.virtue-stat-preview[b-kutnmo1sdz] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.virtue-stat-preview__section[b-kutnmo1sdz] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.virtue-stat-preview__divider[b-kutnmo1sdz] {
    border-top: 1px solid var(--color-line);
}

.stat-preview[b-kutnmo1sdz] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.875rem;
}

.stat-preview__row[b-kutnmo1sdz] {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
}

.stat-preview__label[b-kutnmo1sdz] {
    color: var(--color-content-muted);
}

.stat-preview__value[b-kutnmo1sdz] {
    color: var(--color-content);
}
/* /Pages/Credits.razor.rz.scp.css */
/* ── Credits links ───────────────────────────────────────────────────────────
   Same treatment as the legal page's prose links, so both static pages read
   alike. The link text is the raw URL, which can outrun a narrow viewport —
   hence the wrap allowance.
   ─────────────────────────────────────────────────────────────────────────── */
.static-page a[b-p8db4742mu] {
    color: var(--color-primary-emphasis);
    text-decoration: underline;
    text-underline-offset: 2px;
    overflow-wrap: anywhere;
}

.static-page a:hover[b-p8db4742mu] {
    color: var(--color-primary-hover);
}
/* /Pages/Impressum.razor.rz.scp.css */
/* ── Datenschutz prose ───────────────────────────────────────────────────────
   Styles heading5, paragraph, list, and link elements inside the
   .datenschutz-prose wrapper. h3/h4 use the global heading-section /
   heading-label component classes applied directly to the elements.
   ─────────────────────────────────────────────────────────────────────────── */
.datenschutz-prose h5[b-gkv3ysidiu] {
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--color-content-muted);
    margin-top: 1rem;
    margin-bottom: 0.25rem;
}

.datenschutz-prose p[b-gkv3ysidiu] {
    font-size: 0.875rem;
    color: var(--color-content-muted);
    line-height: 1.6;
    margin-bottom: 0.75rem;
}

.datenschutz-prose ul[b-gkv3ysidiu] {
    list-style: disc;
    padding-left: 1.25rem;
    margin-bottom: 0.75rem;
}

.datenschutz-prose li[b-gkv3ysidiu] {
    font-size: 0.875rem;
    color: var(--color-content-muted);
    line-height: 1.6;
    margin-bottom: 0.375rem;
}

.datenschutz-prose a[b-gkv3ysidiu] {
    color: var(--color-primary-emphasis);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.datenschutz-prose a:hover[b-gkv3ysidiu] {
    color: var(--color-primary-hover);
}
