/* dark only: the site has no light theme */
:root {
    color-scheme: dark;
    --bg: #14171c;
    --surface: #1c2027;
    --text: #e6e8ec;
    --muted: #9aa1ad;
    --border: #2d333d;
    --accent: #79a6f2;
    --row-hover: #232935;
    /* every other table row: a touch lighter than the panel */
    --row-stripe: rgba(255, 255, 255, 0.03);
    --west-bg: #1f3156;
    --west-text: #a9c4f5;
    --east-bg: #4a2420;
    --east-text: #f2b2a8;
    --pirate-bg: #322a4d;
    --pirate-text: #c9bdf0;
    --gain: #5cc98a;
    --gold: #e3b341;
    --fresh: #5cc98a;
    --recent: #d69e2e;
    --stale: #f06a5f;
    /* class roles (ClassRole): tank, DPS, healer */
    --tank: #5cc98a;
    --dps: #f06a5f;
    --healer: #f28fcb;
    /* the DPS roles, each also shown on DPS red */
    --archer: #3a64c8;
    --mage: #5cc6f2;
    --melee: #a8292f;
    /* over the background image: the page colour, nearly opaque */
    --veil: rgba(20, 23, 28, 0.92);
    /* the header, cards and tables: the surface, the background showing through, blurred */
    --panel: rgba(28, 32, 39, 0.7);
    --panel-blur: blur(10px);
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* the background image (partials/backdrop.blade.php), fixed behind the page (not scrolling
   with it) under the veil; a new one fades in over the last */
.backdrop { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.backdrop::after { content: ""; position: absolute; inset: 0; background: var(--veil); }
.backdrop-layer { position: absolute; inset: 0; background: center / cover no-repeat; transition: opacity 2s ease; }
.backdrop-layer.fading-in { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
    .backdrop-layer { transition: none; }
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.top {
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 12px 24px;
    background: var(--panel);
    border-bottom: 1px solid var(--border);
    /* stays at the top as the page scrolls, over it; what passes under is blurred */
    position: sticky;
    top: 0;
    z-index: 10;
    backdrop-filter: var(--panel-blur);
}
.brand { font-weight: 700; font-size: 18px; color: var(--text); }
.top nav { display: flex; gap: 16px; }
.top nav a { color: var(--muted); padding: 4px 0; }
.top nav a.active { color: var(--text); border-bottom: 2px solid var(--accent); }

main { max-width: 1600px; margin: 0 auto; padding: 24px 16px; }
.patches { display: grid; gap: 12px; }
.patch h3 { font-size: 16px; margin: 0; }
.patch-meta { font-size: 13px; margin: 2px 0 0; }
.patch p:not(.patch-meta) { margin: 10px 0 0; }
.patch .patch-list { white-space: pre-line; }
.site-footer { max-width: 1600px; margin: 0 auto; padding: 0 16px 24px; font-size: 12px; }

h1 { font-size: 24px; margin: 0 0 16px; }
h2 { font-size: 18px; margin: 32px 0 12px; }

.muted { color: var(--muted); }
.empty { color: var(--muted); padding: 16px 0; }

/* player page: their details with a map of their homes beside it (open, the map has its own
   row); further down the housing summary with their houses beside it */
.player-top { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
.player-top.with-map { grid-template-columns: minmax(0, 1fr) minmax(0, 360px); }
.player-top.with-map:has(.land-map.open) { grid-template-columns: minmax(0, 1fr); }
/* in their details card: the details, and the shared note filling the rest */
.player-summary { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 16px 40px; }
.player-note { border-left: 1px solid var(--border); padding-left: 24px; min-width: 0; }
.player-note-head { display: flex; align-items: center; gap: 8px; }
.player-note h2 { margin: 0; font-size: 15px; }
.player-note .note-text { white-space: pre-line; overflow-wrap: anywhere; margin: 8px 0; }
.player-note .note-meta { font-size: 12px; margin: 0; }
.player-note .empty { padding: 8px 0; }
.note-edit > span { display: flex; align-items: center; gap: 6px; }
@media (max-width: 700px) {
    .player-summary { grid-template-columns: minmax(0, 1fr); }
    .player-note { border-left: none; padding-left: 0; border-top: 1px solid var(--border); padding-top: 12px; }
}
.housing { display: grid; grid-template-columns: minmax(0, 380px) minmax(0, 1fr); gap: 16px; align-items: start; }
.housing td select { font: inherit; font-size: 13px; padding: 2px 4px; max-width: 220px; }
.home-size { margin-left: 8px; }
/* a home's status from HomeDB (partials/home-status.blade.php) */
.home-demolition { color: var(--stale); font-weight: 600; }
.home-protected { color: var(--gain); }
/* a home's sharecode maker, opened under its row */
.homes-table tbody + tbody { border-top: 0; }
.sharecode-row td { white-space: normal; background: var(--bg); }
.sharecode { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.sharecode input { font: inherit; padding: 4px 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); color: var(--text); }
.sharecode-result input { width: 22em; font-family: ui-monospace, monospace; font-size: 13px; margin-right: 6px; }
.sharecode-note { margin: 6px 0 0; font-size: 13px; }
@media (max-width: 1000px) {
    .player-top.with-map, .housing { grid-template-columns: minmax(0, 1fr); }
}
/* updates page: players, housing and regrades side by side */
.columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
.columns.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.columns h2 { margin-top: 0; }
/* player page: history and regrades, spaced like the headings above them */
.columns.spaced h2 { margin-top: 32px; }
@media (max-width: 1000px) {
    .columns, .columns.three { grid-template-columns: minmax(0, 1fr); }
    .columns h2 { margin-top: 16px; }
}
/* houses page: the map on the left, its owners on the right */
.houses { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 480px); gap: 16px; align-items: start; }
@media (max-width: 1000px) {
    .houses { grid-template-columns: minmax(0, 1fr); }
}
.side-filter { gap: 16px; }
.side-filter label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.side-filter input { padding: 0; margin: 0; }
.house-map { position: relative; padding: 0; overflow: hidden; }
.house-map svg.zoomed { cursor: grab; touch-action: none; }
.house-map svg.dragging { cursor: grabbing; }
/* zoomed in, dots keep about their size (--dot-scale shrinks them in map pixels) */
.house-map .house-dot { r: calc(15px * var(--dot-scale, 1)); stroke-width: calc(3px * var(--dot-scale, 1)); }
.map-zoom { position: absolute; top: 10px; right: 10px; display: flex; gap: 4px; }
.map-zoom button {
    min-width: 32px; height: 32px; padding: 0 8px;
    font: inherit; font-size: 16px; line-height: 1;
    border: 1px solid var(--border); border-radius: 6px;
    background: var(--surface); color: var(--text); cursor: pointer;
}
.map-zoom button:disabled { opacity: 0.4; cursor: default; }
.region-filter { margin-top: 12px; }
/* the Houses page's Demolition button (guild members), red while on, and its table */
button.demolition-toggle { background: none; border-color: var(--border); color: var(--text); }
button.demolition-toggle .count { color: var(--muted); margin-left: 4px; }
button.demolition-toggle[aria-pressed="true"] { background: var(--stale); border-color: var(--stale); color: #fff; }
button.demolition-toggle[aria-pressed="true"] .count { color: #fff; }
.demolitions .sharecode-result input { width: 16em; padding: 2px 6px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); color: var(--text); }
.demolitions .building-name { cursor: help; color: var(--muted); }
.homes-table .home-location { cursor: help; color: var(--muted); }
.house-map svg:not(.icon) { display: block; width: 100%; height: auto; }
/* dot colours by side: strong, to stand out on the map image */
.dot-west { --dot: #1f6fe0; }
.dot-east { --dot: #d6322b; }
.dot-pirate { --dot: #8a3fd1; }
.dot-unknown { --dot: #3d3d3d; }
/* sizes in map pixels: about 4px across at a 900px wide map */
.house-dot { fill: var(--dot); stroke: #fff; stroke-width: var(--dot-stroke, 3); }
/* the side filter's key to the dot colours */
.swatch { width: 10px; height: 10px; border-radius: 50%; background: var(--dot); box-shadow: 0 0 0 1px #fff; }
/* players page top: summary panel filling the left, the online chart on the right */
.summary { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 640px); gap: 16px; margin-bottom: 20px; }
.online-card { padding: 16px 20px; }
.online-card h2 { font-size: 16px; margin: 0 0 4px; }
/* no chart (no recent logins): the panel takes the whole row */
.summary > :only-child { grid-column: 1 / -1; }
@media (max-width: 1000px) {
    .summary { grid-template-columns: minmax(0, 1fr); }
}
/* a land map box (x-land-map), e.g. a guild's third box; open, it takes its own row at the Houses page's map width
   (the page less the owners table, its gap and this card's padding) */
.summary.with-map { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, 320px); }
.summary.with-map.no-chart { grid-template-columns: minmax(0, 1fr) minmax(0, 320px); }
.land-map { display: flex; flex-direction: column; padding: 16px 20px; }
.land-map h2 { font-size: 16px; margin: 0 0 4px; }
.land-map.open { grid-column: 1 / -1; }
/* open, the map has left the top row: the card and the chart share it */
.summary.with-map:has(.land-map.open) { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
.summary.with-map.no-chart:has(.land-map.open) { grid-template-columns: minmax(0, 1fr); }
.map-toggle { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.land-map.open .map-toggle { cursor: zoom-out; }
.map-toggle svg:not(.icon) { display: block; width: 100%; height: auto; border-radius: 6px; }
/* closed, the map fills the rest of the box (cut to fit), however tall the row is */
.land-map:not(.open) .map-toggle { position: relative; flex: 1 1 auto; min-height: 200px; }
.land-map:not(.open) .map-toggle svg:not(.icon) { position: absolute; inset: 0; height: 100%; }
.land-map.open .map-toggle svg:not(.icon) { width: calc(100% - 456px); margin: 0 auto; }
/* narrower: the guild card across the top, the chart and the map side by side under it */
@media (max-width: 1300px) {
    .summary.with-map, .summary.with-map.no-chart { grid-template-columns: minmax(0, 1fr) minmax(0, 320px); }
    .summary.with-map:not(.no-chart) > .summary-panel { grid-column: 1 / -1; }
}
/* stacked: a small map of its own shape */
@media (max-width: 1000px) {
    .summary.with-map, .summary.with-map.no-chart { grid-template-columns: minmax(0, 1fr); }
    .land-map:not(.open) .map-toggle { min-height: 0; }
    .land-map:not(.open) .map-toggle svg:not(.icon) { position: static; height: auto; max-width: 480px; }
    .land-map.open .map-toggle svg:not(.icon) { width: 100%; }
}
/* the panel stretches to the chart's height: side or guild tiles, then recent activity tiles */
.summary-panel { display: flex; flex-direction: column; justify-content: space-between; gap: 14px; }
.summary-panel h1 { margin: 0; }
.summary-panel .guild-buff { margin: -8px 0 0; font-size: 13px; }
.summary-panel .guild-buff strong { color: var(--text); }
/* guilds page: gear score per side, on its own so kept to a readable width */
.guild-gear { max-width: 960px; margin-bottom: 20px; }
.summary-total .stat-value { font-size: 40px; line-height: 1.1; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.stat {
    --side: var(--border);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-left: 3px solid var(--side);
    border-radius: 8px;
    padding: 10px 16px;
    min-width: 0;
}
.stat-value { display: block; font-size: 24px; font-weight: 700; font-variant-numeric: tabular-nums; }
.stat-label { color: var(--muted); font-size: 13px; }
.stat-value-text { font-size: 18px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* a fixed row of four tiles (the guild card); narrow tiles wrap their text instead of cutting it */
.stats-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.stats-group { display: grid; gap: 12px; }
.stats-4 .stat-value-text { font-size: 16px; white-space: normal; }
@media (max-width: 600px) {
    .stats-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.stat-online { color: var(--fresh); }
/* admin page: server health readings getting high, and too high */
.server-health { margin-bottom: 16px; }
.server-health h2 { margin: 0 0 12px; }
.health-warn { color: var(--recent); }
.health-bad { color: var(--stale); }
.stat.side-west { --side: var(--west-text); }
.stat.side-east { --side: var(--east-text); }
.stat.side-pirate { --side: var(--pirate-text); }
.stat[class*="side-"] .stat-value { color: var(--side); }
/* West/East/Pirate share of players, under the stat boxes */
.side-split { display: flex; flex-shrink: 0; height: 8px; border-radius: 999px; overflow: hidden; background: var(--border); }
.side-split span { background: var(--muted); }
.side-split .side-west { background: var(--west-text); }
.side-split .side-east { background: var(--east-text); }
.side-split .side-pirate { background: var(--pirate-text); }

.filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 8px; }
.filters input, .filters select, .filters button {
    font: inherit;
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
}
.filters input[type="search"] { min-width: 220px; flex: 1 1 220px; max-width: 320px; }
.filters label.in-stock { display: inline-flex; gap: 6px; align-items: center; cursor: pointer; }
.filters label.in-stock input { padding: 0; }
.filters button { background: var(--accent); border-color: var(--accent); color: #fff; cursor: pointer; }

.table-wrap {
    overflow-x: auto;
    /* when a table is too wide (narrow screens): a thin dark scrollbar, not the bright default */
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
    background: var(--panel);
    backdrop-filter: var(--panel-blur);
    border: 1px solid var(--border);
    border-radius: 8px;
}
table { width: 100%; border-collapse: collapse; }
th, td { padding: 8px 12px; text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
th { font-size: 13px; color: var(--muted); font-weight: 600; }
th a { color: inherit; }
tbody tr:last-child td { border-bottom: none; }
/* striped rows; no specificity (:where), so hover and a row's own background win. The homes
   table has a tbody per home (its sharecode row under it), so it's striped by home */
:where(tbody tr:nth-child(even)) { background: var(--row-stripe); }
:where(.homes-table tbody tr) { background: none; }
:where(.homes-table tbody:nth-of-type(even) tr:not(.sharecode-row)) { background: var(--row-stripe); }
tbody tr:hover { background: var(--row-hover); }
.num { text-align: right; font-variant-numeric: tabular-nums; }
/* the players list: widths from its headers, not the rows shown; too-long text is cut with
   "…" (hover for all of it) */
.players-table { table-layout: fixed; }
/* a table that fits its box (.fit-table, the layout's fitTables script): too wide, its columns
   hide in order (hide-1 first) until it fits, the box getting fit-1, fit-2, ... for each; a
   row's + (components/more-toggle) lists the hidden ones under it (components/more-row). A
   tbody per row (its row, and that one), so it's striped and ruled by row */
:where(.fit-table tbody tr) { background: none; }
:where(.fit-table tbody:nth-of-type(even) tr) { background: var(--row-stripe); }
.fit-table tbody:last-of-type tr:first-child td { border-bottom: none; }
.fit-table .more-toggle, .fit-table .more-row, .more-list > div { display: none; }
.more-toggle { padding: 1px; margin-right: 6px; vertical-align: middle; }
.more-toggle .icon { width: 13px; height: 13px; }
.fit-table tr.more-row td { padding-top: 0; white-space: normal; }
.more-list { display: flex; flex-wrap: wrap; gap: 6px 28px; margin: 0 0 0 26px; font-size: 13px; }
.more-list dt { display: inline; color: var(--muted); margin-right: 6px; }
.more-list dd { display: inline; margin: 0; }
.fit-1 .more-toggle { display: inline-flex; }
.fit-1 .more-row { display: table-row; }
/* an open row's line goes under its hidden columns instead */
.fit-1 tbody.open tr:first-child td { border-bottom: none; }
.fit-1 tbody.open:not(:last-of-type) tr.more-row td { border-bottom: 1px solid var(--border); }
.fit-1 .hide-1 { display: none; } .fit-1 .more-1 { display: block; }
.fit-2 .hide-2 { display: none; } .fit-2 .more-2 { display: block; }
.fit-3 .hide-3 { display: none; } .fit-3 .more-3 { display: block; }
.fit-4 .hide-4 { display: none; } .fit-4 .more-4 { display: block; }
.fit-5 .hide-5 { display: none; } .fit-5 .more-5 { display: block; }
.fit-6 .hide-6 { display: none; } .fit-6 .more-6 { display: block; }
.fit-7 .hide-7 { display: none; } .fit-7 .more-7 { display: block; }
.fit-8 .hide-8 { display: none; } .fit-8 .more-8 { display: block; }
.fit-9 .hide-9 { display: none; } .fit-9 .more-9 { display: block; }
.fit-10 .hide-10 { display: none; } .fit-10 .more-10 { display: block; }
.players-table td { overflow: hidden; text-overflow: ellipsis; }
.players-table td button.link { max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; vertical-align: bottom; }
.when { cursor: help; }
/* the players list: the name leads the row, in the text colour; the guild comes second, in
   muted grey; both turn the link colour when hovered */
a.player-name { color: var(--text); font-weight: 500; }
button.link.guild-name { color: var(--muted); }
a.player-name:hover, button.link.guild-name:hover { color: var(--accent); }
/* last seen: green dot within 30 mins, amber within 2 hours, red within 5 hours, none after that (components/when.blade.php) */
.when.seen-fresh::before, .when.seen-recent::before, .when.seen-stale::before {
    content: "";
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-right: 6px;
    border-radius: 50%;
    vertical-align: 1px;
}
.when.seen-fresh::before { background: var(--fresh); box-shadow: 0 0 0 3px color-mix(in srgb, var(--fresh) 25%, transparent); }
.when.seen-recent::before { background: var(--recent); }
.when.seen-stale::before { background: var(--stale); }
/* gear score brackets (components/gear-score.blade.php) */
/* even steps from the top bracket's purple down to the bottom bracket's green */
:root { --gs-top: #b09afe; --gs-bottom: #78b165; }
.gs-8700 { color: var(--gs-top); }
.gs-8000 { color: color-mix(in oklch, var(--gs-top) 87.5%, var(--gs-bottom)); }
.gs-7800 { color: color-mix(in oklch, var(--gs-top) 75%, var(--gs-bottom)); }
.gs-7500 { color: color-mix(in oklch, var(--gs-top) 62.5%, var(--gs-bottom)); }
.gs-7000 { color: color-mix(in oklch, var(--gs-top) 50%, var(--gs-bottom)); }
.gs-6500 { color: color-mix(in oklch, var(--gs-top) 37.5%, var(--gs-bottom)); }
.gs-6000 { color: color-mix(in oklch, var(--gs-top) 25%, var(--gs-bottom)); }
.gs-base { color: color-mix(in oklch, var(--gs-top) 12.5%, var(--gs-bottom)); }
.gs-4000 { color: var(--gs-bottom); }
.level-ancestral { display: inline-flex; align-items: center; gap: 4px; color: var(--gold); font-weight: 600; }
.level-ancestral img { display: block; height: 1.1em; width: auto; }

.badge {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    background: var(--row-hover);
    color: var(--muted);
    vertical-align: middle;
}
.side-west { background: var(--west-bg); color: var(--west-text); }
.side-east { background: var(--east-bg); color: var(--east-text); }
.side-pirate { background: var(--pirate-bg); color: var(--pirate-text); }

.gain { color: var(--gain); font-weight: 600; }
.loss { color: var(--stale); font-weight: 600; }

/* regrade results (components/regrade-result) */
.regrade-result { font-weight: 600; }
.regrade-success { color: var(--fresh); }
.regrade-loss { color: var(--recent); }
.regrade-destroyed { color: var(--stale); }
/* grades in their colours, as darugear.com (and the game) colour items: Crude 0 to Eternal 12
   (components/grade, regrade-grades, regrade-item) */
.grade-0 { color: #949293; }
.grade-1 { color: #ffffff; }
.grade-2 { color: #77b064; }
.grade-3 { color: #558fd7; }
.grade-4 { color: #cb72d8; }
.grade-5 { color: #d78b06; }
.grade-6 { color: #e17853; }
.grade-7 { color: #f95252; }
.grade-8 { color: #cf7d5d; }
.grade-9 { color: #8fa5ca; }
.grade-10 { color: #bf7900; }
.grade-11 { color: #ff3030; } /* darugear has #c90b0b, too dark to read here */
.grade-12 { color: #ae98fe; }

.card {
    background: var(--panel);
    backdrop-filter: var(--panel-blur);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 20px;
}
.card h1 { display: flex; align-items: center; gap: 10px; }
.details { display: grid; grid-template-columns: max-content 1fr; gap: 6px 24px; margin: 0; }
.details dt { color: var(--muted); }
.details dd { margin: 0; }
.report-recorders { margin: 4px 0 0; padding-left: 18px; }

[x-cloak] { display: none !important; }

/* Gear score chart */
.chart { position: relative; margin: 0; }
.chart svg:not(.icon) { display: block; width: 100%; height: auto; overflow: visible; touch-action: pan-y; }
.chart svg:not(.icon):focus { outline: none; }
.chart svg:not(.icon):focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; }
.chart .grid { stroke: var(--border); stroke-width: 1; }
.chart .axis { fill: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.chart .line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart .marker { fill: var(--accent); stroke: var(--surface); stroke-width: 2; }
.chart .marker.active { r: 6; }
.chart .crosshair { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 3 3; }
/* Activity chart: hovering a bar dims the others */
.chart .bar { fill: var(--accent); transition: opacity 0.1s; }
.chart:has(.bar.active) .bar:not(.active) { opacity: 0.45; }
.chart-note { margin: 0 0 12px; font-size: 13px; }
.chart-tip {
    position: absolute;
    pointer-events: none;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 4px 10px;
    font-size: 13px;
    white-space: nowrap;
    box-shadow: 0 2px 8px rgb(0 0 0 / 0.12);
}
.chart-tip strong { font-variant-numeric: tabular-nums; margin-right: 6px; }

/* Regrades page: the observed odds, collapsed to a one-line toggle until opened */
.regrade-odds { margin-bottom: 16px; }
.regrade-odds .odds-toggle { font-weight: 600; }
.regrade-odds h3 { margin: 16px 0 6px; font-size: 15px; }
.regrade-odds .odds-total td { font-weight: 600; border-top: 1px solid var(--border); }

/* player page: the regrade luck score opens how it was worked out */
button.link.luck-toggle { text-decoration: underline dotted; text-underline-offset: 3px; }
.luck-breakdown { margin-top: 16px; }
.luck-breakdown .odds-total td { font-weight: 600; border-top: 1px solid var(--border); }
.luck-steps { margin: 12px 0 0; padding-left: 20px; line-height: 1.6; }
.tabs { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.tabs a, .tabs button { font: inherit; background: none; cursor: pointer; padding: 4px 12px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); }
.tabs a.active, .tabs button.active { background: var(--accent); border-color: var(--accent); color: #fff; }

.pages { display: flex; gap: 16px; align-items: center; justify-content: center; margin: 16px 0; color: var(--muted); }

@media (max-width: 600px) {
    .top { padding: 12px 16px; gap: 16px; }
}

/* Livewire controls */
button.sort, button.link {
    font: inherit;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: inherit;
}
button.link { color: var(--accent); }
button.link:hover, button.sort:hover { text-decoration: underline; }
th button.sort { font-weight: 600; }

/* icons (components/icon.blade.php, Lucide): the text's colour, a little bigger than it */
.icon { width: 1.15em; height: 1.15em; flex-shrink: 0; vertical-align: -0.2em; }
/* a button that's just an icon (its words in title and aria-label) */
.icon-button {
    display: inline-flex; align-items: center; justify-content: center;
    font: inherit; line-height: 1;
    padding: 3px 6px;
    border: 1px solid var(--border); border-radius: 6px;
    background: var(--surface); color: var(--accent); cursor: pointer;
}
.icon-button:hover { border-color: currentColor; }
button.link.icon-button { border: none; background: none; padding: 2px; }
/* a link or button with an icon beside its words */
.back-link, .with-icon, .pages button { display: inline-flex; align-items: center; gap: 4px; }
.back-link .icon { margin-left: -4px; }
/* sorted column, and the collapsed / open toggles */
.sort-icon { width: 1em; height: 1em; margin-left: 2px; }
.sort-icon-then { opacity: 0.6; }
.toggle-icon { transition: transform 0.15s; }
.toggle-icon.open { transform: rotate(90deg); }
.map-zoom button { display: inline-flex; align-items: center; justify-content: center; }

.pages button {
    font: inherit;
    padding: 4px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--accent);
    cursor: pointer;
}

.users td button {
    font: inherit;
    font-size: 13px;
    margin-left: 6px;
    padding: 2px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--accent);
    cursor: pointer;
}
.nickname-edit { display: flex; gap: 6px; align-items: center; }
.nickname-edit input {
    font: inherit;
    font-size: 14px;
    padding: 2px 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    width: 14em;
}
.users .nickname-edit button { margin-left: 0; }
.users td .icon-button { padding: 3px 6px; }
/* a nickname: hover for the email */
.users .user-name { cursor: help; text-decoration: underline dotted var(--muted); text-underline-offset: 3px; }
/* the Users page's Created and Last login columns: an icon with the date as its tooltip */
.icon-cell { text-align: center; }
.date-icon { display: inline-flex; color: var(--muted); cursor: help; vertical-align: middle; }
.date-icon:hover { color: var(--text); }
/* a class as its role's icon (components/class-role.blade.php): in its colour on a tint of it */
.role-tank { --role: var(--tank); }
.role-dps { --role: var(--dps); }
.role-healer { --role: var(--healer); }
.role-archer { --role: var(--archer); }
.role-mage { --role: var(--mage); }
.role-melee { --role: var(--melee); }
.role-none { --role: var(--muted); }
.role { display: inline-flex; vertical-align: middle; cursor: help; padding: 3px; border-radius: 999px; color: var(--role); background: color-mix(in srgb, var(--role) 18%, transparent); }
.role .icon { width: 14px; height: 14px; vertical-align: 0; }
/* a DPS role: its orb cut corner to corner at 45 degrees, DPS red and the role's colour */
.role.dps-kind, .role-toggle.dps-kind.on {
    color: color-mix(in srgb, var(--role) 45%, white);
    background: linear-gradient(135deg, color-mix(in srgb, var(--dps) 55%, transparent) 50%, color-mix(in srgb, var(--role) 70%, transparent) 50%);
}
/* a guild's members by role (components/role-split.blade.php): one full-width bar, a part per role */
.role-split {
    display: flex; height: 34px; margin-bottom: 16px; overflow: hidden;
    border: 1px solid var(--border); border-radius: 8px; background: var(--panel); backdrop-filter: var(--panel-blur);
}
.role-split > span {
    flex: 0 1 0; min-width: 0; overflow: hidden; white-space: nowrap; cursor: help;
    display: flex; align-items: center; justify-content: center; gap: 6px; padding: 0 8px;
    font-size: 13px; font-weight: 600;
    color: var(--role); background: color-mix(in srgb, var(--role) 24%, var(--surface));
}
.role-split > span + span { border-left: 1px solid var(--bg); }
.role-split .count { color: var(--text); }
/* the Class roles page: both tables' columns line up (partials/class-roles-table.blade.php);
   a role's button, in its colour while the class has it */
.class-roles-table { table-layout: fixed; }
.role-toggle {
    display: inline-flex; padding: 5px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--border); background: none; color: var(--muted);
}
.role-toggle:hover, .role-toggle:focus-visible { border-color: var(--role); color: var(--role); }
.role-toggle.on { color: var(--role); background: color-mix(in srgb, var(--role) 18%, transparent); border-color: color-mix(in srgb, var(--role) 50%, transparent); }
/* the Users page note: wraps (cells don't otherwise) with its line breaks kept */
.users td.user-note { white-space: normal; min-width: 10em; max-width: 28em; }
.users .note-text { white-space: pre-line; }
.note-edit { display: flex; flex-direction: column; gap: 6px; }
.note-edit textarea {
    font: inherit;
    font-size: 14px;
    padding: 4px 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    width: 100%;
    resize: vertical;
}
.users .note-edit button { margin-left: 0; margin-right: 6px; }
/* status badges that switch the status when clicked (Users page) */
.users td button.toggle {
    margin-left: 0;
    padding: 1px 8px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    background: var(--row-hover);
    color: var(--muted);
}
.users td button.toggle.on { color: var(--gain); }
/* what API access may upload: one badge each, dimmed while API access is off */
.users .api-scopes button.toggle { margin-right: 4px; }
.users td.api-scopes.muted button.toggle { opacity: 0.5; }
.users td button.link { margin-left: 6px; padding: 0; border: none; background: none; }
/* user's Uploads page: what one upload wrote, under its row */
.upload-changes { font-size: 13px; }
.upload-changes td { padding: 3px 8px; white-space: normal; vertical-align: top; }
.users td button.toggle:hover, .users td button.toggle:focus-visible { border-color: currentColor; }
.error { color: var(--east-text); font-size: 13px; }
.badge.on { color: var(--gain); }
.notice { color: var(--gain); font-size: 13px; }
/* API page: the steps beside a screenshot of PlayerDB Sync, then its README */
.api-setup { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 660px); gap: 16px; align-items: start; }
.api-setup h2:first-child { margin-top: 0; }
.api-setup h2 { font-size: 16px; margin: 20px 0 8px; }
.api-setup p { margin: 0 0 8px; }
.api-fields { align-items: baseline; row-gap: 12px; }
.api-fields code { font-size: 14px; margin-right: 8px; }
.api-key { display: block; margin: 8px 0; word-break: break-all; user-select: all; }
button.action, a.action {
    font: inherit; padding: 6px 12px; border-radius: 6px; cursor: pointer;
    background: var(--accent); border: 1px solid var(--accent); color: #fff;
}
a.action { display: inline-block; text-decoration: none; }
/* something that can't be taken back, e.g. deleting a raid */
button.action.danger { background: var(--east-text); border-color: var(--east-text); }
button.action.danger:hover { filter: brightness(1.08); }
button.action.secondary { background: none; border-color: var(--border); color: var(--text); }
button.action.secondary:hover { border-color: var(--muted); }
.raid-delete { margin-top: 32px; }

/* wire:confirm's question (askToConfirm in site.js) */
.confirm-dialog {
    width: min(440px, calc(100vw - 32px));
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    color: var(--text);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}
.confirm-dialog::backdrop { background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(2px); }
.confirm-dialog form { padding: 20px; }
.confirm-message { margin: 0 0 20px; line-height: 1.5; white-space: pre-line; overflow-wrap: anywhere; }
.confirm-buttons { display: flex; justify-content: flex-end; gap: 8px; }
.confirm-buttons button { min-width: 84px; }
a.action:hover { text-decoration: none; filter: brightness(1.08); }
.admin-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* admin page's site settings, and the bank's add form */
.site-settings, .bank-add { margin: 16px 0; }
.site-settings h2:first-child, .bank-add h2:first-child { margin-top: 0; }
.site-settings h2 { font-size: 16px; }
/* a raid's points and gold payout forms, for admins */
.raid-rewards { margin: 16px 0; }
.raid-rewards form:last-of-type { margin-bottom: 0; }
.raid-rewards label { min-width: 150px; }
/* a raid's details and reward forms, with the loot totals beside them */
.raid-top { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.raid-top .raid-rewards { margin-bottom: 0; }
.raid-side .raid-loot + .raid-loot { margin-top: 16px; }
/* a raid's screenshots, and their thumbnails on the Raid images page */
.raid-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.raid-gallery a { position: relative; display: block; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--panel); }
.raid-gallery img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
/* a screenshot's place in the order taken, then why RaidsDB asked for it, over its top left corner */
.raid-image-tags { position: absolute; top: 6px; left: 6px; display: flex; gap: 4px; }
.raid-image-tags .badge { background: var(--panel); border: 1px solid var(--border); text-transform: capitalize; }
.raid-image-number { color: var(--text); font-variant-numeric: tabular-nums; }
.raid-image-tag-start { color: var(--gain); }
.raid-image-tag-end { color: var(--east-text); }
.raid-image-tag-drop { color: var(--gold); }
/* an image full screen (x-image-viewer), over everything, with an X top right */
.image-viewer { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(0, 0, 0, 0.9); }
.image-viewer img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; }
.image-viewer-close { position: absolute; top: 12px; right: 12px; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; padding: 0; border: 1px solid rgba(255, 255, 255, 0.3); border-radius: 50%; background: rgba(0, 0, 0, 0.6); color: #fff; cursor: pointer; }
.image-viewer-close:hover { background: rgba(255, 255, 255, 0.15); }
.image-viewer-close svg { width: 22px; height: 22px; }
.raid-image-thumb { display: block; width: 96px; height: 54px; object-fit: cover; border-radius: 4px; border: 1px solid var(--border); }
.raid-loot h2 { margin-top: 0; font-size: 16px; }
/* room on the right so an overlay scrollbar (Windows 11) doesn't sit on the counts */
.raid-loot ul { list-style: none; margin: 0; padding: 0 12px 0 0; max-height: 320px; overflow-y: auto; }
.raid-loot li { display: flex; justify-content: space-between; gap: 16px; padding: 3px 0; border-bottom: 1px solid var(--border); }
.raid-loot li:last-child { border-bottom: 0; }
.raid-loot .num { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* how many of a merged raid's reports recorded an item: a segment each, lit for the ones that did */
.raid-loot .loot-count { display: inline-flex; align-items: center; gap: 8px; }
.report-meter { display: inline-flex; gap: 2px; cursor: help; }
.report-meter span { width: 10px; height: 8px; border-radius: 2px; background: var(--border); }
.report-meter span.on { background: var(--accent); }
@media (max-width: 1000px) {
    .raid-top { grid-template-columns: minmax(0, 1fr); }
}
/* a raid member the addon didn't see with the raid, and each time they joined and left */
.not-seen { display: inline-flex; vertical-align: middle; cursor: help; color: var(--stale); }
.not-seen svg { stroke-width: 3; }
tr.raid-stays td { padding-top: 0; padding-left: 52px; }
/* an upload's rows, under it on its user's uploads page */
tr.upload-details > td { padding-left: 52px; }
.raid-stays ol { margin: 0; padding-left: 20px; }
/* a raid member in the host guild (SiteSetting::GUILD) */
.host-star { display: inline-flex; vertical-align: middle; cursor: help; color: var(--gold); }
.host-star svg { fill: currentColor; }
/* a raid's name: admins click it to rename the raid */
h1 button.link.raid-name { color: inherit; font-weight: inherit; }
.raid-rename { display: flex; gap: 4px; align-items: center; margin: 24px 0 4px; }
.raid-rename input { font: inherit; font-size: 20px; padding: 4px 8px; min-width: 0; flex: 0 1 420px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); color: var(--text); }
/* a player's page: admins' "Name changed" button, and the panel it opens */
h1 button.link.name-changed { font-size: 14px; font-weight: normal; margin-left: 8px; vertical-align: middle; }
.name-change { margin: 16px 0; }
.name-change h2:first-child { margin-top: 0; }
/* bank: admins click a points item to spend a member's points on it */
.bank-spend { margin: 16px 0; }
.bank-spend h2:first-child { margin-top: 0; }
.bank-spend .filters button.link { background: none; border: none; color: var(--accent); padding: 0 4px; }
.bank button.bank-item.picked { font-weight: 600; text-decoration: underline; }
/* a locked bank item's padlock, and the admins' lock button while it's locked */
.bank-lock { display: inline-flex; vertical-align: middle; color: var(--gold); cursor: help; margin-right: 4px; }
.bank .icon-button.bank-lock { cursor: pointer; margin-right: 0; }
.bank-actions { white-space: nowrap; }
.bank .price-edit { display: inline-flex; gap: 4px; align-items: center; }
.bank .price-edit input { width: 110px; text-align: right; font: inherit; font-size: 13px; padding: 2px 6px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); color: var(--text); }
.bank td select { font: inherit; font-size: 13px; padding: 2px 4px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); color: var(--text); }
/* regrade costs page: fields in the table cells */
.costs td input, .costs td select { font: inherit; font-size: 13px; padding: 2px 6px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); color: var(--text); }
/* no up / down arrows: they sat against the number, and prices are typed anyway */
.costs td input[type="number"] { width: 110px; text-align: right; padding-right: 8px; appearance: textfield; -moz-appearance: textfield; }
.costs td input[type="number"]::-webkit-inner-spin-button,
.costs td input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
/* items page: an item's market price for each grade */
.market-prices { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.market-prices label { display: flex; flex-direction: column; gap: 2px; font-size: 12px; }
.market-note { font-size: 12px; margin: 8px 0 0; }
.per-grade-heading { font-size: 13px; margin: 4px 0 8px; }
.market-note + .per-grade-heading { margin-top: 16px; }
.api-shot { margin: 0; padding: 12px; }
.api-shot img { display: block; width: 100%; height: auto; border-radius: 4px; }
.api-shot figcaption { margin-top: 8px; font-size: 13px; }
@media (max-width: 1000px) {
    .api-setup { grid-template-columns: minmax(0, 1fr); }
}
.readme { max-width: 960px; line-height: 1.55; }
.readme h1 { font-size: 22px; }
.readme h2 { font-size: 18px; margin: 24px 0 8px; }
.readme h3 { font-size: 16px; margin: 20px 0 8px; }
.readme > :first-child { margin-top: 0; }
.readme table { width: auto; margin: 8px 0 16px; }
.readme th, .readme td { white-space: normal; vertical-align: top; }
.readme code { font-size: 0.9em; }
.readme pre { overflow-x: auto; padding: 12px; border: 1px solid var(--border); border-radius: 6px; }
/* Admin options: phpMyAdmin, served by the site under /phpmyadmin/ */
.pma-frame { display: block; width: 100%; height: calc(100vh - 220px); min-height: 480px; border: 1px solid var(--border); border-radius: 6px; background: #fff; }
.new-key { margin-bottom: 16px; }
.new-key p { margin: 0 0 8px; }
.new-key code { display: block; margin-bottom: 8px; font-size: 14px; word-break: break-all; user-select: all; }

.spinner { color: var(--muted); font-size: 13px; }
.loading { opacity: 0.55; transition: opacity 0.15s; }

.account { margin-left: auto; display: flex; gap: 12px; align-items: center; font-size: 14px; }
/* an admin's ghost (livewire/access-preview), by their name: green while previewing other
   access; its panel drops down under it */
.access-preview { margin-left: auto; position: relative; display: flex; align-items: center; }
.access-preview + .account { margin-left: 0; }
.access-ghost.on { color: var(--gain); border-color: var(--gain); background: color-mix(in srgb, var(--gain) 15%, transparent); }
.access-panel { position: absolute; top: calc(100% + 8px); right: 0; z-index: 20; width: 260px; padding: 14px 16px; font-size: 14px; }
.access-panel p { margin: 0 0 10px; font-size: 13px; }
.access-panel label { display: flex; align-items: center; gap: 8px; padding: 3px 0; cursor: pointer; }
.access-panel .scopes { padding-left: 22px; }
.access-panel .stranger { margin-top: 6px; padding-top: 9px; border-top: 1px solid var(--border); }
.access-panel button.action { margin-top: 10px; width: 100%; }
@media (max-width: 600px) {
    .account .muted { display: none; }
}

/* Login page */
.login { min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.login-card { width: 100%; max-width: 380px; text-align: center; padding: 32px 24px; }
.login-card h1 { justify-content: center; margin-bottom: 8px; }
.login-card p { margin: 0 0 24px; }
.button {
    display: inline-block;
    padding: 10px 20px;
    border-radius: 6px;
    background: var(--accent);
    color: #fff;
    font-weight: 600;
}
.button:hover { text-decoration: none; filter: brightness(1.08); }
.login-status { margin: 16px 0 0; }

/* Tools, and its Cookbook */
.tools-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
a.tool-card { display: block; color: var(--text); text-decoration: none; }
a.tool-card:hover { border-color: var(--accent); text-decoration: none; }
.tool-card h2 { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; color: var(--accent); }
.tool-card p { margin: 0; }
.money { white-space: nowrap; font-variant-numeric: tabular-nums; }
.money-gold { color: var(--gold); }
.money-silver { color: #c4cad4; }
.money-copper { color: #d08a5a; }
.money.loss .money-gold, .money.loss .money-silver, .money.loss .money-copper { color: var(--stale); }
.money-input { display: inline-flex; align-items: center; gap: 4px; }
.money-input input { width: 64px; }
.money-input input:first-child { width: 90px; }
.recipe-form { margin-bottom: 24px; }
.recipe-form h2 { margin-top: 0; }
.recipe-form h3 { font-size: 15px; margin: 20px 0 8px; }
.recipe-form input, .recipe-form select {
    font: inherit; padding: 6px 8px; border: 1px solid var(--border); border-radius: 6px;
    background: var(--surface); color: var(--text);
}
.recipe-form input[type="checkbox"] { padding: 0; }
.recipe-fields { display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: flex-end; }
.recipe-fields label, .recipe-field { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
.recipe-fields label input[type="text"] { min-width: 240px; }
.recipe-fields label input[type="number"] { width: 110px; }
.recipe-materials { display: flex; flex-direction: column; gap: 8px; }
.recipe-material { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.recipe-material select { max-width: 220px; }
.recipe-material .recipe-qty { width: 80px; }
.recipe-material .recipe-bound { display: inline-flex; gap: 4px; align-items: center; cursor: pointer; }
.recipe-material input.recipe-material-name { min-width: 200px; flex: 1 1 200px; max-width: 320px; }
.recipe-errors { margin: 12px 0 0; padding-left: 18px; }
.cookbook .badge { margin-left: 6px; font-size: 12px; }
.cookbook .spl-low { color: var(--stale); }
.cookbook .spl-mid { color: #c4cad4; }
.cookbook .spl-good { color: var(--gain); }
.market-speed { font-weight: 600; }
.market-speed.dead { color: var(--muted); }
.market-speed.slow { color: var(--stale); }
.market-speed.normal { color: var(--recent); }
.market-speed.fast { color: var(--gain); }
.recipe-actions { text-align: right; white-space: nowrap; }
.recipe-details > td { background: var(--row-stripe); white-space: normal; }
.recipe-flow { display: flex; align-items: center; gap: 8px; margin: 4px 0 4px 22px; }
.recipe-box { border: 1px solid var(--border); border-radius: 8px; background: var(--surface); padding: 8px 4px; align-self: stretch; }
.recipe-box h4 { margin: 0 10px 4px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.recipe-flow-title { margin: 10px 0 4px 22px; font-size: 13px; font-weight: 600; }
.recipe-flow-arrow { flex: none; color: var(--muted); width: 20px; height: 20px; }
@media (max-width: 1000px) {
    .recipe-flow { flex-direction: column; align-items: stretch; margin-left: 0; }
    .recipe-flow-title { margin-left: 0; }
    .recipe-flow-arrow { align-self: center; transform: rotate(90deg); }
}
.recipe-breakdown { width: auto; font-size: 13px; }
.recipe-breakdown tr { background: none; }
.recipe-breakdown td { border: none; padding: 3px 10px; white-space: normal; }
.recipe-breakdown td.num { white-space: nowrap; }
.recipe-breakdown .recipe-sum td { font-weight: 600; border-top: 1px solid var(--border); }
/* Cookbook category picker: a grid of icons with their names below; and a recipe's icon */
.category-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 10px; margin: 0 0 16px; }
.category-tile {
    display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 10px 6px 8px;
    font: inherit; font-size: 13px; color: var(--text); text-align: center; cursor: pointer;
    background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
}
.category-tile:hover { border-color: var(--muted); }
.category-tile.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.category-tile .muted { font-size: 12px; }
.category-image { width: 56px; height: 56px; border-radius: 6px; }
.recipe-category { width: 20px; height: 20px; margin-left: 6px; border-radius: 3px; vertical-align: middle; }
@media (max-width: 600px) {
    .category-grid { grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 8px; }
    .category-image { width: 44px; height: 44px; }
}
/* Cookbook prices (admin page): each material and made item, priced once */
.cookbook-prices h3 { font-size: 14px; margin: 16px 0 8px; }
.cookbook-prices h3:first-of-type { margin-top: 0; }
/* Bake, by a recipe's name (partials/recipe-bake): what you have, Let's cook, then the plan */
button.action.bake-button { padding: 2px 8px; margin-right: 6px; font-size: 12px; vertical-align: middle; }
.bake-have { display: flex; flex-wrap: wrap; gap: 10px 20px; margin: 4px 0 0 22px; }
.bake-have label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.bake-have input { width: 110px; }
.bake .admin-actions, .bake .error { margin: 10px 0 4px 22px; }
.bake-plan .bake-buy-first td { border-top: 1px dashed var(--border); }
@media (max-width: 1000px) {
    .bake-have, .bake .admin-actions, .bake .error { margin-left: 0; }
}
.recipe-ways tr.active td { background: rgba(127, 127, 127, 0.12); }
.recipe-ways th { text-align: left; font-weight: 600; }
.recipe-ways th.num { text-align: right; }
.price-pager { display: flex; gap: 0.75rem; align-items: center; }
.price-table { width: auto; }
.price-table th, .price-table td { text-align: left; vertical-align: middle; padding: 4px 24px 4px 0; }
.price-table .price-name { min-width: 220px; }
.price-updated { white-space: nowrap; }
