/*
 * Admin chrome. Global rather than scoped .razor.css on purpose: every class here is handed to
 * a MudBlazor component, and Blazor's CSS isolation only stamps its scope attribute on markup
 * the owning component renders itself — a class passed down to a child component's element
 * would silently never match (the same trap documented for TorchButton in
 * Torch.Shared.DesignSystem/wwwroot/css/components.css).
 *
 * Note what is deliberately absent: the geometric texture. It belongs to accent panels on the
 * public site, never to persistent chrome like an app bar or drawer.
 */

/* ---------------------------------------------------------------- mudblazor material */

/*
 * TorchAdminTheme.cs gives MudBlazor the right *colours*. This block gives it the right
 * *substance*, which is a separate problem: recoloured Material Design is still Material Design —
 * elevation shadows doing the work that material should do, filled paper, pill-shaped nav rows,
 * and a light-to-dark ramp on every raised thing. The admin came out looking like a competent
 * dark dashboard rather than like the same world as the game in front of it.
 *
 * So the public site's language is carried across wholesale: flat matte faces, a groove chiselled
 * inside the edge instead of a drop shadow (--torch-chisel), hairlines that fade before they meet
 * an edge, and the ember accent spent as a marker rather than as a fill. The forged plate on
 * primary actions comes from the same --torch-plate-* tokens the public site's CTA uses, so the
 * two can no longer drift apart.
 *
 * Everything is scoped under .torch-admin (the class on MudLayout) where it can be. Overlays —
 * dialogs, popovers, pickers — render at the document root, outside that subtree, so those few
 * selectors are unscoped; they are safe unscoped because MudBlazor is only ever mounted under
 * /admin (Docs/08-design-system.md).
 */

.torch-admin .mud-paper {
    background-color: var(--torch-surface-2);
    border: 1px solid var(--torch-border);
    box-shadow: var(--torch-shadow-md), var(--torch-chisel);
}

/*
 * MudBlazor paints its dark-theme elevation overlay as a background-*image* on paper, so clearing
 * that property is what makes the face read as matte rather than tinted-by-elevation.
 *
 * The :not() is load-bearing. The stat tiles carry the stonework lattice in that same property,
 * and this rule outranks .torch-textured (two classes to one) — without the exclusion it silently
 * erased the texture and the tiles rendered as flat rectangles, which is exactly what happened
 * the first time round.
 */
.torch-admin .mud-paper:not(.torch-textured) {
    background-image: none;
}

/*
 * MudMainContent supplies its own padding-top to clear the fixed app bar. A `pa-6` utility on it
 * overwrote that with a flat 24px — shorthand beats the component's longhand — which buried the
 * page eyebrow underneath the bar on every admin page. The layout now applies only px-/pb-
 * utilities so the top offset survives, and this restates it with the page's breathing room.
 *
 * Deliberately not `calc(48px + …)`: --mud-appbar-height reports 64px, the *non*-dense height,
 * while this bar is Dense and measures 48. Building on the variable rather than on the measured
 * height keeps this correct if the bar ever stops being dense.
 */
.torch-admin .mud-main-content {
    padding-top: calc(var(--mud-appbar-height) + var(--torch-space-8));
}

/* Chrome is flat, here as on the public site: a solid surface, one hairline, no texture and no
   inner groove. The groove says "this piece was cut out and set down"; persistent chrome was
   never set down. */
.torch-admin .mud-appbar,
.torch-admin .mud-drawer {
    background-color: var(--torch-surface-1);
    box-shadow: none;
    border: 0;
}

.torch-admin__bar {
    position: relative;
    border-bottom: 1px solid var(--torch-border);
    backdrop-filter: blur(8px);
}

/* The same ember hairline that sits under the public site's header and along the top of its
   footer — the admin is bracketed by the accent for the same reason the site is. */
.torch-admin__bar::after {
    content: "";
    position: absolute;
    inset: auto 0 -1px 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(201, 151, 63, 0.35), transparent);
    pointer-events: none;
}

.torch-admin__brand-logo {
    height: 1.5rem;
    width: auto;
    opacity: 0.9;
}

/* A hairline between the wordmark and the surface name — the same divider motif as the public
   header's sign-out — so "Torch" and "Admin" read as one lockup rather than as two words that
   happen to sit next to each other. The label is the quieter half of that lockup: the logo is the
   product, this only says which door you came in. */
.torch-admin__brand-label {
    position: relative;
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-sm);
    letter-spacing: var(--torch-tracking-eyebrow);
    text-transform: uppercase;
    margin-left: var(--torch-space-4);
    padding-left: var(--torch-space-4);
    color: var(--torch-text-muted);
}

.torch-admin__brand-label::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 1px;
    height: 1rem;
    transform: translateY(-50%);
    background: linear-gradient(180deg, transparent, var(--torch-border-strong), transparent);
}

.torch-admin__user {
    color: var(--torch-text-secondary);
    margin-right: var(--torch-space-4);
}

.torch-admin__drawer {
    border-right: 1px solid var(--torch-border);
}

/*
 * The current page is marked by an ember bar cut into the left edge of the row, not by Material's
 * filled pill. A pill is a button; a nav row is a place you already are, and it should be marked
 * the way a page is tabbed rather than the way a control is pressed.
 *
 * Two details do the anti-plastic work, and both are about where the light comes from:
 *
 *  - The rows are square. A rounded filled chip floating inside a drawer is the single most
 *    "app-framework" shape in Material, and at nav width it reads as a moulded tab.
 *  - The wash is a gradient that fades out to the right, not a uniform fill. A flat translucent
 *    rectangle is a swatch; a wash that decays away from the ember bar reads as light spilling
 *    from the marker across the stone, which is the same logic as the plate's bottom bloom.
 */
.torch-admin .mud-nav-link {
    position: relative;
    border-radius: 0;
    color: var(--torch-text-secondary);
    font-size: var(--torch-text-base);
    letter-spacing: 0.01em;
    transition: color var(--torch-duration-fast) var(--torch-ease-out),
        background var(--torch-duration-fast) var(--torch-ease-out);
}

.torch-admin .mud-nav-link .mud-icon-root {
    color: var(--torch-text-muted);
    transition: color var(--torch-duration-fast) var(--torch-ease-out);
}

.torch-admin .mud-nav-link:hover {
    background: linear-gradient(90deg, rgba(255, 235, 205, 0.075) 0%, transparent 88%);
    color: var(--torch-text-primary);
}

.torch-admin .mud-nav-link:hover .mud-icon-root {
    color: var(--torch-text-secondary);
}

.torch-admin .mud-nav-link.active {
    background: linear-gradient(90deg, rgba(201, 151, 63, 0.14) 0%, rgba(201, 151, 63, 0.025) 58%, transparent 100%);
    color: var(--torch-accent-strong);
}

.torch-admin .mud-nav-link.active::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 2px;
    background: var(--torch-accent);
    box-shadow: 0 0 8px rgba(201, 151, 63, 0.55);
}

.torch-admin .mud-nav-link.active .mud-icon-root {
    color: var(--torch-accent);
}

/* ---------------------------------------------------------------- mudblazor controls */

/* Primary actions are the same forged plate as the public site's CTA, from the same tokens.
   Material's uppercase-and-ripple stays off it — the plate is stamped, not pressed. */
.torch-admin .mud-button-filled.mud-button-filled-primary {
    background: var(--torch-plate-face);
    color: var(--torch-plate-label);
    border: 1px solid var(--torch-plate-rim);
    box-shadow: var(--torch-plate-shadow);
    text-shadow: 0 0 16px rgba(224, 160, 80, 0.4);
}

.torch-admin .mud-button-filled.mud-button-filled-primary:hover {
    background: var(--torch-plate-face-hot);
    border-color: var(--torch-plate-rim-hot);
    color: var(--torch-plate-label-hot);
    box-shadow: var(--torch-plate-shadow-hot);
}

.torch-admin .mud-button-outlined {
    background-color: var(--torch-surface-2);
    border-color: var(--torch-border);
    color: var(--torch-text-primary);
    box-shadow: var(--torch-chisel);
}

.torch-admin .mud-button-outlined:hover {
    background-color: var(--torch-surface-3);
    border-color: var(--torch-border-strong);
}

/*
 * Inputs are sockets cut into the surface, the inverse of the plate — the same treatment the
 * launcher's build selector gets on the public site. Material's floating-label outline notch is
 * left alone; only the material inside it changes.
 */
.torch-admin .mud-input.mud-input-outlined .mud-input-slot {
    background-color: var(--torch-surface-1);
    box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.45);
}

.torch-admin .mud-input-outlined-border {
    border-color: var(--torch-border);
}

.torch-admin .mud-input.mud-input-outlined:hover .mud-input-outlined-border {
    border-color: var(--torch-border-strong);
}

.torch-admin .mud-input.mud-input-outlined.mud-focused .mud-input-outlined-border {
    border-color: var(--torch-accent);
    border-width: 1px;
}

/* Tables: the head row is a legend stamped above the data, and the rule under it fades out at
   both ends like every other engraved divider in the product. */
.torch-admin .mud-table {
    background-color: var(--torch-surface-2);
}

.torch-admin .mud-table-head .mud-table-cell {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xs);
    font-weight: 600;
    letter-spacing: var(--torch-tracking-eyebrow);
    text-transform: uppercase;
    color: var(--torch-accent);
    border-bottom: 1px solid var(--torch-border-strong);
}

.torch-admin .mud-table-body .mud-table-cell {
    border-bottom: 1px solid var(--torch-border);
}

.torch-admin .mud-table-body .mud-table-row:hover .mud-table-cell {
    background-color: rgba(201, 151, 63, 0.05);
}

/*
 * Material's switch — a grey lozenge with a floating white disc — is the most recognisably
 * "settings app" control in the framework and was the last plastic thing left in the console.
 *
 * Rebuilt from the two materials everything else here is made of: the track is a socket cut into
 * the surface (dark, inset), the thumb is a small plate standing proud of it. Switched on, the
 * socket fills with ember and the plate takes the accent — the state is legible from the fill, not
 * from a colour swap on a disc.
 *
 * The checked state is matched with :has() on the real <input type=checkbox> rather than on
 * MudBlazor's own state class, so it stays correct if the framework renames that class.
 */
.torch-admin .mud-switch-track {
    background-color: var(--torch-surface-1);
    border: 1px solid var(--torch-border);
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5);
    opacity: 1;
}

.torch-admin .mud-switch-thumb-medium,
.torch-admin .mud-switch-thumb {
    background-color: var(--torch-surface-3);
    border: 1px solid var(--torch-border-strong);
    box-shadow: var(--torch-shadow-sm);
}

.torch-admin .mud-switch-span:has(.mud-switch-input:checked) .mud-switch-track {
    background-color: color-mix(in oklab, var(--torch-accent) 24%, var(--torch-surface-1));
    border-color: var(--torch-accent-muted);
}

.torch-admin .mud-switch-span:has(.mud-switch-input:checked) .mud-switch-thumb-medium,
.torch-admin .mud-switch-span:has(.mud-switch-input:checked) .mud-switch-thumb {
    background-color: var(--torch-accent);
    border-color: var(--torch-plate-rim-hot);
}

/* Chips carry the badge treatment: flat face, hairline rim, tracked caps, no gradient and no
   glow — see TorchBadge.razor.css for why. */
.torch-admin .mud-chip {
    border-radius: var(--torch-radius-sm);
    font-size: var(--torch-text-xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    box-shadow: none;
}

/*
 * Severity is carried by a 2px bar on the leading edge, not by tinting the panel — the same rule
 * as TorchAlert.razor.css on the public site, and for the same reason: an alert should read as the
 * same material as the surfaces around it, marked, rather than as a differently-coloured box
 * dropped onto the page.
 *
 * MudBlazor's text variant does the opposite. It tints the message, the icon and the background
 * with the severity colour, which is how the console alert ended up as blue-on-navy inside a warm
 * hairline — two products in one box. Neutralising the face here and colouring only the edge bar
 * and the icon is what lets it sit down next to the stat tiles.
 *
 * The neutral default is what "info" means in this design system: absence of colour. Only the
 * three severities that genuinely demand attention spend any.
 */
.torch-admin .mud-alert {
    position: relative;
    overflow: hidden;
    background-color: var(--torch-surface-2);
    border: 1px solid var(--torch-border);
    border-radius: var(--torch-radius-md);
    box-shadow: var(--torch-chisel);
}

.torch-admin .mud-alert::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 2px;
    background: var(--torch-border-strong);
}

.torch-admin .mud-alert .mud-alert-message {
    color: var(--torch-text-secondary);
}

.torch-admin .mud-alert .mud-alert-icon {
    color: var(--torch-text-muted);
}

.torch-admin .mud-alert-text-success::before {
    background: var(--torch-success);
}

.torch-admin .mud-alert-text-success .mud-alert-icon {
    color: var(--torch-success);
}

.torch-admin .mud-alert-text-warning::before {
    background: var(--torch-accent);
}

.torch-admin .mud-alert-text-warning .mud-alert-icon {
    color: var(--torch-accent);
}

.torch-admin .mud-alert-text-error::before {
    background: var(--torch-danger);
}

.torch-admin .mud-alert-text-error .mud-alert-icon {
    color: var(--torch-danger);
}

/* Overlays render at the document root, outside .torch-admin — see the note at the top. */
.mud-dialog,
.mud-popover {
    background-color: var(--torch-surface-2);
    background-image: none;
    border: 1px solid var(--torch-border);
    box-shadow: var(--torch-shadow-lg), var(--torch-chisel);
}

/* Page heading rhythm — one composition per admin page: eyebrow, title, and an optional
   trailing action row. */
.torch-admin-page__header {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--torch-space-4);
    padding-bottom: var(--torch-space-4);
    margin-bottom: var(--torch-space-6);
}

/* An engraved rule closing the page head. It fades to the right rather than to both sides — the
   heading it underlines is left-aligned, so a symmetric rule would float unattached to it. */
.torch-admin-page__header::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 1px;
    background: linear-gradient(90deg, var(--torch-border-strong) 0%, transparent 72%);
}

.torch-admin-page__title {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xl);
    line-height: var(--torch-leading-display);
    margin: 0;
}

.torch-admin-page__subtitle {
    color: var(--torch-text-secondary);
    margin: var(--torch-space-2) 0 0;
    max-width: 46rem;
}

/* Stat tiles on the overview page. */
.torch-admin-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: var(--torch-space-4);
    margin-bottom: var(--torch-space-8);
}

/*
 * The one place the admin gets the worked-stonework lattice. This is within the rule that texture
 * is a panel treatment and never chrome: the tiles are accent panels, the app bar and drawer above
 * them stay flat. It is also the whole reason the overview stops reading as a dashboard — four
 * pieces of cut stone laid on a dark desk, instead of four grey rectangles with numbers in them.
 *
 * The vignette is not decoration. Without it the 480px tile gets visibly cropped by a ~13rem tile
 * and the panel reads as a scrap of wallpaper; fading the pattern out before the edges is what
 * makes it read as material catching the light. Same trick, same reason, as .torch-panel.
 */
.torch-admin-stat {
    position: relative;
    padding: var(--torch-space-6);
    overflow: hidden;
}

.torch-admin-stat::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(120% 90% at 50% 45%,
            transparent 0%,
            transparent 40%,
            var(--torch-surface-2) 100%);
}

.torch-admin-stat > * {
    position: relative;
}

.torch-admin-stat__label {
    font-size: var(--torch-text-xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--torch-text-muted);
    margin: 0 0 var(--torch-space-2);
}

.torch-admin-stat__value {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xl);
    line-height: 1;
    color: var(--torch-text-primary);
    margin: 0;
}

.torch-admin-stat__hint {
    font-size: var(--torch-text-sm);
    color: var(--torch-text-muted);
    margin: var(--torch-space-2) 0 0;
}

.torch-admin-links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--torch-space-3);
}

.torch-admin-mono {
    font-family: var(--torch-font-mono);
    font-size: var(--torch-text-sm);
}
