html, body {
    background-color: #1a1a1a;
    color-scheme: dark;
}

/* Card definition — a subtle neutral border so cards read against the flat
   neutral-grey tab panels/page, where drop-shadows are nearly invisible. */
.mud-card {
    border: 1px solid rgba(255, 255, 255, 0.08);
}

/* Outlined buttons rest at the theme's quiet BorderOpacity, and MudBlazor's own hover
   only adds a background wash — so the edge never announces the hit target. Raising the
   opacity variable on the element brings every one of the framework's per-colour border
   declarations up with it, rather than racing their specificity with a border-color. */
.mud-button-outlined:hover {
    --mud-palette-border-opacity: 0.4;
}

/* MudBlazor draws an icon button as a circle, so its hover wash and focus ring arrive as a
   halo in a UI whose every other edge is square. Squaring it to the framework's own default
   radius rather than a hard 0 keeps it the same shape as the `MudButton` it sits beside in a
   toolbar, instead of introducing a second, sharper corner into the chrome. Global rather
   than scoped: corner shape is app-wide by intent, and a scope would leave circles standing
   wherever it didn't reach. Same specificity as MudBlazor's own rule, so source order wins;
   checkbox, radio and switch bases carry the class too and square off with it, which leaves
   their glyphs and the switch track untouched. */
.mud-icon-button {
    border-radius: var(--mud-default-borderradius);
}

/* Breathing room between the tab toolbar and the first row of cards on the spec
   detail page. The `pt-8` MudBlazor utility on PanelClass doesn't take effect
   reliably, so force the gap with a higher-specificity rule. */
.spec-tabs .mud-tab-panel {
    padding-top: 16px !important;
}

/* Compact tab header. The default bar is ~48px and the uppercase label uses less
   than half of it. Force every element in the bar's height chain down and flatten
   the tall default line-height (min-height alone can't shrink a bar whose text
   line-box is already taller than the target). Scoped to the spec page and to the
   planner's two strips, which pay the same ~48px for a one-line label. */
.spec-tabs .mud-tabs-tabbar,
.spec-tabs .mud-tabs-tabbar-inner,
.spec-tabs .mud-tabs-tabbar-content,
.spec-tabs .mud-tabs-tabbar-wrapper,
.planner-character-tabs .mud-tabs-tabbar,
.planner-character-tabs .mud-tabs-tabbar-inner,
.planner-character-tabs .mud-tabs-tabbar-content,
.planner-character-tabs .mud-tabs-tabbar-wrapper,
.planner-spec-tabs .mud-tabs-tabbar,
.planner-spec-tabs .mud-tabs-tabbar-inner,
.planner-spec-tabs .mud-tabs-tabbar-content,
.planner-spec-tabs .mud-tabs-tabbar-wrapper {
    min-height: 0 !important;
}

.spec-tabs .mud-tabs-tabbar-content,
.planner-character-tabs .mud-tabs-tabbar-content,
.planner-spec-tabs .mud-tabs-tabbar-content {
    display: flex;
    align-items: center;
}

.spec-tabs .mud-tab,
.planner-character-tabs .mud-tab,
.planner-spec-tabs .mud-tab {
    min-height: 0 !important;
    height: 30px !important;
    line-height: 1 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* Signed out, the character strip is a spec picker rather than tabs, and the dense input slot's
   8.5px of vertical padding stands the row at ~40px — taller than the 30px bar it replaces. Force
   the same height chain down, flattening the padding so a min-height alone isn't fighting a slot
   that is already taller than the target. Scoped to the strip, so the picker keeps its normal
   height everywhere else it is used. */
.planner-character-tabs .mud-input-control,
.planner-character-tabs .mud-input-slot {
    min-height: 0 !important;
}

.planner-character-tabs .mud-input-slot {
    height: 30px !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    font-size: 0.875rem;
}

/* The spec strip's active tab carries its own controls, and MudBlazor pads a small icon
   button's 20px glyph out to a 30px box — the whole height of the compact bar, so the tab
   is sized by its buttons rather than by the name it exists to show. Dropping the padding
   leaves each one the size of the spec icon already beside the name. Scoped to the tabs
   themselves, so the trailing add-plan picker in the bar keeps its own hit area. */
.planner-spec-tabs .mud-tab .mud-icon-button {
    padding: 0;
}

/* Denser cards on a working surface: MudBlazor pads card content 16px with a 24px
   last-child bottom, which costs a page several rows of vertical space across every
   card it draws. Scoped to the pages that opt in. The top is zero because the header
   already pays 6px below itself — paying both separates the two by more than either
   was asked for. */
.dense-surface .mud-card-content {
    padding: 0 12px 12px;
}

/* The header pays the same 16px, for a single row of title and actions. Its title is
   an h6 sized for a page heading rather than a card label, so it shrinks with the
   padding — together that is ~20px of chrome back per card. */
.dense-surface .mud-card-header {
    padding: 6px 12px;
}

.dense-surface .mud-card-header .mud-typography-h6 {
    font-size: 1rem;
    line-height: 1.5;
}

/* Header actions pull themselves up and out by 8px, which assumes the 16px padding
   they were designed against — against 6px 12px that lifts a save button above the
   card's top border. Neutralising both offsets centres the actions in the row and
   gives them back the full right-hand padding. */
.dense-surface .mud-card-header-actions {
    align-self: center;
    margin-top: 0;
    margin-inline-end: 0;
}

/* A disabled button emits no pointer events, so the tooltip explaining *why* it is
   disabled would never open. Letting the pointer through to the tooltip root — which
   carries the hover handlers — is what makes those hints reachable. */
.dense-surface .mud-tooltip-root .mud-button-root:disabled {
    pointer-events: none;
}

/* Accent scale — one full-strength token for the 1-2px marks, two washes for anything that
   fills area. Named here so a later adopter picks a tier instead of inventing an alpha; the
   wash percentages are the pair GearPickerList already uses for its rank fills. */
:root {
    --accent-mark: var(--mud-palette-tertiary);
    --accent-wash: color-mix(in srgb, var(--mud-palette-tertiary) 8%, transparent);
    --accent-wash-strong: color-mix(in srgb, var(--mud-palette-tertiary) 14%, transparent);
}

/* Accent — MudBlazor draws both of the framework's state marks (the tab slider and the
   input focus indicator) from Primary, which the theme holds at near-white. Retargeting
   them here rather than per-component means a new tab strip or input picks up the accent
   without anyone passing a parameter — and focus rings take no parameter at all. Each
   selector mirrors MudBlazor's own, so it wins on source order while the higher-specificity
   error states still override it. */
.mud-tab-slider {
    background: var(--mud-palette-tertiary);
}

.mud-input.mud-input-underline:after,
.mud-input.mud-input-filled.mud-input-underline:after {
    border-bottom-color: var(--mud-palette-tertiary);
}

.mud-input.mud-input-outlined:focus-within > .mud-input-outlined-border,
.mud-input.mud-input-outlined:focus-within .mud-shrink > .mud-input-outlined-border {
    border-color: var(--mud-palette-tertiary);
}

/* The rule above accents focus on inputs only; everything else MudBlazor draws clears the
   browser's outline (`button`, `.mud-button-root`, `a:focus-visible`, `.mud-chip`,
   `.mud-list-item-clickable` all set `outline: 0`) and marks focus with a Primary-tinted
   overlay, which the theme holds at near-white — so a keyboard user loses the caret the
   moment they leave a field. One accent ring puts the same mark on every stop. It is an
   outline rather than a border or a wash, so a focused control never reads as a selected
   one, and it is `:focus-visible` rather than `:focus`, so a mouse click still gains
   nothing the browser would otherwise suppress. Element selectors are enough to outrank
   MudBlazor's class-level `outline: 0`, and tie its `button:focus` / `a:focus-visible`
   pair on specificity — which this file then wins on source order. Negative tabindex is
   excluded: a dialog or popover the framework focuses programmatically is not a tab stop
   and should not be ringed like one, and so is an input root — a select's focusable slot
   already carries the border treatment above and would otherwise wear both. A switch
   focuses its input, which is a transparent overlay — an outline there would be invisible
   — so its ring goes on the track container holding that input. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:not([tabindex="-1"], .mud-input-root):focus-visible,
.mud-tab:focus-visible,
.mud-switch-span:has(.mud-switch-input:focus-visible) {
    outline: 2px solid var(--accent-mark);
    outline-offset: 2px;
}

/* The toggle group and the tab bar both hide their overflow to keep their own rounded edge,
   which would crop an outset ring away. Turning the offset inward keeps the same 2px mark
   inside the control's own box. */
.mud-toggle-item:focus-visible,
.mud-tab:focus-visible {
    outline-offset: -2px;
}

/* The admin drawer is the only nav outside the public header, and MudBlazor marks its active
   link in Primary. Giving it the header's treatment — white label over a 2px accent underline —
   means "you are here" reads the same in both navs. The selector matches the specificity of
   MudBlazor's own `.mud-navmenu-default` rule and wins on source order. */
.admin-nav.mud-navmenu .mud-nav-link.active:not(.mud-nav-link-disabled) {
    color: #fff;
    text-decoration: underline;
    text-decoration-color: var(--accent-mark);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

/* Tier list — one row per band. Four of these share a screen in the role-quadrant layout, so the
   compact sizing is the base rather than an override on top of a roomier default. The band colour is
   set inline from WowQualityColors, which is what keeps the rank palette in Core with no second copy
   of it here. */
.tier-row {
    display: flex;
    margin-bottom: 8px;
    border-radius: 8px;
    overflow: hidden;
}

.tier-label {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    padding: 6px;
    font-size: 1.6rem;
    font-weight: bold;
    color: #fff;
}

.tier-specs {
    flex: 1;
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    padding: 8px;
    background-color: rgba(255, 255, 255, 0.05);
}

.spec-card {
    cursor: pointer;
    padding: 2px;
    width: fit-content;
    transition: transform 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.spec-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}

.spec-icon {
    width: 48px;
    height: 48px;
    border-radius: 8px;
    border: 2px solid rgba(255, 255, 255, 0.1);
}

.spec-perf-label {
    font-size: 0.6rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.75);
    letter-spacing: 0.02em;
    line-height: 1;
}

/* Loading and Error States */
.loading-container {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 300px;
}

.error-container {
    margin: 32px 0;
}

/* Footer Styles */
.footer {
    margin-top: 64px;
    padding: 32px 0;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    text-align: center;
}

.footer-links {
    display: flex;
    justify-content: center;
    gap: 24px;
    margin: 16px 0;
}

/* Header Navigation */
.header-nav-group {
    display: flex;
    align-items: stretch;
    gap: 0;
    height: 64px;
}

.header-nav-link {
    display: inline-flex;
    align-items: flex-end;
    height: 64px;
    padding: 0 20px 16px;
    color: rgba(255, 255, 255, 0.7);
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 500;
    transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out;
}

.header-nav-link:hover {
    color: #fff;
    background-color: rgba(255, 255, 255, 0.08);
    text-decoration: none;
}

.header-nav-link-active {
    color: #fff;
    text-decoration: underline;
    text-decoration-color: var(--mud-palette-tertiary);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

.header-nav-link-active:hover {
    text-decoration: underline;
    text-decoration-color: var(--mud-palette-tertiary);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

.header-nav-link-disabled {
    color: rgba(255, 255, 255, 0.35);
    cursor: not-allowed;
}

.header-nav-link-disabled:hover {
    color: rgba(255, 255, 255, 0.35);
    background-color: transparent;
}

/* The same nav links laid on a paper surface rather than the app bar: a shorter row, palette text
   colours instead of the bar's whites, and wrapping onto further lines so every entry stays visible
   at any width. Used by the planner's tier/boss strip. */
.header-nav-group-paper {
    height: auto;
    flex-wrap: wrap;
}

.header-nav-group-paper .header-nav-link {
    align-items: center;
    height: 36px;
    padding: 0 12px;
    color: var(--mud-palette-text-secondary);
}

.header-nav-group-paper .header-nav-link:hover {
    color: var(--mud-palette-text-primary);
    background-color: var(--mud-palette-action-default-hover);
}

.header-nav-group-paper .header-nav-link-active {
    color: var(--mud-palette-text-primary);
}

/* Season picker — the nav group stretches its children to the full 64px bar, which an input must
   not do, so the picker is centred in a fixed-width box of its own. */
.header-season-select {
    display: flex;
    align-items: center;
    width: 180px;
    margin-right: 16px;
}

/* Planner boss list — make the whole card read as a clickable tile. */
.planner-boss-card {
    cursor: pointer;
    transition: border-color 0.15s ease-in-out, transform 0.15s ease-in-out;
}

.planner-boss-card:hover {
    border-color: rgba(255, 255, 255, 0.3);
    transform: translateY(-2px);
}

/* Reorderable drop lists — MudBlazor gives a reordering drop zone an absolutely positioned
   .mud-drop-item-preview-start overlay (20px tall, full width, z-index 1) as the "drop above the
   first item" target, and .mud-drop-zone is position: relative, so it sits over most of row 1 and
   swallows clicks on anything unpositioned there (a link's <a>). Take it out of hit-testing at
   rest and hand it back for the duration of a drag: ApplyDropClassesOnDragStarted on the container
   applies CanDropClass to its zones while a drag transaction is running, so reorder-active is only
   present when the overlay is actually needed. Opt-in by class, so it cannot reach a drop zone
   (MudTabs) that has not asked for it. */
.reorderable-list .mud-drop-item-preview-start {
    pointer-events: none;
}

.reorderable-list .reorder-active .mud-drop-item-preview-start {
    pointer-events: auto;
}

/* Blazor Error UI */
#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}
