/**
 * Layout and components, following the GenosDB design guide.
 *
 * Chrome lives at the edges in bands of one height (48px); the content occupies
 * the middle and nothing else does. One surface throughout — 1px borders
 * divide, never a darker well.
 */

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  font: 14px/1.5 var(--font);
  color: var(--text-primary);
  background: var(--bg-primary);
}

.hidden {
  display: none !important;
}

/* ── Bands ─────────────────────────────────────────────────────────── */

.layout {
  display: grid;
  grid-template-rows: auto 1fr;
  height: 100vh;
  height: 100dvh;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 48px;
  padding: var(--space-2) var(--space-5);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-subtle);
}

.brand {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.brand span {
  font-weight: 400;
  color: var(--text-tertiary);
}

.session {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-right: -6px;
}

.session-addr {
  padding: 0;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-secondary);
  background: none;
  border: none;
}

.role-tag {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
}

.role-tag[data-role="user"] {
  color: var(--ok);
}
.role-tag[data-role="creator"] {
  color: var(--accent);
}
.role-tag[data-role="client"] {
  color: var(--warn);
}
.role-tag[data-role="superadmin"] {
  color: var(--violet);
}

.body {
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
  min-height: 0;
}

.sidebar {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  background: var(--bg-secondary);
  border-right: 1px solid var(--border-subtle);
}

.sidebar-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
}

.sidebar-head .icon-btn {
  margin-right: -6px;
}

.sidebar-head input.search {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  font-size: 13px;
}

/* No list has claimed the box yet, so it says so rather than accepting typing
   it cannot answer. */
.sidebar-head input.search:disabled {
  /* Overriding the generic `input:disabled`, which paints a field background
     the box does not have: here it sits inside the head band. */
  background: none;
  opacity: 0.5;
  cursor: not-allowed;
}

.search-icon {
  flex: 0 0 15px;
  width: 15px;
  height: 15px;
  color: var(--text-tertiary);
}

.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  background: var(--bg-secondary);
}

.content {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: var(--space-5);
}

.statusbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 48px;
  padding: var(--space-2) var(--space-5);
  background: var(--bg-secondary);
  border-top: 1px solid var(--border-subtle);
  font-size: 12px;
  color: var(--text-tertiary);
}

.presence {
  font-family: var(--mono);
}

/* ── Side switcher: the three views over one graph ─────────────────── */

/* Words divided by a rule, not three buttons. The switcher sits in chrome next
   to the layout control, so it should read as one thing you are choosing
   within — the way a set of tabs does — rather than as three offers. */
.sides {
  display: flex;
  align-items: center;
}

.side-btn {
  padding: 4px var(--space-3);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  background: none;
  border: none;
  border-radius: 0;
}

.side-btn:hover {
  color: var(--text-primary);
  background: none;
}

/* The separator is a border rather than a character: it aligns itself, and
   there is no glyph to inherit a colour it should not have. */
.side-btn + .side-btn {
  border-left: 1px solid var(--border-subtle);
}

.side-btn[aria-current="true"] {
  color: var(--accent);
  font-weight: 600;
}

/* ── Lists ─────────────────────────────────────────────────────────── */

.item-list {
  flex: 1;
  min-height: 0;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.item {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  border-left: 2px solid transparent;
  cursor: pointer;
}

.item:hover {
  background: var(--bg-tertiary);
}

.item[aria-current="true"] {
  background: var(--bg-tertiary);
  border-left-color: var(--accent);
}

.item-title {
  font-weight: 600;
}

.item-excerpt {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-size: 12px;
  color: var(--text-secondary);
}

.list-empty,
.empty {
  padding: var(--space-5);
  color: var(--text-secondary);
  text-align: center;
}

.empty {
  flex: 1;
  display: grid;
  place-items: center;
}

/* ── Cards & meta ──────────────────────────────────────────────────── */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-4);
}

.card {
  padding: var(--space-4);
  background: var(--bg-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}

.card:hover {
  border-color: var(--border-strong);
}

.addr {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-tertiary);
}

.verdict {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.verdict[data-verdict="approved"] {
  color: var(--ok);
}
.verdict[data-verdict="rejected"] {
  color: var(--danger);
}
.verdict[data-verdict="pending"] {
  color: var(--warn);
}
.verdict[data-verdict="paid"] {
  color: var(--violet);
}

/* ── The network, on a map ─────────────────────────────────────────────
   Leaflet paints inside this box; the tiles are Esri's keyless canvas, dark or
   light to follow the palette. */
.peer-plot {
  height: 320px;
  margin: var(--space-3) 0;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--bg-tertiary);
  z-index: 0; /* keep Leaflet's panes under the app's dialogs */
}

.peer-plot .leaflet-control-attribution {
  background: var(--bg-secondary);
  color: var(--text-tertiary);
  font-size: 10px;
}

.peer-plot .leaflet-control-attribution a {
  color: var(--text-secondary);
}

/* ── The queue, as a table (design guide §5.4) ─────────────────────────
   Separators rather than boxes, no zebra striping, addresses in mono, and row
   actions kept out of the way until the row is the one being read. */
.queue {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.queue th {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-strong);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
  text-align: left;
}

.queue td {
  padding: var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  vertical-align: top;
}

.queue tr.picked td {
  background: var(--bg-tertiary);
}

/* Real widths rather than `width: 1%`. Collapsing the meta columns pushes them
   into a huddle on the right of a wide screen and leaves the first column with
   a field of empty space — the columns line up either way, but it reads as a
   layout that was never looked at. */
.col-pick {
  width: 36px;
}

.col-who {
  width: 22%;
  min-width: 120px;
}

.col-verdict {
  width: 15%;
  min-width: 96px;
}

.col-actions {
  width: 260px;
  white-space: nowrap;
  text-align: right;
}

.cell-stack {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

/* Out of the way until wanted: the row you are reading is the row that offers
   its controls. Focus counts as reading, so the keyboard is not shut out. */
.row-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  opacity: 0;
  transition: opacity 0.12s ease;
}

.queue tr:hover .row-actions,
.row-actions:focus-within,
.queue tr.picked .row-actions {
  opacity: 1;
}

.row-actions input[type="text"] {
  width: 140px;
}

/* Coarse pointers have no hover to reveal anything with. */
@media (hover: none) {
  .row-actions {
    opacity: 1;
  }
}

/* ── The same rows, as cards ───────────────────────────────────────────
   No second renderer: the table is the markup and this is a presentation of
   it, so the two can never disagree about what a list contains. */
[data-view="cards"] .queue {
  display: block;
}

[data-view="cards"] .queue thead {
  display: none; /* a card carries its own labels */
}

[data-view="cards"] .queue tbody {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-4);
}

[data-view="cards"] .queue tr {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  background: var(--bg-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}

[data-view="cards"] .queue tr:hover {
  border-color: var(--border-strong);
}

[data-view="cards"] .queue tr.picked {
  border-color: var(--accent);
}

[data-view="cards"] .queue td {
  display: block;
  width: auto;
  min-width: 0;
  padding: 0;
  border: 0;
  text-align: left;
}

/* A card has no column above it to say what a value is, so the cell says it. */
[data-view="cards"] .queue td[data-label]::before {
  content: attr(data-label);
  display: block;
  margin-bottom: 2px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
}

/* Nothing to hover along a row here: the actions are simply part of the card. */
[data-view="cards"] .row-actions {
  opacity: 1;
  justify-content: flex-start;
  flex-wrap: wrap;
}

[data-view="cards"] .queue tr.picked td,
[data-view="cards"] .queue td {
  background: none;
}

/* The picker belongs with the title in a card, not in a column of its own. */
[data-view="cards"] .col-pick {
  order: -1;
}

/* Which icon the toggle shows: the one you would be switching to. */
.icon-cards,
[data-view="cards"] .icon-rows {
  display: block;
}

.icon-rows,
[data-view="cards"] .icon-cards {
  display: none;
}

/* Paging controls sit under the list, never over it. */
.pager {
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

/* The evidence, reachable from the card it belongs to. */
.proof-link {
  align-self: flex-start;
  padding: 4px var(--space-2);
  font-size: 12px;
  font-family: var(--mono);
  color: var(--text-secondary);
  background: none;
  border: 1px solid var(--border-subtle);
}

.proof-link:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ── Filters & bulk selection (design guide §5.4) ──────────────────── */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.filter-btn {
  padding: 6px var(--space-3);
  font-size: 13px;
}

.filter-btn[aria-current="true"] {
  border-color: var(--accent);
  color: var(--accent);
}

/* Appears only with a selection, and shares the chrome band height so it reads
   as part of the furniture rather than something that fell into the page. */
.bulk-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 48px;
  margin-bottom: var(--space-4);
  padding: var(--space-2) var(--space-4);
  background: var(--bg-tertiary);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
}

.bulk-count {
  flex: none;
  font-size: 13px;
  font-weight: 600;
}

.bulk-bar input[type="text"] {
  flex: 1;
  min-width: 0;
}

.pick {
  flex: none;
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.card.picked {
  border-color: var(--accent);
}

/* An attempt beyond the first: the history the model refuses to overwrite. */
.attempt-tag {
  flex: none;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-tertiary);
}

/* ── Stats: numbers first, then the shape of them ──────────────────── */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.stat-value {
  font-family: var(--mono);
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.stat-label {
  font-size: 12px;
  color: var(--text-secondary);
}

/* One bar, three outcomes. The track is the whole; the fills are the parts. */
.bar {
  display: flex;
  height: 6px;
  margin-bottom: var(--space-2);
  overflow: hidden;
  background: var(--bg-tertiary);
  border-radius: 3px;
}

.bar-fill[data-verdict="approved"] {
  background: var(--ok);
}
.bar-fill[data-verdict="rejected"] {
  background: var(--danger);
}
.bar-fill[data-verdict="pending"] {
  background: var(--warn);
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  font-size: 12px;
  color: var(--text-secondary);
}

.legend-key {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 6px;
  border-radius: 2px;
}

.note {
  margin: var(--space-5) 0 0;
  font-size: 12px;
  color: var(--text-tertiary);
}

/* ── Fields ────────────────────────────────────────────────────────── */

input[type="text"],
input[type="password"],
textarea,
select {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font-family: inherit;
  font-size: 14px;
  color: var(--text-primary);
  background: var(--bg-secondary);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  outline: none;
  resize: none;
}

input[type="text"]:focus,
input[type="password"]:focus,
textarea:focus,
select:focus {
  border-color: var(--accent);
}

input::placeholder,
textarea::placeholder {
  color: var(--text-tertiary);
}

input:disabled,
textarea[readonly] {
  color: var(--text-tertiary);
  background: var(--bg-primary);
}

label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
}

.field {
  margin-bottom: var(--space-4);
}

/* ── Buttons: four weights, one vocabulary ─────────────────────────── */

button {
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: var(--space-2) var(--space-3);
  color: var(--text-primary);
  background: var(--bg-tertiary);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

button:hover:not(:disabled) {
  border-color: var(--text-tertiary);
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-on-accent);
}

button.primary:hover:not(:disabled) {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

button.ghost {
  background: transparent;
  border-color: transparent;
  color: var(--text-secondary);
}

button.ghost:hover:not(:disabled) {
  color: var(--text-primary);
  border-color: var(--border-strong);
}

button.danger {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--danger);
}

button.danger:hover:not(:disabled) {
  border-color: var(--danger);
}

.icon-btn {
  display: flex;
  width: auto;
  padding: 6px;
  background: none;
  border: none;
  color: var(--text-secondary);
}

.icon-btn svg {
  width: 16px;
  height: 16px;
}

.row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* ── The band across the content, level with the search head ───────────
   Chrome bands share one height (48px): top bar, sidebar head, this, and the
   status bar. Navigation and the layout switch live here rather than inside
   the content, which is for what the page is about. */
.content-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 48px;
  padding: var(--space-2) var(--space-5);
  border-bottom: 1px solid var(--border-subtle);
}

/* The view's name, in the same voice as the switcher opposite it — chrome, not
   a heading the content has to make room for. */
.head-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
}

#head-left {
  gap: var(--space-3);
}

/* A bare mark, not a control in a box. These sit in chrome, where a button's
   border would compete with the bands themselves. */
.head-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px;
  font-size: 13px;
  color: var(--text-secondary);
  background: none;
  border: none;
  cursor: pointer;
}

.head-btn:hover {
  color: var(--accent);
  background: none;
}

.head-btn svg {
  width: 18px;
  height: 18px;
}

/* Align the mark, not the hit area: the icon pads itself, so pull the row back
   by that padding and what lines up is what the eye can see. */
#head-left {
  margin-left: -4px;
}

#head-right {
  margin-right: -4px;
}

/* Rhythm inside a section. A toolbar sitting directly on the list it governs
   reads as part of it; the list needs room to start. */
.content section + section {
  margin-top: var(--space-6);
}

.content section > .row {
  margin-bottom: var(--space-5);
}

/* The layout switch belongs at the far end of the toolbar it governs, which is
   also where the eye lands last — after the actions, before the list. */
.view-toggle {
  display: flex;
  gap: 2px;
  margin-left: auto;
  padding: 2px;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.view-toggle .icon-btn[aria-pressed="true"] {
  color: var(--accent);
  background: var(--bg-secondary);
}

.spread {
  justify-content: space-between;
}

/* ── Dialogs ───────────────────────────────────────────────────────── */

dialog {
  width: min(440px, calc(100vw - var(--space-6)));
  padding: var(--space-6);
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  color: var(--text-primary);
  text-align: center;
}

dialog::backdrop {
  background: var(--backdrop);
  backdrop-filter: blur(2px);
}

.modal-title {
  margin: 0 0 var(--space-3);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.modal-hint {
  margin: 0 0 var(--space-5);
  font-size: 14px;
  color: var(--text-secondary);
}

.modal-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.modal-actions button {
  width: 100%;
  padding: 13px var(--space-4);
  font-size: 14px;
  font-weight: 600;
}

.modal-warn {
  display: grid;
  place-items: center;
  min-height: 45px;
  margin: var(--space-2) 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--warn);
}

/* A quiet way out of a modal that is asking for a decision the reader cannot
   make yet. */
.modal-link {
  margin-top: var(--space-3);
  padding: var(--space-2);
  background: none;
  border: 0;
  font-size: 13px;
  color: var(--text-secondary);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.modal-link:hover {
  color: var(--accent);
}

/* The help dialog is wider than the identity door and its body reads as a
   document: left-aligned, sectioned, and scrollable on a short viewport. */
dialog.help {
  width: min(520px, calc(100vw - var(--space-6)));
}

.help-body {
  text-align: left;
  max-height: min(58vh, 520px);
  overflow-y: auto;
  margin: 0 0 var(--space-4);
}

.help-body section {
  padding: var(--space-4) 0;
  border-top: 1px solid var(--border-subtle);
}

.help-body section:first-child {
  padding-top: 0;
  border-top: 0;
}

.help-body h3 {
  margin: 0 0 var(--space-2);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--accent);
}

.help-body p {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-secondary);
}

.help-body p + p {
  margin-top: var(--space-3);
}

.help-body ul,
.help-body ol {
  margin: 0;
  padding-left: var(--space-5);
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-secondary);
}

.help-body li {
  margin-bottom: var(--space-2);
}

.help-body li:last-child {
  margin-bottom: 0;
}

.help-body strong {
  color: var(--text-primary);
  font-weight: 600;
}

.mnemonic-field {
  position: relative;
}

#mnemonic-input {
  min-height: 45px;
  display: block;
  background: none;
  padding-right: 32px;
  overflow: hidden;
  font-family: var(--mono);
  font-size: 13px;
  text-align: left;
}

/* The dialog focuses this field on open, so the accent would fire before the
   visitor has done anything. The caret already says where you are. */
#mnemonic-input:focus {
  border-color: var(--border-strong);
}

.field-action {
  position: absolute;
  right: 6px;
  bottom: 6px;
  display: flex;
  padding: 5px;
  background: none;
  border: none;
  color: var(--text-tertiary);
}

.field-action svg {
  width: 15px;
  height: 15px;
}

.field-action:hover:not(:disabled) {
  color: var(--text-primary);
  border-color: transparent;
}

.side-choice {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.side-choice button {
  flex: 1;
}

.side-choice button[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--accent);
}

dialog .form-body {
  text-align: left;
}

/* ── Toasts ────────────────────────────────────────────────────────── */

.toast-stack {
  position: fixed;
  inset: auto;
  right: var(--space-5);
  bottom: var(--space-5);
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  overflow: visible;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 280px;
  max-width: 360px;
  padding: 14px 18px;
  background: var(--bg-elevated);
  color: var(--text-primary);
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--text-tertiary);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  animation: toast-in 0.3s ease;
  transition: opacity 0.4s, transform 0.4s;
}

.toast-icon {
  flex: 0 0 18px;
  text-align: center;
  font-size: 18px;
  line-height: 1;
  color: var(--text-tertiary);
}

.toast-text {
  flex: 1;
  min-width: 0;
}

.toast.success {
  border-left-color: var(--ok);
}
.toast.error {
  border-left-color: var(--danger);
}
.toast.warning {
  border-left-color: var(--warn);
}

.toast.success .toast-icon {
  color: var(--ok);
}
.toast.error .toast-icon {
  color: var(--danger);
}
.toast.warning .toast-icon {
  color: var(--warn);
}

.toast:not(:last-child) {
  opacity: 0.6;
}

.toast.out {
  opacity: 0;
  transform: translateX(20px);
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateX(100%);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .toast {
    animation: none;
  }
  .toast.out {
    transform: none;
  }
}

/* ── Theme icons: one shown per preference ─────────────────────────── */

.icon-moon,
.icon-system {
  display: none;
}

[data-pref="dark"] .icon-sun {
  display: none;
}
[data-pref="dark"] .icon-moon {
  display: block;
}
[data-pref="system"] .icon-sun {
  display: none;
}
[data-pref="system"] .icon-system {
  display: block;
}

/* ── One breakpoint, still one screen ──────────────────────────────── */

@media (max-width: 820px) {
  .body {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 38vh) minmax(0, 1fr);
  }
  .sidebar {
    border-right: none;
    border-bottom: 1px solid var(--border-subtle);
  }
  .brand span {
    display: none;
  }
}
