/* ChromeHounds Forever - the site's look, taken from the launcher (ChromeHoundsForeverApp/UI/Resources:
   Colors.xaml and Styles.xaml), so the website and the app read as one thing.

   - Dark military green behind everything, grey panels and bars over it, metal grey text on the green.
   - Square grey buttons with a black edge and black bold lettering in the ChromeHounds mono face.
   - Hover is the launcher's slow pulse between two rusty oranges. The launcher also pulses a CHECKED
     toggle; here an active button is held at solid orange instead - the planner can have four or five
     things active at once, and four pulsing together is noise rather than a signal.
   - Panels are the launcher's GroupBox: a black tab with a slanted end above a grey body.

   Plain reading text stays in the system face, as it does in the launcher; the game's faces are for
   buttons, labels and headings, where they read best. */

@font-face {
    font-family: "ChromeHounds";
    src: url("fonts/ChromeHoundsFont.ttf") format("truetype");
    font-display: swap;
}

@font-face {
    font-family: "ChromeHounds Mono";
    src: url("fonts/ChromeHoundsMonoFont.ttf") format("truetype");
    font-display: swap;
}

:root {
    /* The launcher's palette, by its own names. */
    --dark-green: #3f4d40;
    --metal-grey: #bfbfbb;
    --background-grey: #7b8179;
    --button-grey: #696d66;
    --button-orange: #aa6746;
    --button-dark-orange: #925e47;
    --slider-orange: #ab6a40;

    /* What they are used for. */
    --ground: var(--dark-green);
    --panel: var(--background-grey);
    --button: var(--button-grey);
    --edge: #000000;
    --ink-on-green: var(--metal-grey);
    --ink-on-grey: #0e110e;
    --muted-on-grey: #2a2f29;
    --accent: var(--button-orange);

    /* Chart series: dark enough to read on the grey panels, and apart from each other in hue. */
    --series-0: #1c1d1b;
    --series-1: #7a2e0c;
    --series-2: #0f3a6e;
    --series-3: #57307a;
    --series-4: #1d5a2a;
    --series-5: #6e5400;
    --series-6: #7a1040;
    --series-7: #005a5a;

    --face-display: "ChromeHounds", system-ui, sans-serif;
    --face-ui: "ChromeHounds Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
    --face-text: system-ui, -apple-system, "Segoe UI", sans-serif;

    color-scheme: dark;
}

* { box-sizing: border-box; }

html { scrollbar-color: var(--button) var(--edge); }

body {
    margin: 0;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    background: var(--ground);
    color: var(--ink-on-green);
    font: 400 1rem/1.55 var(--face-text);
}

a { color: #e0a47e; }

h1, h2, h3 {
    font-family: var(--face-display);
    font-weight: 400;
    letter-spacing: 0.02em;
}

h1 { font-size: 1.8rem; margin: 0 0 0.75rem; }
h1:focus { outline: none; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ---- the launcher's pulse ---- */

@keyframes chf-pulse {
    from { background-color: var(--button-orange); }
    to { background-color: var(--button-dark-orange); }
}

/* ---- buttons ----
   <button>, and anything given the .button class - links and file pickers that should look like one. */

button,
.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    font: 700 0.9rem/1.2 var(--face-ui);
    color: #000000;
    background: var(--button);
    border: 1px solid var(--edge);
    border-radius: 0;
    padding: 0.35rem 0.7rem;
    cursor: pointer;
    text-decoration: none;
}

button:hover:not(:disabled),
.button:hover {
    animation: chf-pulse 0.6s ease-in-out infinite alternate;
}

/* Active: held at solid orange - see the note at the top. */
button.on,
button[aria-pressed="true"],
.button.active {
    background: var(--button-orange);
}

button:disabled {
    background: #a9a9a9;
    opacity: 0.6;
    cursor: default;
}

input[type="text"],
input:not([type]),
input[type="search"] {
    font: 400 0.95rem/1.2 var(--face-ui);
    color: #000000;
    background: var(--metal-grey);
    border: 1px solid var(--edge);
    border-radius: 0;
    padding: 0.3rem 0.5rem;
}

input[type="range"] { accent-color: var(--slider-orange); }
input[type="checkbox"] { accent-color: var(--slider-orange); }

/* ---- panels: the launcher's GroupBox ---- */

/* A column, so the tab sits on the body with no gap from the line it would otherwise sit on. */
.panel {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.panel-title {
    align-self: flex-start;
    margin: 0;
    padding: 0.2rem 2rem 0.15rem 0.6rem;
    background: #000000;
    color: var(--metal-grey);
    font: 400 0.85rem/1.3 var(--face-ui);
    letter-spacing: 0.04em;
    border-top-left-radius: 6px;
    /* The slanted end: the launcher draws it as a triangle beside the tab. */
    clip-path: polygon(0 0, calc(100% - 1.3rem) 0, 100% 100%, 0 100%);
}

.panel-body {
    background: var(--panel);
    color: var(--ink-on-grey);
    border: 1px solid var(--edge);
    padding: 0.65rem;
    flex: 1;
}

.panel-body .muted { color: var(--muted-on-grey); }
.panel-body a:not(.button) { color: #4a2410; }

/* A chart panel's title folds it (charts.js): the tab's words become a button, with an arrow down while
   the panel is open and right while it is folded to the tab alone. */
.panel-fold {
    all: unset;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    cursor: pointer;
}

.panel-fold::before {
    content: "";
    border-style: solid;
    border-width: 0.32rem 0.28rem 0 0.28rem;
    border-color: currentColor transparent transparent transparent;
}

.panel.folded .panel-fold::before,
.fold-strip .panel-fold::before {
    border-width: 0.28rem 0 0.28rem 0.32rem;
    border-color: transparent transparent transparent currentColor;
}

.panel-fold:hover { color: var(--accent); }
.panel-fold:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.panel.folded > .panel-body {
    display: none;
}

/* ---- site header and footer: the launcher's grey bars ---- */

.site-header,
.site-footer {
    display: flex;
    align-items: center;
    gap: 0.75rem 1.25rem;
    flex-wrap: wrap;
    padding: 0.4rem 0.9rem;
    background: var(--panel);
    color: var(--ink-on-grey);
    border-color: var(--edge);
    border-style: solid;
    border-width: 0;
}

.site-header { border-bottom-width: 1px; }
.site-footer { border-top-width: 1px; margin-top: auto; font: 400 0.8rem/1.4 var(--face-ui); }
.site-footer a { color: #4a2410; }

.site-brand {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    color: var(--ink-on-grey);
    text-decoration: none;
    font: 400 1.25rem/1 var(--face-display);
    letter-spacing: 0.03em;
}

.site-brand img { height: 2rem; width: auto; }

.site-header nav {
    display: flex;
    gap: 0.35rem;
    margin-left: auto;
}

.site-main {
    width: 100%;
    max-width: 1100px;
    margin: 0 auto;
    padding: 1.25rem 1rem 2.5rem;
}

.notice { color: var(--ink-on-green); opacity: 0.85; }

/* The planner uses the whole screen: its map is sized to the screen and its tools sit beside it,
   which the reading width every other page keeps would squeeze into a strip. */
.site-main:has(.planner) {
    max-width: none;
}

/* ---- the launcher's loading mark: the CHF mark lit segment by segment ---- */

.loading {
    display: grid;
    justify-items: center;
    gap: 0.75rem;
    padding: 3rem 0;
    color: var(--ink-on-green);
    font: 400 0.9rem/1.3 var(--face-ui);
}

.load-mark {
    position: relative;
    width: 7rem;
    aspect-ratio: 560 / 480;
}

.load-mark img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    animation: chf-segment 0.9s linear infinite;
}

.load-mark img:first-child {
    opacity: 1;
    animation: none;
    /* The bare mark, lightened so the lit segments stand out against it on the green. */
    filter: brightness(1.6) saturate(0.6);
}

/* Started part way through the cycle, a negative delay each, so the mark is already turning when it
   appears rather than lighting its segments in for the first second. */
.load-mark img:nth-child(2) { animation-delay: -0.9s; }
.load-mark img:nth-child(3) { animation-delay: -0.75s; }
.load-mark img:nth-child(4) { animation-delay: -0.6s; }
.load-mark img:nth-child(5) { animation-delay: -0.45s; }
.load-mark img:nth-child(6) { animation-delay: -0.3s; }
.load-mark img:nth-child(7) { animation-delay: -0.15s; }

/* Each segment flares and fades, one after another - faded smoothly rather than in the launcher's
   steps, and a little quicker than its 1.2 s, so the light glides round the mark with a tail behind it. */
@keyframes chf-segment {
    0% { opacity: 0; }
    8% { opacity: 1; }
    25% { opacity: 0.55; }
    45% { opacity: 0.15; }
    60%, 100% { opacity: 0; }
}

/* The mark in the middle of the screen while a page loads (js/loading.js). It covers nothing that can
   be clicked - the page under it stays usable - and fades in, so a page that is nearly in never flashes. */
.page-loading {
    position: fixed;
    inset: 0;
    z-index: 20;
    display: grid;
    place-items: center;
    pointer-events: none;
    animation: page-loading-in 0.2s ease-out;
}

.page-loading .load-mark {
    width: 8rem;
    padding: 1.25rem;
    box-sizing: content-box;
    background: color-mix(in srgb, var(--dark-green) 88%, transparent);
    border: 1px solid var(--edge);
    box-shadow: 0 0.4rem 1.6rem rgb(0 0 0 / 0.45);
}

.page-loading .load-mark img {
    inset: 1.25rem;
    width: calc(100% - 2.5rem);
    height: calc(100% - 2.5rem);
}

@keyframes page-loading-in {
    from { opacity: 0; }
}

/* While the centred mark waits on a page's content, the page's own loading mark is hidden, so there is
   only ever one. If the centred mark gives up, the page's own comes back. */
.page-waiting .site-main .loading {
    visibility: hidden;
}

/* ---- pages ---- */

.hero {
    display: grid;
    justify-items: center;
    text-align: center;
    gap: 0.4rem;
    padding: 1.5rem 0 2rem;
}

.hero img { width: 9rem; height: auto; filter: brightness(1.6) saturate(0.6); }
.hero h1 { font-size: 2.4rem; margin: 0.5rem 0 0; }
.hero p { margin: 0; font: 400 1rem/1.4 var(--face-ui); }

/* The home page's tools, two across - four make a square rather than three and one left over - and one
   across on a tablet held upright. */
.tool-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(24rem, 1fr));
    gap: 1.25rem;
}

/* A tool's "i" (ChartInfo) sits on the card's title line, as on the parts pages' charts. */
.tool-card .panel-body { position: relative; display: flex; }

/* The calculator's "i" (ChartInfo) on the Result panel's title line. */
.calc-result-body { position: relative; }

.area-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
    gap: 1.1rem;
}

.area-maps {
    display: grid;
    gap: 0.35rem;
    /* Panels in a row share a height; an area with fewer maps keeps its buttons their own size. */
    align-content: start;
}

.area-maps .button {
    justify-content: space-between;
    width: 100%;
}

.map-id {
    font: 400 0.75rem/1 var(--face-ui);
    opacity: 0.75;
}

/* ---- the part pages ---- */

.crumbs {
    margin: 0 0 0.25rem;
    font: 400 0.85rem/1.3 var(--face-ui);
}

.credit {
    margin-top: 1.5rem;
    font-size: 0.85rem;
    opacity: 0.8;
}

.part-kind {
    display: grid;
    gap: 0.45rem;
    align-content: start;
}

.part-kind .button {
    justify-self: start;
}

.part-filter,
.part-compare-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.75rem;
}

.part-filter select {
    font: 400 0.95rem/1.2 var(--face-ui);
    color: #000000;
    background: var(--metal-grey);
    border: 1px solid var(--edge);
    border-radius: 0;
    padding: 0.25rem 0.4rem;
}

.part-compare-bar .muted {
    font-size: 0.9rem;
    opacity: 0.85;
}

/* The part tables use the whole screen, as the planner does - weapons have fourteen columns, and the
   reading width would put half of them out of sight. */
.site-main:has(.part-table-wrap) {
    max-width: none;
}

/* Where they are still wider than the screen, they scroll sideways inside the page, not the page itself. */
.part-table-wrap {
    overflow-x: auto;
    max-width: 100%;
}

/* A parts list fits the screen: the page is held to the window's height, the table takes what is left
   below the filters and the Compare bar and scrolls inside itself, both ways, its headings stuck at
   its top - so the filters and Compare stay in reach. On a screen too short for that it is an ordinary
   page again. */
@media (min-height: 32rem) {
    body:has(.part-list) {
        height: 100dvh;
    }

    .site-main:has(.part-list) {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
        padding-bottom: 0.75rem;
    }

    .site-main:has(.part-list) > * {
        flex: none;
    }

    .site-main > .part-list {
        flex: 1 1 auto;
        min-height: 10rem;
        overflow: auto;
        border-bottom: 1px solid var(--edge);
    }
}

/* The tick and the Name stay put when the list scrolls sideways: both columns stick to the left, the
   tick at a fixed width so the Name knows where to stick. Stuck cells are opaque - the row's stripe
   or hover laid over the panel - so the columns sliding under them do not show through; the two
   corner headings stick both ways, over everything. */
.part-list > .part-table .tick {
    box-sizing: border-box;
    width: 2.6rem;
    min-width: 2.6rem;
    max-width: 2.6rem;
}

.part-list > .part-table :is(th, td):nth-child(-n + 2) {
    position: sticky;
    left: 0;
    z-index: 1;
}

.part-list > .part-table :is(th, td):nth-child(2) {
    left: 2.6rem;
    box-shadow: inset -1px 0 0 var(--edge);
}

.part-list > .part-table tbody td:nth-child(-n + 2) {
    background: var(--panel);
}

.part-list > .part-table tbody tr:nth-child(even) td:nth-child(-n + 2) {
    background: linear-gradient(rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.06)) var(--panel);
}

.part-list > .part-table tbody tr:hover td:nth-child(-n + 2) {
    background: linear-gradient(rgba(170, 103, 70, 0.25), rgba(170, 103, 70, 0.25)) var(--panel);
}

.part-list > .part-table thead th:nth-child(-n + 2) {
    z-index: 2;
}

/* Stuck a pixel high, and the table's own top border dropped, so no sliver of a row shows above. */
.part-list > .part-table {
    border-top: 0;
}

.part-list > .part-table thead th {
    z-index: 1;
    top: -1px;
}

.part-table {
    border-collapse: collapse;
    width: 100%;
    background: var(--panel);
    color: var(--ink-on-grey);
    border: 1px solid var(--edge);
    font-size: 0.9rem;
}

.part-table th,
.part-table td {
    padding: 0.3rem 0.55rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.25);
    text-align: left;
    white-space: nowrap;
}

.part-table thead th {
    background: #000000;
    color: var(--metal-grey);
    font: 400 0.8rem/1.3 var(--face-ui);
    position: sticky;
    top: 0;
}

.part-table thead a {
    color: var(--metal-grey);
    text-decoration: none;
}

.part-table thead a.sorted {
    color: #e0a47e;
}

.part-table tbody tr:nth-child(even) {
    background: rgba(255, 255, 255, 0.06);
}

.part-table tbody tr:hover {
    background: rgba(170, 103, 70, 0.25);
}

.part-table a {
    color: #000000;
}

.part-table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.part-table .tick {
    width: 2rem;
    text-align: center;
}

.part-table input[type="checkbox"] {
    accent-color: var(--slider-orange);
}

/* A stat the garage does not show, read from the game's data - a round's spread, a missile's turn rate. */
.hidden-stat,
.hidden-stat th,
.part-table thead th.hidden-stat a {
    font-style: italic;
}

/* A comparison: the stat names down the side, one column per part, the better value lit. */
.part-compare tbody th {
    font: 400 0.85rem/1.3 var(--face-ui);
}

.part-compare .best {
    background: var(--button-orange);
    color: #000000;
    font-weight: 700;
}

.part-compare .remove {
    margin-left: 0.4rem;
    color: var(--metal-grey);
    text-decoration: none;
}

/* The stats panel at a reading width, and whatever goes with the part - a weapon's ammo table - taking
   the rest; on a narrow screen they stack. */
.part-detail {
    display: flex;
    flex-wrap: wrap;
    gap: 1.1rem;
    align-items: flex-start;
}

/* The column beside the stats: a weapon's ammo, then a missile's guidance under it. */
.part-detail > .part-side {
    flex: 1 1 28rem;
    min-width: min(100%, 20rem);
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

.part-detail > .part-side:not(:has(> *)) {
    display: none;
}

.part-detail > .panel:first-child {
    flex: 0 1 28rem;
}

.part-detail > .panel {
    flex: 1 1 28rem;
    min-width: min(100%, 20rem);
}

/* ---- the about page: what the site is, then its credits, at a reading width ---- */

.about {
    display: grid;
    gap: 1.1rem;
    max-width: 44rem;
}

.about p { margin: 0 0 0.6rem; }
.about p:last-child { margin-bottom: 0; }

/* A known issue's facts: short labels, so the answers get the width. */
.part-stats.issue-facts th { width: 7rem; white-space: nowrap; vertical-align: top; }
.part-stats.issue-facts { margin-bottom: 0; }

.about .myth-verdict { font-weight: 700; }

/* ---- the part viewer: the garage's turning model (part-viewer.js) ---- */

.part-model > .panel-body {
    display: grid;
    gap: 0.6rem;
}

/* The garage's dark ground behind the part, which its grey reads against. */
.part-viewer {
    position: relative;
    aspect-ratio: 4 / 3;
    max-height: 30rem;
    background: radial-gradient(ellipse at 50% 40%, #4b5b4c, var(--dark-green) 70%);
    border: 1px solid var(--edge);
    overflow: hidden;
    /* A finger dragging across turns it; up and down still scrolls the page. */
    touch-action: pan-y;
}

.part-viewer-canvas {
    display: block;
    width: 100%;
    height: 100%;
    cursor: grab;
}

.part-viewer.active .part-viewer-canvas:active { cursor: grabbing; }

/* The view widget (model-file.js), in the top right of the part viewer and the build renderer. */
.view-gizmo {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    z-index: 1;
    touch-action: none;
}

/* The slow turn's toggle (model-file.js), in the part viewer and the build renderer, on the bottom right of
   the 92px widget: orange while the view turns, as the site's active buttons are. */
.view-spin {
    position: absolute;
    top: calc(0.4rem + 92px - 1.5rem);
    right: 0.4rem;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border: 1px solid var(--edge);
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45);
    color: var(--metal-grey);
    cursor: pointer;
}

.view-spin[aria-pressed="true"] {
    background: var(--accent);
    color: var(--ink-on-grey);
}

/* A part's moving pieces' toggle, under the turn's, and a gun's sound's under that. */
.view-spin.view-animate { top: calc(0.4rem + 92px + 0.3rem); }
.view-spin.view-sound { top: calc(0.4rem + 92px + 0.3rem + 1.5rem + 0.3rem); }
.view-spin.view-effects { top: calc(0.4rem + 92px + 0.3rem + 2 * (1.5rem + 0.3rem)); }

.part-viewer-status {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
}

.part-viewer-status .load-mark { width: 5.5rem; }

.part-viewer-message {
    margin: 0;
    padding: 1rem;
    color: var(--ink-on-green);
    font: 400 0.9rem/1.3 var(--face-ui);
    text-align: center;
}

.paint-form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.9rem;
    align-items: center;
    font: 400 0.85rem/1.3 var(--face-ui);
}

.paint-form label {
    display: inline-flex;
    gap: 0.4rem;
    align-items: center;
}

.paint-form[hidden] { display: none; }

.paint-colours {
    display: inline-flex;
    gap: 0.25rem;
}

.paint-colours input[type="color"] {
    width: 2rem;
    height: 1.6rem;
    padding: 0;
    border: 1px solid var(--edge);
    background: none;
    cursor: pointer;
}

.ammo-bin {
    display: inline-flex;
    gap: 0.4rem;
    align-items: center;
    font: 400 0.85rem/1.3 var(--face-ui);
}

.ammo-bin[hidden] { display: none; }

.part-viewer-hint {
    margin: 0;
    font-size: 0.8rem;
}

/* ---- the build renderer ---- */

.build-renderer .panel-body { display: grid; gap: 0.8rem; }

.build-drop {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.8rem;
    align-items: center;
    padding: 1rem;
    border: 1px dashed var(--edge);
    font: 400 0.9rem/1.3 var(--face-ui);
}

.build-drop.over { border-style: solid; background: rgba(255, 255, 255, 0.06); }
.build-drop p { margin: 0; }
.build-drop .build-help { flex-basis: 100%; font-size: 0.8rem; }

/* THE WORKSPACE: the turning view with the stats under it, and beside them a panel of boxes - paint,
   background, scale, pictures, the sheet. From 900px across (a tablet on its side, a desktop) the two sit
   side by side; narrower (a tablet held upright) the boxes go straight under the view, side by side as they
   fit, and the stats after them. Phones are not laid out for (Samuel, 2026-10-30). */
.build-workspace {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 18rem;
    gap: 1rem;
    align-items: start;
}

.build-stage { display: grid; gap: 0.4rem; min-width: 0; }
.build-stage .build-stats-panel { margin-top: 0.6rem; }

.build-panel {
    display: grid;
    gap: 0.8rem;
    align-content: start;
    font: 400 0.85rem/1.3 var(--face-ui);
}

@media (max-width: 899px) {
    .build-workspace { grid-template-columns: minmax(0, 1fr); }
    /* The panel straight under the view, and the stats after it, so the controls stay by the view. */
    .build-stage { display: contents; }
    .build-panel { order: 1; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
    .build-stage .build-stats-panel { order: 2; }
    .build-panel .build-status,
    .build-panel .build-sheet-options { grid-column: 1 / -1; }
}

.build-status { margin: 0; font: 400 0.9rem/1.3 var(--face-ui); }
.build-status:empty { display: none; }
.build-missing { margin: 0; font-size: 0.8rem; }

.build-view {
    position: relative;
    aspect-ratio: 4 / 3;
    background: radial-gradient(ellipse at 50% 40%, #4b5b4c, var(--dark-green) 70%);
    border: 1px solid var(--edge);
    overflow: hidden;
    touch-action: pan-y;
}

.build-canvas {
    display: block;
    width: 100%;
    height: 100%;
    cursor: grab;
}

.build-canvas:active { cursor: grabbing; }

/* One box of the panel: a titled frame round its controls. */
.build-group {
    display: grid;
    gap: 0.55rem;
    min-width: 0;
    margin: 0;
    padding: 0.5rem 0.7rem 0.7rem;
    border: 1px solid var(--edge);
}

.build-group legend { padding: 0 0.3rem; }
.build-group label { display: inline-flex; gap: 0.35rem; align-items: center; }
.build-group .paint-form { gap: 0.5rem 0.8rem; }
.build-group select { max-width: 100%; }

/* A row of choices; its title, when it has one, on a line of its own above them. */
.build-choices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.9rem;
    align-items: center;
}

.build-choices-title { flex-basis: 100%; color: var(--muted-on-grey); }

.build-group input[type="color"] {
    width: 2rem;
    height: 1.6rem;
    padding: 0;
    border: 1px solid var(--edge);
    background: none;
    cursor: pointer;
}

.build-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.build-save-all[hidden] { display: none; }

.build-stats { max-width: 28rem; }
.build-stats[hidden] { display: none; }
.build-stats td { text-align: right; font-variant-numeric: tabular-nums; }
.build-stats th { white-space: nowrap; }
.build-stats-panel { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 2rem; }
.build-stats-panel .build-stats { flex: 1 1 18rem; }
.build-radar { width: min(100%, 18rem); height: auto; }
.build-radar[hidden] { display: none; }

.build-shots {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
    gap: 0.8rem;
}

.build-shot { margin: 0; }

.build-shot img {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid var(--edge);
}

/* A transparent picture shown on a checkerboard, so the transparency reads as such. */
.build-shot.transparent img {
    background: repeating-conic-gradient(#3a443b 0 25%, #2c342d 0 50%) 0 0 / 16px 16px;
}

.build-shot figcaption {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.3rem;
    font: 400 0.85rem/1.3 var(--face-ui);
}

/* ---- the comparison's "add a part" choice ---- */

.compare-add {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: end;
    margin: 0 0 1rem;
}

.compare-add label {
    display: grid;
    gap: 0.25rem;
    font: 400 0.85rem/1.3 var(--face-ui);
    color: var(--ink-on-green);
}

.compare-add select {
    font: 400 0.95rem/1.2 var(--face-ui);
    color: #000000;
    background: var(--metal-grey);
    border: 1px solid var(--edge);
    border-radius: 0;
    padding: 0.3rem 0.4rem;
    min-width: min(100%, 18rem);
}

.compare-add.scripted .compare-add-go {
    display: none;
}

/* ---- the weapon comparison's ammo choice, above its charts ---- */

.compare-ammo {
    margin: 1.1rem 0;
}

.compare-ammo-fields {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
    gap: 0.6rem 1rem;
    margin-bottom: 0.6rem;
}

.compare-ammo-fields label {
    display: grid;
    gap: 0.25rem;
    font: 400 0.85rem/1.3 var(--face-ui);
}

.compare-ammo-fields select {
    font: 400 0.95rem/1.2 var(--face-ui);
    color: #000000;
    background: var(--metal-grey);
    border: 1px solid var(--edge);
    border-radius: 0;
    padding: 0.3rem 0.4rem;
    width: 100%;
}

/* With the chart script the form sends itself when a choice changes, so the button is not needed. */
.compare-ammo form[data-autosubmit].scripted .compare-ammo-show,
.aim-form.scripted .aim-show {
    display: none;
}

/* The aim of High-Angle weapons (AimFields): a choice and an angle slider with its reading. */
.aim-fields {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
    gap: 0.6rem 1rem;
    margin-bottom: 0.6rem;
}

.aim-fields label {
    display: grid;
    gap: 0.25rem;
    font: 400 0.85rem/1.3 var(--face-ui);
}

.aim-fields select,
.target-fields select {
    font: 400 0.95rem/1.2 var(--face-ui);
    color: #000000;
    background: var(--metal-grey);
    border: 1px solid var(--edge);
    border-radius: 0;
    padding: 0.3rem 0.4rem;
    width: 100%;
}

.aim-angle {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.aim-angle input[type=range] {
    flex: 1;
    min-width: 0;
    accent-color: var(--series-0);
}

/* The spread chart's two charts, each under its own small heading. */
.chart-subtitle {
    margin: 0.4rem 0 0.2rem;
    font: 400 0.85rem/1.3 var(--face-ui);
    color: var(--ink-on-grey);
}

/* The target view (TargetPanel): its distance and size, then one view of every round's box on the
   target, with a key like the charts'. */
.target-form.scripted .target-show {
    display: none;
}

.target-fields {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
    gap: 0.6rem 1rem;
    margin-bottom: 0.8rem;
}

.target-fields label {
    display: grid;
    gap: 0.25rem;
    font: 400 0.85rem/1.3 var(--face-ui);
}

.target-distance {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.target-distance input[type=range] {
    flex: 1;
    min-width: 0;
    accent-color: var(--series-0);
}

.target-distance output {
    min-width: 5ch;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* No wider than it needs: a picture, not a chart with axes to read. */
.target-view {
    display: block;
    width: 100%;
    max-width: 40rem;
    height: auto;
}

.target-view .target { fill: rgba(0, 0, 0, 0.12); stroke: none; }
/* The target's top, above its face, as a round coming down sees it. */
.target-view .target-roof { fill: rgba(0, 0, 0, 0.14); }
.target-view .target-outline { fill: none; stroke: var(--series); stroke-width: 1.2; }
/* A hound outline is a path stretched over its box: keep its line the same width however far it is stretched. */
.target-view path.target-outline { vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.target-view .target-box { fill: var(--series); fill-opacity: 0.16; stroke: var(--series); stroke-width: 1; stroke-dasharray: 4 3; }
.target-view .scale { stroke: var(--ink-on-grey); stroke-width: 2; }
/* Fired direct, the ground at the hound's feet. */
.target-view .target-ground { stroke: var(--muted-on-grey); stroke-width: 1.5; }
.target-view .tick { font: 400 11px var(--face-ui); fill: var(--ink-on-grey); }
.target-view .target-measure line { stroke: var(--ink-on-grey); stroke-width: 1; }
.target-view .target-measure text { font: 400 11px var(--face-ui); fill: var(--ink-on-grey); }

/* Your own hound for the target (charts.js): what the target is, and the buttons to change it. */
.target-own {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.8rem;
    align-items: center;
    margin-bottom: 0.6rem;
    font: 400 0.85rem/1.3 var(--face-ui);
}

.target-own[hidden],
.target-own-reset[hidden] { display: none; }
.target-own-says { flex: 1 1 14rem; }
/* A row of its own across the card, above the view, rather than a column beside it. */
.chart-block > .target-own { flex: 1 1 100%; }

/* Past a round's reach: its entry dimmed, with why. */
.target-block .chart-legend li { flex-wrap: wrap; }
.target-block .chart-legend li.target-unreachable label { opacity: 0.55; }
.target-block .target-note {
    display: block;
    flex-basis: 100%;
    font: 400 0.8rem/1.3 var(--face-ui);
    color: var(--muted-on-grey);
}

.target-block .target-note:empty {
    display: none;
}

/* A round drawn with one before it, at this distance (TargetView.Alike): its entry hidden, its name in that one's. */
.target-block .chart-legend li.target-merged {
    display: none;
}

/* Free only for a fixed angle; otherwise it shows the aim's own angle, greyed. */
.aim-angle input[type=range]:disabled,
.aim-angle input[type=range]:disabled + output {
    opacity: 0.55;
}

.aim-angle output {
    min-width: 3ch;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* ---- the ballistics charts: server-drawn SVG, to the panel's width ---- */

/* Each round's colour comes from its series-n class (Series.Class), never a style attribute. */
.series-0 { --series: var(--series-0); }
.series-1 { --series: var(--series-1); }
.series-2 { --series: var(--series-2); }
.series-3 { --series: var(--series-3); }
.series-4 { --series: var(--series-4); }
.series-5 { --series: var(--series-5); }
.series-6 { --series: var(--series-6); }
.series-7 { --series: var(--series-7); }

.chart .line,
.chart .landing,
.splash-rings .ring-edge,
.splash-rings .ring-core { stroke: var(--series); }

.chart .bar,
.swatch { fill: var(--series); background: var(--series); }

.splash-rings stop { stop-color: var(--series); }


/* Full width - even first in the row, as on the weapon comparison, where no stats panel comes before. */
.part-detail > .panel.part-charts,
.part-detail > .live-charts > .panel.part-charts {
    flex: 1 1 100%;
    min-width: min(100%, 20rem);
}

/* The charts the aim redraws in place (charts.js, data-live) - a wrapper the layout does not see. */
.live-charts {
    display: contents;
}

/* The aim and the charts it moves (Samuel, 2026-10-26): a column the aim bar sticks within, so it
   follows the screen down past every chart it moves and leaves with the last. */
.aim-scope {
    flex: 1 1 100%;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

/* On a comparison the spread, target and splash follow in a block of their own, with the same gap
   as between the panels (Samuel: Spread sat tight under Velocity). */
.aim-scope + .part-detail {
    margin-top: 1.1rem;
}

/* Folded chart panels (charts.js) leave their places, and their tabs sit together on one row, a little
   apart, tucked into the footer like folder tabs in a drawer (Samuel, 2026-10-26) - and held at the foot
   of the screen until the footer comes up to meet them, so they are always to hand. Lined up with the
   page's content; the room a short page has to spare goes above them, not between them and the footer.
   A tab opens its panel where it belongs. */
.panel.part-charts.folded {
    display: none;
}

.fold-strip {
    position: sticky;
    bottom: 0;
    /* Over the aim bar where the two meet (Samuel: the tabs slid behind it). */
    z-index: 9;
    box-sizing: border-box;
    width: 100%;
    max-width: 1100px;
    margin: auto auto 0;
    padding: 0 1rem;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.3rem 0.35rem;
}

.fold-strip + .site-footer {
    margin-top: 0;
}

/* As wide as the page's content: a comparison's spans the screen (Samuel: the tabs sat mid-screen). */
.site-main:has(.part-table-wrap) ~ .fold-strip {
    max-width: none;
}

/* Over the charts scrolling under it - and their "i"s - on the page's own ground, so nothing shows
   beside its tab; one row of fields, each label beside its control. */
.aim-bar {
    position: sticky;
    top: 0;
    z-index: 8;
    background: var(--ground);
    padding-top: 0.4rem;
    margin-top: -0.4rem;
    box-shadow: 0 0.4rem 0.6rem -0.4rem rgba(0, 0, 0, 0.5);
}

.aim-bar .aim-fields {
    margin-bottom: 0;
}

.aim-bar .aim-fields label {
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 0.6rem;
}

/* Below about 36rem the lettering would shrink past reading, so a chart keeps that width and
   scrolls sideways inside its panel instead, as the tables do. */
.chart-wrap {
    overflow-x: auto;
}

.chart {
    display: block;
    width: 100%;
    min-width: 36rem;
    max-width: 60rem;
    height: auto;
}

.chart text {
    font: 400 11px var(--face-ui);
    fill: var(--ink-on-grey);
}

.chart .tick { fill: var(--muted-on-grey); }
.chart .grid { stroke: rgba(0, 0, 0, 0.18); }
.chart .axis { stroke: var(--ink-on-grey); }
.chart .hatch { stroke: var(--ink-on-grey); stroke-width: 1.5; }
.chart .line { fill: none; stroke-width: 2.5; stroke-linejoin: round; }
.chart .range-mark { stroke: var(--ink-on-grey); stroke-width: 2; }
.chart .max-range { stroke: var(--series); stroke-width: 2; stroke-dasharray: 2 4; stroke-linecap: round; }
.chart .landing { fill: none; stroke-width: 2.5; stroke-linecap: round; }
.chart .expiry { fill: none; stroke: var(--series); stroke-width: 2; }

/* The chart's explanation, behind an "i" on the panel's title line - open, it lies over the chart. */
.part-charts > .panel-body,
.part-guidance > .panel-body,
.compare-ammo > .panel-body {
    position: relative;
}

.part-guidance caption {
    text-align: left;
    font: 600 0.9rem/1.3 var(--face-ui);
    padding: 0.25rem 0.4rem;
}

.chart-info {
    position: absolute;
    top: -1.65rem;
    right: 0;
    z-index: 6;
}

.chart-info-button {
    display: block;
    cursor: help;
    width: 1.35rem;
    height: 1.35rem;
    border: 1px solid var(--edge);
    border-radius: 50%;
    background: var(--button);
    color: var(--ink-on-grey);
    font: 700 0.85rem/1.25rem var(--face-text);
    text-align: center;
    font-style: italic;
}

/* Shown while the pointer is on the "i" or its text, or a tap has given it focus - and above the next
   panel's "i", which would otherwise poke through it. */
.chart-info:hover,
.chart-info:focus-within { z-index: 7; }
.chart-info:hover .chart-info-button,
.chart-info:focus-within .chart-info-button { background: var(--accent); }

.chart-info-body {
    display: none;
    position: absolute;
    right: 0;
    top: 1.75rem;
    width: min(32rem, 85vw);
    padding: 0.6rem 0.8rem;
    background: var(--metal-grey);
    color: var(--ink-on-grey);
    border: 1px solid var(--edge);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
    font-size: 0.88rem;
}

.chart-info:hover .chart-info-body,
.chart-info:focus-within .chart-info-body { display: block; }

/* The gap between the "i" and its text, bridged, so the pointer can cross to the text without it closing. */
.chart-info-body::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -0.5rem;
    height: 0.5rem;
}

.chart-info-body p { margin: 0 0 0.5rem; }
.chart-info-body p:last-child { margin-bottom: 0; }

/* The readout (wwwroot/js/charts.js): a cursor down the chart, a dot on each visible line, and a
   box beside the pointer with every visible line's value there. */
.chart-wrap {
    position: relative;
}

.chart .readout-cursor {
    stroke: var(--ink-on-grey);
    stroke-width: 1;
    stroke-dasharray: 3 3;
    pointer-events: none;
}

.chart .readout circle {
    stroke: var(--panel);
    stroke-width: 1.5;
    pointer-events: none;
}

.chart-readout {
    display: none;
    position: absolute;
    z-index: 4;
    pointer-events: none;
    min-width: 9rem;
    max-width: 22rem;
    padding: 0.35rem 0.55rem;
    background: var(--metal-grey);
    color: var(--ink-on-grey);
    border: 1px solid var(--edge);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
    font-size: 0.82rem;
    line-height: 1.35;
}

.chart-readout-head {
    font: 400 0.8rem/1.4 var(--face-ui);
    margin-bottom: 0.15rem;
}

.chart-readout-row {
    display: flex;
    gap: 0.45rem;
    align-items: baseline;
    white-space: nowrap;
}

.chart-readout-row .swatch {
    width: 0.9rem;
}

.chart-readout-name {
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--muted-on-grey);
}

/* The chart and its key side by side - the key in a column on the right - wrapping the key below on
   a narrow screen. */
.chart-block {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1.25rem;
    align-items: flex-start;
}

.chart-block > .chart-wrap {
    flex: 1 1 36rem;
    max-width: 60rem;
    min-width: 0;
}

.chart-block > .chart-legend {
    flex: 0 1 17rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin: 0;
}

.chart-legend li {
    position: relative;
    cursor: default;
}

/* A click on a key entry hides or shows its line: each entry is a label round a hidden checkbox, and
   the line it names carries "key-{n}", n its place in the key. While a box is unticked, its line -
   in the same chart only - is hidden and its entry dimmed and struck through. No script, and no
   inline style. Twelve places: a weapon takes at most six ammo, and lines that match share one. */
.chart-block:has(> .chart-legend > li:nth-child(1) input:not(:checked)) .key-0,
.chart-block:has(> .chart-legend > li:nth-child(2) input:not(:checked)) .key-1,
.chart-block:has(> .chart-legend > li:nth-child(3) input:not(:checked)) .key-2,
.chart-block:has(> .chart-legend > li:nth-child(4) input:not(:checked)) .key-3,
.chart-block:has(> .chart-legend > li:nth-child(5) input:not(:checked)) .key-4,
.chart-block:has(> .chart-legend > li:nth-child(6) input:not(:checked)) .key-5,
.chart-block:has(> .chart-legend > li:nth-child(7) input:not(:checked)) .key-6,
.chart-block:has(> .chart-legend > li:nth-child(8) input:not(:checked)) .key-7,
.chart-block:has(> .chart-legend > li:nth-child(9) input:not(:checked)) .key-8,
.chart-block:has(> .chart-legend > li:nth-child(10) input:not(:checked)) .key-9,
.chart-block:has(> .chart-legend > li:nth-child(11) input:not(:checked)) .key-10,
.chart-block:has(> .chart-legend > li:nth-child(12) input:not(:checked)) .key-11 {
    display: none;
}

/* After the rounds, the key's max range entry hides every max range line; and what the ring means. */
.chart-block:has(> .chart-legend > li.key-ranges input:not(:checked)) .max-range-mark {
    display: none;
}

.swatch-dotted {
    background: repeating-linear-gradient(90deg, var(--ink-on-grey) 0 0.15rem, transparent 0.15rem 0.45rem);
}

.swatch-ring {
    flex: none;
    align-self: center;
    box-sizing: border-box;
    width: 0.7rem;
    height: 0.7rem;
    margin: 0 0.35rem;
    border: 2px solid var(--ink-on-grey);
    border-radius: 50%;
}

.chart-legend li.key-note {
    font-size: 0.85rem;
}

/* A hidden entry. */
.chart-legend label {
    display: flex;
    gap: 0.5rem;
    align-items: baseline;
    cursor: pointer;
}

.chart-legend li:has(input:not(:checked)) label {
    opacity: 0.45;
    text-decoration: line-through;
}


.chart-legend li:has(input:focus-visible) {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.chart-legend li:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }



.chart-note {
    margin: 0.5rem 0 0;
    font-size: 0.85rem;
}

.chart-legend {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
    gap: 0.25rem 1rem;
    font-size: 0.9rem;
}

.chart-legend li {
    display: flex;
    gap: 0.5rem;
    align-items: baseline;
}

.swatch {
    flex: none;
    width: 1.4rem;
    height: 0.35rem;
    align-self: center;
}

.splash-rings {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
    gap: 0.75rem;
    margin-top: 0.75rem;
}

.splash-rings figure {
    margin: 0;
    text-align: center;
    font-size: 0.85rem;
}

.splash-rings svg {
    display: block;
    width: 100%;
    max-width: 12rem;
    margin: 0 auto;
}

.splash-rings text {
    font: 400 11px var(--face-ui);
    fill: var(--ink-on-grey);
}

.splash-rings .ring-guide { fill: none; stroke: rgba(0, 0, 0, 0.35); stroke-dasharray: 2 3; }
.splash-rings .ring-edge { stroke-width: 1.5; }
.splash-rings .ring-core { fill: none; stroke-width: 1.5; stroke-dasharray: 3 2; }
.splash-rings .scale { stroke: var(--ink-on-grey); stroke-width: 2; }

.part-description {
    margin: 0 0 0.75rem;
}

.part-stats {
    border-collapse: collapse;
    width: 100%;
    margin-bottom: 0.75rem;
}

.part-stats th,
.part-stats td {
    padding: 0.25rem 0.4rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.2);
    text-align: left;
}

.part-stats th {
    font: 400 0.85rem/1.3 var(--face-ui);
    width: 55%;
}

.part-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

/* ---- the damage calculator ---- */

/* The choices stacked on the left, the answer beside them using the rest of the width - so its
   working lies across the page instead of down it. One column on a narrow screen. */
.site-main:has(.calculator) {
    max-width: 1400px;
}

.calculator {
    display: grid;
    gap: 1.1rem;
    grid-template-columns: minmax(18rem, 1fr) 2fr;
    grid-template-areas: "loadout result" "target result";
    grid-template-rows: auto 1fr;
    align-items: start;
}

.calc-loadout { grid-area: loadout; }
.calc-target { grid-area: target; }
.calc-result { grid-area: result; }

@media (max-width: 48rem) {
    .calculator {
        grid-template-columns: 1fr;
        grid-template-areas: "loadout" "target" "result";
        grid-template-rows: auto;
    }
}

/* A select is as wide as its longest option unless told otherwise, and a grid item will not
   shrink below its content - so every level here may shrink, and the fields fill their panel. */
.calculator > *,
.calc-fields,
.calc-fields label {
    min-width: 0;
}

.calc-fields {
    display: grid;
    gap: 0.75rem;
}

.calc-fields label {
    display: grid;
    gap: 0.25rem;
    font: 400 0.9rem/1.3 var(--face-ui);
}

/* A tick box beside its words, not stretched across the panel like the other fields. */
.calc-fields .calc-check { display: flex; gap: 0.5rem; align-items: center; }
.calc-fields .calc-check input { width: auto; }

.calc-fields select,
.calc-fields input {
    font: 400 0.95rem/1.2 var(--face-ui);
    color: #000000;
    background: var(--metal-grey);
    border: 1px solid var(--edge);
    border-radius: 0;
    padding: 0.3rem 0.4rem;
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

.calc-answer {
    margin: 0 0 0.75rem;
    font: 400 1.25rem/1.4 var(--face-ui);
}

.calc-working {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
    column-gap: 1.25rem;
    margin: 0 0 0.75rem;
}

.calc-working > div {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.3rem 0.4rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.2);
}

.calc-working dt {
    font: 400 0.85rem/1.3 var(--face-ui);
}

.calc-working dd {
    margin: 0;
    text-align: right;
}

.calc-answer strong {
    font-size: 1.6rem;
    color: #4a2410;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* A phone: the brand gives up room so the way round stays on the same bar. */
@media (max-width: 480px) {
    .site-brand { font-size: 0.95rem; gap: 0.4rem; }
    .site-brand img { height: 1.6rem; }
    .site-header { padding: 0.35rem 0.6rem; }
    .hero h1 { font-size: 1.8rem; }
}

/* Animation is a flourish, never a requirement. */
@media (prefers-reduced-motion: reduce) {
    button:hover:not(:disabled),
    .button:hover {
        animation: none;
        background: var(--button-orange);
    }

    .load-mark img { animation: none; }
    .page-loading { animation: none; }
    .load-mark img:nth-child(2) { opacity: 1; }
}

/* ---- the framework's error banners, kept from the template ---- */

#blazor-error-ui {
    background: lightyellow;
    color: #222;
    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;
}

.blazor-error-boundary {
    background: #b32121;
    padding: 1rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred."
}
