:root {
    --bg: #15140f;
    --panel: #1f1d17;
    --panel-hover: #29261e;
    --line: #3a3529;
    --text: #e9e3d3;
    --muted: #9a9180;
    --accent: #c9a24a;
    --accent-dim: #6e5a2b;
    --owned: #7fae6a;
    --danger: #c0634f;
    color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 15px/1.5 "Segoe UI", system-ui, sans-serif;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1 { font-size: 1.8rem; margin: 0 0 1rem; letter-spacing: .02em; }
h2 { font-size: 1.15rem; margin: 0 0 .5rem; }
h1:focus { outline: none; }

.muted { color: var(--muted); }

.shell { display: flex; min-height: 100vh; }

.sidebar {
    width: 220px;
    flex-shrink: 0;
    padding: 1.25rem 1rem;
    background: var(--panel);
    border-right: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    gap: .25rem;
}

.sidebar .brand {
    font-size: 1.4rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    margin-bottom: 1rem;
}

.sidebar a:not(.brand) {
    color: var(--text);
    padding: .4rem .6rem;
    border-radius: 6px;
}

.sidebar a:not(.brand):hover { background: var(--panel-hover); text-decoration: none; }
.sidebar a.active { background: var(--accent-dim); }
.sidebar .nav-bottom { margin-top: auto; }
.sidebar .brand { display: flex; align-items: center; gap: .55rem; }
.sidebar .brand img { width: 1.6rem; height: 1.6rem; flex-shrink: 0; }

/* Held to the window rather than grown to the page: Settings sits at the bottom of the sidebar, and on a page as long
   as Paints a sidebar as tall as the page put it thousands of pixels below the window. */
.sidebar { position: sticky; top: 0; height: 100vh; overflow-y: auto; }

@media (max-width: 700px) {
    .sidebar { position: static; height: auto; overflow-y: visible; }
}

.nav-search { margin-bottom: .75rem; }
.nav-search input {
    width: 100%;
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: .4rem .6rem;
    font: inherit;
}

.search-wide { flex: 1; max-width: 32rem; }

.chips { display: flex; flex-wrap: wrap; gap: .4rem; margin: -.5rem 0 1.25rem; }
.chip {
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: .2rem .8rem;
    font: inherit;
    font-size: .85rem;
    cursor: pointer;
}
.chip:hover { color: var(--text); }
.chip.active { background: var(--accent-dim); border-color: var(--accent-dim); color: var(--text); }

.small { font-size: .8rem; }

.panel { margin-bottom: 1.25rem; }
.warn { color: var(--danger); }
code { font-family: Consolas, "Cascadia Mono", monospace; font-size: .9em; color: var(--text); }

.content { flex: 1; min-width: 0; padding: 1.5rem 2rem 3rem; }

.card {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 1rem 1.25rem;
}

.system-grid, .faction-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

.faction-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }

.stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: .5rem;
    margin: .75rem 0;
}

.stats dt { color: var(--muted); font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; }
.stats dd { margin: 0; font-size: 1.3rem; font-weight: 600; }

.btn {
    background: var(--accent);
    color: #1b1a17;
    border: 0;
    border-radius: 6px;
    padding: .45rem .9rem;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.btn:disabled { opacity: .6; cursor: progress; }

.notice { margin-top: 1rem; padding: .6rem .9rem; border-left: 3px solid var(--accent); background: var(--panel); }
.credit { margin-top: 2rem; color: var(--muted); font-size: .85rem; }

.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin-bottom: 1.25rem; }

.search, input[type=number], select {
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: .4rem .6rem;
    font: inherit;
}

.search { min-width: 260px; }
.toggle { display: flex; align-items: center; gap: .4rem; color: var(--muted); }

.faction-card { display: flex; flex-direction: column; gap: .15rem; color: var(--text); }
.faction-card:hover { background: var(--panel-hover); text-decoration: none; }
.faction-card .name { font-weight: 600; }
.faction-card.owned { border-color: var(--accent-dim); border-left-color: var(--faction-line, var(--accent-dim)); }
.owned-count { color: var(--owned); font-size: .85rem; }

.crumbs { font-size: .9rem; margin-bottom: .25rem; }

.role-group { margin-bottom: 1.75rem; }
.table-scroll { overflow-x: auto; }

.units { width: 100%; border-collapse: collapse; }
.units th { text-align: left; color: var(--muted); font-weight: 500; font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; }
.units th, .units td { padding: .45rem .6rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
.units tr.owned .unit-name { color: var(--owned); font-weight: 600; }
.units .num { width: 6rem; }
.units input[type=number] { width: 5rem; }
.units .ext { margin-left: .35rem; font-size: .85rem; }

.tag {
    display: inline-block;
    margin: .1rem .25rem .1rem 0;
    padding: 0 .45rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: .75rem;
    color: var(--muted);
}

.tag.retired { border-color: var(--danger); color: var(--danger); margin-left: .5rem; }

.btn-quiet {
    background: transparent;
    color: var(--text);
    border: 1px solid var(--line);
    font-weight: 500;
    text-decoration: none;
    display: inline-block;
}

.btn-quiet:hover { background: var(--panel-hover); text-decoration: none; }

/* Pictures in the faction tables. Box shots are all shapes, so they are fitted, not cropped. */
.units .thumb-col { width: 3.5rem; padding-right: 0; }
.thumb { display: block; width: 44px; height: 44px; border-radius: 6px; object-fit: contain; background: #fff; }
.thumb-empty { background: var(--bg); border: 1px dashed var(--line); }
.units a.unit-name { color: var(--text); }
.units tr.owned a.unit-name { color: var(--owned); }

.unit-layout {
    display: grid;
    grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
    margin-bottom: 1.5rem;
}

.unit-picture img { display: block; width: 100%; border-radius: 8px; background: #fff; }

/* A picture worth a closer look: the button is only there to make the picture clickable. */
.zoom { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.zoom:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.lightbox { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 2rem; background: rgba(0, 0, 0, .85); cursor: zoom-out; }
.lightbox img { max-width: 100%; max-height: 100%; width: auto; object-fit: contain; border-radius: 6px; background: #fff; }
.lightbox-close { position: fixed; top: .75rem; right: 1rem; }
.no-picture {
    display: grid;
    place-items: center;
    aspect-ratio: 1;
    border: 1px dashed var(--line);
    border-radius: 8px;
    color: var(--muted);
}

.picture-search { display: flex; gap: .5rem; margin-top: .75rem; }
.picture-search .search { flex: 1; min-width: 0; }
.picture-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .5rem; }

.unit-facts dl { display: grid; grid-template-columns: max-content 1fr; gap: .5rem 1rem; margin: 0 0 1rem; align-items: center; }
.unit-facts dt { color: var(--muted); font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; }
.unit-facts dd { margin: 0; }
.unit-facts input[type=number] { width: 6rem; }
.description { color: var(--muted); }

.candidates h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: .75rem; }
.candidates h2 .btn { margin-left: auto; }
.candidates h3 { font-size: .95rem; margin: 1rem 0 .5rem; color: var(--muted); }

.candidate-grid { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }

.candidate {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    padding: .5rem;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 8px;
    color: var(--text);
    font: inherit;
    font-size: .85rem;
    text-align: left;
    cursor: pointer;
}

.candidate:hover { border-color: var(--accent); }
.candidate:disabled { opacity: .6; cursor: progress; }
.candidate img { width: 100%; aspect-ratio: 1; object-fit: contain; background: #fff; border-radius: 6px; }

@media (max-width: 700px) {
    .unit-layout { grid-template-columns: 1fr; }
}

.page-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: .75rem; }
a.chip { display: inline-block; text-decoration: none; }
.crop-choice { margin: .25rem 0 0; }

/* The gallery: a wall of what you own. */
.gallery-game { margin-bottom: 2.25rem; }
.gallery-game h2 { font-size: 1.35rem; border-bottom: 1px solid var(--line); padding-bottom: .4rem; margin-bottom: .75rem; }
.gallery-game h2 .muted, .gallery-game h3 .muted { font-size: .85rem; font-weight: 400; margin-left: .35rem; }
.gallery-game h3 { font-size: 1rem; margin: 1.25rem 0 .6rem; }
.gallery-game h3 a { color: var(--text); }

.gallery-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }

.gallery-card {
    display: flex;
    flex-direction: column;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 10px;
    overflow: hidden;
    color: var(--text);
}

/* Hovering a card lights the whole border in the army's colour its top stripe already wears;
   a card with no army of its own - a scenery kit, a codex - falls back to the app's accent. */
.gallery-card:hover { border-color: var(--faction-line, var(--accent)); text-decoration: none; }
.gallery-card img, .gallery-empty { width: 100%; aspect-ratio: 1; object-fit: contain; background: var(--bg); }
.gallery-empty { display: grid; place-items: center; color: var(--muted); font-size: .85rem; }
.gallery-caption { display: flex; flex-direction: column; gap: .2rem; padding: .6rem .7rem .7rem; }
.gallery-name { font-weight: 600; line-height: 1.25; }
.gallery-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; margin-top: .15rem; }

.status { border-radius: 999px; padding: 0 .5rem; font-size: .75rem; border: 1px solid var(--line); color: var(--muted); }
.status-built { color: #c8b98f; border-color: #6b5f40; }
.status-primed { color: #b9c2cc; border-color: #56606b; }
.status-inprogress { color: var(--accent); border-color: var(--accent-dim); }
.status-painted { color: var(--owned); border-color: #4c6b3f; }

/* Faction colours: hand-picked accents (Services/FactionColours.cs), passed in as --faction or --swatch. */
.swatch {
    display: inline-block;
    width: .7em;
    height: .7em;
    border-radius: 50%;
    background: var(--swatch);
    vertical-align: baseline;
    /* A ring, so a black army's dot still shows on a dark page. */
    box-shadow: 0 0 0 1px rgba(233, 227, 211, .35);
}

/* The stripe an army wears. It is the colour lifted for a thin line (Services/FactionColours.cs),
   because several armies are painted near-black and would read as no colour at all. */
.faction-card { border-left: 4px solid var(--faction-line, var(--line)); }
.gallery-card { border-top: 4px solid var(--faction-line, var(--line)); }
.chip .swatch { margin-right: .15rem; }
.chip .muted { margin-left: .2rem; }
.sub-faction { white-space: nowrap; }
.chapter { white-space: nowrap; }
.panel h3 { font-size: 1rem; margin: 1.25rem 0 .5rem; }

/* Paints */
.paint-swatch {
    display: inline-block;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    vertical-align: middle;
    box-shadow: 0 0 0 1px rgba(233, 227, 211, .35);
}

.paint-swatch.small { width: 1.1rem; height: 1.1rem; }
.paint-swatch-none { background: repeating-linear-gradient(45deg, var(--panel), var(--panel) 3px, var(--line) 3px, var(--line) 6px); }

.paint-stats { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); max-width: 52rem; margin-bottom: 1.25rem; }
.units.paints td.shop { white-space: nowrap; }
.units.paints td.shop a { margin-right: .5rem; }
.units tr.owned .unit-name { color: var(--owned); font-weight: 600; }
.in-stock { color: var(--owned); }

.recipe { list-style: none; counter-reset: step; margin: .5rem 0 1rem; padding: 0; }
.recipe li {
    counter-increment: step;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding: .45rem 0;
    border-bottom: 1px solid var(--line);
}
.recipe li::before { content: counter(step); width: 1.4rem; color: var(--muted); text-align: right; }
.recipe .paint-name { font-weight: 600; }
.recipe li.need .paint-name { color: var(--muted); }
.recipe .note { flex: 1; min-width: 8rem; background: transparent; border: 1px solid transparent; }
.recipe .note:hover, .recipe .note:focus { border-color: var(--line); }
.recipe .recipe-actions { display: flex; gap: .25rem; margin-left: auto; }
.recipe .recipe-actions .btn { padding: .15rem .5rem; }
.picture-search .note { flex: 0 1 12rem; }
.picture-search .part { flex: 0 1 14rem; }

/* Factions: picture and description at the top of a faction page, pictures on a game's faction cards. */
.faction-head { display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: 1.25rem; align-items: start; margin-bottom: 1.25rem; }
.faction-picture img { display: block; width: 100%; border-radius: 8px; background: #fff; }
.faction-picture .no-picture { aspect-ratio: 4 / 3; }
.faction-description { margin: 0 0 .75rem; line-height: 1.55; }
.link-button { background: none; border: 0; padding: 0; font: inherit; color: var(--accent); cursor: pointer; }
.link-button:hover { text-decoration: underline; }
/* Faction pictures are banners with the badge and line at the foot: the card shows the art from the top. */
.faction-card-image { display: block; width: calc(100% + 2.5rem); margin: -1rem -1.25rem .6rem; aspect-ratio: 4 / 3; object-fit: cover; object-position: center top; border-radius: 10px 10px 0 0; }
.faction-card { overflow: hidden; }
.also-in { margin-left: .4rem; }

@media (max-width: 700px) {
    .faction-head { grid-template-columns: 1fr; }
}

.unit-facts .unit-size { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .6rem; }
.candidate > a { color: inherit; }

.unit-facts .price-link { display: flex; flex-wrap: wrap; gap: .3rem; flex-basis: 100%; margin-top: .3rem; }
.unit-facts .price-link .search { flex: 1 1 14rem; min-width: 0; }
.also-in .shown-under { display: inline-flex; align-items: center; gap: .4rem; margin-left: .5rem; white-space: nowrap; }

/* Paint recipes */
.tabs { display: flex; flex-wrap: wrap; gap: .25rem; border-bottom: 1px solid var(--line); margin: -.5rem 0 1.25rem; }
.tabs a { padding: .45rem .9rem; color: var(--muted); border-bottom: 2px solid transparent; margin-bottom: -1px; }
.tabs a:hover { color: var(--text); text-decoration: none; }
.tabs a.active { color: var(--text); border-bottom-color: var(--accent); }
/* Four to a row at most, and always the same width: auto-fit stretched a group of two cards across the page
   while a group of nine sat narrow, so no two groups looked alike. A track of at least a quarter of the row
   caps it at four; at least 320px drops it to three, two or one as the space narrows. auto-fill rather than
   auto-fit keeps the empty tracks, which is what stops two cards growing to half the page each. The quarter is
   short by its share of the gaps - four tracks of a flat 25% plus three gaps never fit, so it would only ever
   manage three. */
.recipe-grid { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, max(calc(25% - .7rem), 320px)), 1fr)); }
.recipe-card { margin-bottom: .75rem; }
.recipe-grid .recipe-card { margin-bottom: 0; }
.recipe-card h3 { margin: 0 0 .5rem; display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .5rem; font-size: 1rem; }
.recipe-card h3 .btn { margin-left: auto; }
/* Signing in, and setting the password the first time. Served outside Blazor, so these two pages have
   nothing but the stylesheet to go on. */
.sign-out { margin: .4rem 0 0 .6rem; }
.password-fields { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-top: .5rem; }
.password-fields .search { min-width: 0; flex: 0 1 14rem; }

body.signin-page { display: grid; place-items: center; min-height: 100vh; padding: 1.5rem; }
.signin { display: flex; flex-direction: column; gap: .6rem; width: min(100%, 23rem); }
.signin h1 { font-size: 1.4rem; margin: 0; }
.signin .search { width: 100%; min-width: 0; }
.signin .notice { margin: 0; }
.notice.warn { border-left-color: var(--danger); color: var(--danger); }

/* Setting the colour an army or a chapter is marked with. */
.colour-list { list-style: none; margin: .5rem 0 0; padding: 0; }
.colour-list li { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; padding: .4rem 0; border-bottom: 1px solid var(--line); }
.colour-list li:last-child { border-bottom: 0; }
.colour-list .colour-name { font-weight: 600; margin-right: auto; }
.colour-list .paint-pick { min-width: 0; flex: 0 1 16rem; padding: .2rem .5rem; }
.colour-list .btn { padding: .1rem .5rem; font-size: .85rem; }

/* A recipe's steps, each on two lines - what it does, then what with - and a rule between them. Like a
   scheme's parts, each stays a list item rather than a flex box, so the numbering says what order they go in. */
.recipe-steps-view { margin: 0; padding-left: 1.3rem; }
.recipe-steps-view li { padding: .45rem 0; border-bottom: 1px solid var(--line); }
.recipe-steps-view li:last-child { padding-bottom: 0; border-bottom: 0; }
.recipe-steps-view li > * { display: block; }
.recipe-steps-view .step-what .tag { margin-right: .3rem; }
.recipe-steps-view .step-paints { display: flex; flex-wrap: wrap; align-items: center; gap: .2rem .4rem; margin-top: .2rem; }
.recipe-steps-view .step-paint { display: inline-flex; align-items: center; gap: .3rem; }
.recipe-steps-view .step-paint.need { color: var(--muted); text-decoration: underline dotted; }
.recipe-steps-view .parts { color: var(--accent); font-weight: 600; }
.stand-in { color: var(--muted); font-size: .85em; white-space: nowrap; }
.recipe-notes { white-space: pre-line; color: var(--muted); margin: .6rem 0 0; }
.recipe-targets { display: flex; flex-wrap: wrap; gap: .3rem; margin: .6rem 0 .4rem; }
.recipe-targets .chip .link-button { margin-left: .2rem; }
.faction-recipes h2, .unit-recipes h2, .unit-schemes h2, .unit-sources h2, .unit-paints h2, .painting-notes-panel h2 {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .5rem;
}
.faction-recipes h2 .btn { margin-left: auto; }
.recipe-editor .field { display: flex; flex-direction: column; gap: .3rem; margin-bottom: 1rem; }
.paste-recipe { margin: .4rem 0 .8rem; display: flex; flex-direction: column; align-items: flex-start; gap: .4rem; }
.paste-recipe p { margin: 0; }
.paste-recipe form { width: 100%; }
.archive-page { width: 100%; border: 1px solid var(--line); border-radius: 8px; padding: .5rem .75rem; }
.archive-page h4 { margin: .2rem 0 .5rem; display: flex; align-items: baseline; gap: .5rem; }
.archive-recipe { display: flex; align-items: baseline; gap: .5rem; padding: .15rem 0; flex-wrap: wrap; }
.archive-recipe .name { font-weight: 600; }
.recipe-group { margin-bottom: 1.25rem; }
.recipe-group h2 { display: flex; align-items: baseline; gap: .5rem; margin: 0 0 .5rem; font-size: 1.05rem; }
.archive-recipe img { width: 54px; height: 54px; object-fit: cover; border-radius: 6px; background: var(--bg); }
.recipe-picture { display: block; width: 100%; max-width: 18rem; border-radius: 8px; margin: .25rem 0 .6rem; }
.recipe-editor textarea { width: 100%; box-sizing: border-box; font: inherit; color: inherit; background: var(--bg, transparent); border: 1px solid var(--line); border-radius: 6px; padding: .5rem .6rem; }
.recipe-editor h3 { margin: 1.25rem 0 .5rem; font-size: .95rem; }
.recipe-steps { padding-left: 1.4rem; margin: 0 0 .75rem; display: flex; flex-direction: column; gap: .8rem; }
.recipe-steps .step-head, .recipe-steps .step-paints { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.recipe-steps .step-head .note { flex: 1 1 14rem; min-width: 0; }
.recipe-steps .step-paints { margin-top: .4rem; }
.recipe-steps .step-paint { display: inline-flex; flex-wrap: wrap; gap: .3rem; align-items: center; flex: 1 1 16rem; min-width: 0; }
.recipe-steps .step-paint .search { flex: 1 1 12rem; min-width: 0; }
.recipe-steps .count { width: 4rem; }
.target-results { list-style: none; padding: 0; margin: .4rem 0 0; display: flex; flex-direction: column; gap: .2rem; }
.editor-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: 1.5rem; }

/* Wishlist stars */
.wish { background: none; border: 0; padding: 0 .3rem 0 0; font-size: 1.05rem; line-height: 1; color: var(--muted); cursor: pointer; }
.wish:hover, .wish.on { color: var(--accent); }
h1 .wish-toggle { font-size: .85rem; vertical-align: middle; margin-left: .6rem; }
h1 .wish-toggle.on { color: var(--accent); }

/* Scenery on the collection wall */
.scenery-card img { background: #fff; }
.scenery-card .status-pick { font-size: .8rem; padding: .1rem .3rem; max-width: 100%; }
.scenery-card .gallery-name { color: var(--text); }

/* Codexes & scenery */
.product-thumb { width: 48px; height: 48px; object-fit: contain; background: #fff; border-radius: 4px; display: block; }
.chip-gap { flex-basis: .75rem; }
.add-product { margin-top: 1.5rem; }
.add-product select { max-width: 100%; }

/* Sets on the collection page */
.sets-panel { margin-bottom: 1.25rem; }
.sets-panel h2 { display: flex; align-items: center; gap: .6rem; margin-top: 0; }
.sets-panel h2 .btn { margin-left: auto; }
.set-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .6rem; }
.set-row { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; }
.set-row img { width: 72px; height: 54px; object-fit: contain; background: #fff; border-radius: 6px; flex-shrink: 0; }
.set-body { display: flex; flex-direction: column; gap: .15rem; flex: 1 1 14rem; min-width: 0; }
.set-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-top: .6rem; }
.set-preview { display: flex; flex-direction: column; gap: .6rem; }
.set-contents select { max-width: 100%; }

/* Prices */
.collection-value { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.25rem; margin-bottom: 1.25rem; }
.collection-value > div { display: flex; flex-direction: column; }
.collection-value strong { font-size: 1.6rem; }
.collection-value .notice { margin: 0; flex-basis: 100%; }
.unit-facts .price { display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .6rem; }
.unit-facts .price-amount { font-weight: 600; font-size: 1.1rem; }
.unit-facts .price-actions { display: flex; flex-wrap: wrap; gap: .3rem; flex-basis: 100%; }
.unit-facts .price-actions .btn { padding: .15rem .5rem; font-size: .85rem; }
.gallery-meta .value { margin-left: auto; color: var(--text); }

/* A model's or a kit's two columns: pictures on the left, what it is and how you paint it on the right.
   The gap between the panels is the column's alone, so every one of them sits the same distance from the next. */
.unit-main, .unit-side { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
.unit-main > *, .unit-side > * { margin-bottom: 0; }
.unit-main > .card > :last-child, .unit-side > .card > :last-child { margin-bottom: 0; }

.photo-grid { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); margin: .5rem 0 1rem; }
.photo { margin: 0; display: flex; flex-direction: column; gap: .35rem; }
.photo img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 6px; background: var(--bg); }
.photo .caption {
    width: 100%;
    background: transparent;
    color: var(--text);
    border: 1px solid transparent;
    border-radius: 4px;
    padding: .15rem .3rem;
    font: inherit;
    font-size: .85rem;
}
.photo .caption:hover, .photo .caption:focus { border-color: var(--line); }
.photo-actions { display: flex; flex-wrap: wrap; gap: .25rem; }
.photo-actions .btn { padding: .1rem .45rem; font-size: .8rem; }

.btn-danger { background: var(--danger); color: #fff; border: 0; }

.candidate { cursor: default; }
.candidate-actions { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: auto; }
.candidate-actions .btn { padding: .15rem .45rem; font-size: .8rem; }

/* Every panel on a model or a kit ends the same way: one row of things you can do next. */
.panel-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: .9rem 0 0; }

.painting-notes-panel .saved { margin-left: auto; }
.painting-notes-panel textarea {
    width: 100%;
    min-height: 8rem;
    resize: vertical;
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: .5rem .6rem;
    font: inherit;
    line-height: 1.45;
}

/* Paint schemes: a whole model, part by part */
.scheme-card h3 { margin: 0 0 .5rem; display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem .5rem; font-size: 1rem; }
.scheme-card h3 .btn { margin-left: auto; }
.recipe-grid .scheme-card { margin-bottom: 0; }
/* A scheme's parts, each on three lines - name, how many steps, the colours - with a rule between them. Side
   by side they wrapped at a different place on every row, which is what made a long scheme hard to read down.
   Each stays a list item rather than a flex box, so the numbering still says what order you paint them in. */
.scheme-parts { margin: .25rem 0 .5rem; padding-left: 1.3rem; }

/* What a recipe or a scheme wants that is not on your shelf: one wrapped line, because a card that names
   a dozen paints a row apiece is taller than everything else on it put together. The range, what it holds
   up and how near the stand-in is are all on hover. */
.missing-paints {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .2rem .7rem;
    margin: .6rem 0 0;
    font-size: .85rem;
}
.missing-paints .want { display: inline-flex; align-items: center; gap: .25rem; cursor: help; }
.missing-paints .paint-name { font-weight: 600; }
.missing-paints .stand-in { font-size: 1em; }
/* Onto the wishlist one pot at a time, from where you noticed it was missing. Small enough that a dozen of
   them do not turn the line into a row of buttons. */
.missing-paints .wish {
    border: 1px solid var(--line);
    background: none;
    color: var(--muted);
    border-radius: 4px;
    padding: 0 .3rem;
    line-height: 1.2;
    font: inherit;
    cursor: pointer;
}
.missing-paints .wish:hover { color: var(--text); border-color: var(--accent); }
.missing-paints .wish:disabled { cursor: default; opacity: .5; }
.missing-paints .wished { color: var(--accent); cursor: help; }

/* A card of a recipe or a scheme holds several unlike things - what it paints, what you are short of, what
   you can do next - and they run together without something between them. A rule, not a gap: a gap alone
   reads as an accident at this size. */
.card-band { margin-top: .7rem; padding-top: .7rem; border-top: 1px solid var(--line); }
.scheme-card .card-band, .recipe-card .card-band { margin-bottom: 0; }
.scheme-parts.card-band, .recipe-steps-view.card-band { padding-left: 1.3rem; }
.scheme-actions.card-band { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }

/* The Paints tabs as lists rather than cards. */
.units.sources td.about { max-width: 34rem; }
.units.sources td.about .chip { margin: 0 .25rem .25rem 0; }
.units.recipes td, .units.schemes td, .units.sources td { vertical-align: top; }
.units.recipes .scheme-swatches { display: inline-flex; gap: .15rem; }
.scheme-parts li { padding: .45rem 0; border-bottom: 1px solid var(--line); }
.scheme-parts li:last-child { padding-bottom: 0; border-bottom: 0; }
.scheme-parts li > * { display: block; }
.scheme-parts .part-name .muted { margin-left: .4rem; }
.scheme-parts .scheme-swatches { display: flex; flex-wrap: wrap; gap: .2rem; margin-top: .25rem; }
.scheme-swatches { display: inline-flex; gap: .15rem; }
.scheme-actions { margin: .6rem 0 0; }
.scheme-edit-parts { margin: 0 0 .75rem; padding-left: 1.4rem; display: flex; flex-direction: column; gap: .5rem; }
.scheme-edit-parts li { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.scheme-edit-parts .name { font-weight: 600; flex: 0 0 auto; }
.scheme-edit-parts .search { flex: 1 1 14rem; min-width: 0; }

/* Where the painting is written down. Sources are short, so they sit two or three across. */
.source-grid { display: grid; gap: .5rem 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.source-grid .source-card { margin-bottom: 0; border-left: 2px solid var(--line); padding-left: .7rem; }
.source-card { margin-bottom: .75rem; }
.source-card:last-child { margin-bottom: 0; }
.source-card h3 { margin: 0 0 .2rem; display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .5rem; font-size: 1rem; }
.source-card h3 .btn { margin-left: auto; }
.source-card .citation { margin: 0; }
.source-card .recipe-notes { margin-top: .35rem; }
.source-fields { display: flex; flex-wrap: wrap; gap: .75rem 1rem; margin-bottom: .5rem; }
.source-fields .field { display: flex; flex-direction: column; gap: .3rem; margin: 0; }
.source-fields .field.wide { flex: 1 1 18rem; min-width: 0; }
.source-fields .field.wide .search { width: 100%; box-sizing: border-box; }
.source-editor h4 { margin: 1rem 0 .4rem; font-size: .95rem; }

/* The desk: one step at a time, at arm's length */
.desk { outline: none; max-width: 46rem; }
.desk-head { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: .75rem; }
.desk-head h1 { margin: 0 0 .2rem; }
.desk-head p { margin: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.desk-head .btn { margin-left: auto; }
.desk-progress { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: 1rem; }
.desk-progress .pip {
    width: 1.5rem; height: .45rem; padding: 0; border: 0; border-radius: 999px;
    background: var(--line); cursor: pointer;
}
.desk-progress .pip.done { background: var(--accent-dim); }
.desk-progress .pip.now { background: var(--accent); }
.desk-step {
    background: var(--card); border: 1px solid var(--line); border-radius: 12px;
    padding: 1.5rem 1.75rem; margin-bottom: 1rem;
}
.desk-part { margin: 0 0 .25rem; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; font-size: .8rem; }
.desk-note { margin: 0 0 1rem; font-size: 2rem; line-height: 1.15; font-weight: 600; }
.desk-paints { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .75rem; }
.desk-paints li { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem; }
.desk-paints .name { font-size: 1.35rem; font-weight: 600; }
.desk-paints .parts { color: var(--accent); font-weight: 600; }
.desk-paints .paint-swatch { width: 2.4rem; height: 2.4rem; }
.desk-buttons { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.25rem; }
.desk-buttons .btn { padding: .6rem 1.4rem; font-size: 1.05rem; }
.desk-all { margin: 0 0 1.25rem; padding-left: 1.4rem; display: flex; flex-direction: column; gap: .3rem; }
.desk-all li.now { color: var(--accent); }
.desk-all .link-button { text-align: left; display: flex; flex-wrap: wrap; gap: .4rem; }

/* Progress: the grey tide, and what you finish each month */
.tide { display: flex; height: 1.1rem; border-radius: 999px; overflow: hidden; background: var(--bg); margin: .25rem 0 .75rem; }
.tide-part { display: block; }
.tide-key { list-style: none; margin: 0 0 .5rem; padding: 0; display: flex; flex-wrap: wrap; gap: .3rem 1.25rem; }
.tide-key li { display: flex; align-items: center; gap: .4rem; }
.tide-key .pip { width: .8rem; height: .8rem; border-radius: 3px; display: inline-block; }
.unbuilt { background: #4a4438; }
.built { background: #6b6250; }
.primed { background: #8d8270; }
.inprogress { background: var(--accent); }
.painted { background: var(--owned); }
.months { display: flex; align-items: flex-end; gap: .4rem; height: 9rem; margin: .5rem 0; }
.months .month { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: .2rem; height: 100%; }
.months .bar { width: 100%; background: var(--accent-dim); border-radius: 4px 4px 0 0; min-height: 0; }
.months .month:last-child .bar { background: var(--accent); }
.progress-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .35rem; }
.progress-list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem .75rem; }

/* Cards or a list: the same things, shown either way */
.view-toggle { margin: 0; }
.toolbar .chips { margin: 0; }
.unit-card .gallery-name, .product-card .gallery-name, .wish-card .gallery-name { color: var(--text); }
.unit-card .gallery-name a { color: var(--text); }
.unit-card .gallery-name a:hover { color: var(--accent); }
.unit-card.owned, .product-card.owned { border-color: var(--accent-dim); border-top-color: var(--faction-line, var(--accent-dim)); }
.unit-card.owned:hover, .product-card.owned:hover { border-color: var(--faction-line, var(--accent)); }
.unit-card .owned-controls, .product-card .gallery-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }
.owned-controls .count { width: 4rem; }
.unit-card .status-pick, .product-card .status-pick { font-size: .8rem; padding: .1rem .3rem; max-width: 100%; }
.product-card .toggle, .product-card .small { font-size: .8rem; }
.wish-card .gallery-meta .btn, .product-card .gallery-meta .btn { margin-left: auto; padding: .15rem .5rem; }
.units .price { white-space: nowrap; }
.units .price .muted { display: block; }
.units.collected .num { width: 5rem; }
.show-more { margin-top: .75rem; }

#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    padding: .75rem 1.25rem;
    background: var(--danger);
    color: #fff;
}

#blazor-error-ui .reload { color: #fff; text-decoration: underline; margin-left: .5rem; }

@media (max-width: 700px) {
    .shell { flex-direction: column; }
    .sidebar { width: auto; flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--line); }
    .sidebar .brand { margin: 0 1rem 0 0; }
    .content { padding: 1rem; }
    .search { min-width: 0; width: 100%; }
}
