/* Tokens, base, components, then pages. Pages only lay components out; a
   control's look lives in its component. */

/* ---------- Fonts ---------- */

/* Inter, self-hosted: the variable font's Latin subset (fonts/SOURCES.md).
   Until it loads, Arial stands in, scaled to Inter's metrics so the swap
   moves no text. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/static/fonts/inter-latin-wght-normal.woff2?v=3100e775e8) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter fallback";
  src: local("Arial");
  ascent-override: 90.44%;
  descent-override: 22.52%;
  line-gap-override: 0%;
  size-adjust: 107.12%;
}

/* ---------- Tokens ---------- */

:root {
  color-scheme: light dark;

  --bg: #ffffff;
  --surface: #ffffff;
  --raised: #f2f3f5;
  --raised-hover: #e7e8eb;
  --border: #e2e4e8;
  --border-strong: #858a94;
  --text: #17181c;
  --muted: #5d616b;
  --accent: #0b5563;
  --accent-hover: #083f4a;
  --accent-soft: #e2f0f1;
  --accent-text: #0b5563;
  --accent-line: #0b5563;
  --on-accent: #ffffff;
  --focus: #0b5563;
  --nav-mark: #d16a00;
  --pick-bar: #0b5563;
  --danger: #b42318;
  --danger-soft: #fdeceb;
  --danger-text: #b42318;
  --on-danger: #ffffff;
  --warning: #b54708;
  --warning-soft: #fef0c7;
  --warning-text: #b54708;
  --success: #067647;
  --success-soft: #e3f8ec;
  --success-text: #067647;
  --toast-bg: #17181c;
  --toast-text: #ffffff;
  --backdrop: rgb(15 17 22 / 0.4);
  --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235d616b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");

  --font: "Inter", "Inter fallback", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Page widths: wide for grids, narrow for forms, indexes, and reading,
     centred; the gutter grows with the screen. */
  --page-wide: 80rem;
  --page-narrow: 48rem;
  --gutter: var(--s4);

  --s1: 0.25rem;
  --s2: 0.5rem;
  --s3: 0.75rem;
  --s4: 1rem;
  --s5: 1.25rem;
  --s6: 1.5rem;
  --s8: 2rem;
  --s12: 3rem;

  --fs-xs: 0.75rem;
  --lh-xs: 1rem;
  --fs-sm: 0.875rem;
  --lh-sm: 1.25rem;
  --fs-md: 1rem;
  --lh-md: 1.5rem;
  --fs-lg: 1.125rem;
  --lh-lg: 1.75rem;
  --fs-xl: 1.5rem;
  --lh-xl: 2rem;

  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 12px;

  --h-sm: 2rem;
  --h-md: 2.5rem;

  --shadow-sm: 0 1px 2px rgb(15 17 22 / 0.08);
  --shadow-md: 0 2px 8px rgb(15 17 22 / 0.12), 0 1px 2px rgb(15 17 22 / 0.08);
  --shadow-lg: 0 16px 40px rgb(15 17 22 / 0.18), 0 2px 6px rgb(15 17 22 / 0.08);

  --z-sticky: 3;
  --z-tip: 5;

  --t: 140ms cubic-bezier(0.2, 0, 0, 1);
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1416;
    --surface: #161d20;
    --raised: #1f282b;
    --raised-hover: #283236;
    --border: #263034;
    --border-strong: #74858b;
    --text: #ededf0;
    --muted: #9fadb2;
    --accent: #0e6a6a;
    --accent-hover: #0b5a5a;
    --accent-soft: #12313a;
    --accent-text: #7fd3dc;
    --accent-line: #5cc2cd;
    --on-accent: #ffffff;
    --focus: #7fd3dc;
    --nav-mark: #f0901f;
    --pick-bar: #5cc2cd;
    --danger: #c4321f;
    --danger-soft: #3b1715;
    --danger-text: #ff8d80;
    --on-danger: #ffffff;
    --warning: #fdb022;
    --warning-soft: #3a2806;
    --warning-text: #fdb022;
    --success: #4fd18c;
    --success-soft: #0f2a1c;
    --success-text: #4fd18c;
    --toast-bg: #ededf0;
    --toast-text: #17181c;
    --backdrop: rgb(0 0 0 / 0.6);
    --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239fadb2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.4);
    --shadow-md: 0 2px 8px rgb(0 0 0 / 0.5), 0 0 0 1px var(--border);
    --shadow-lg: 0 16px 40px rgb(0 0 0 / 0.6), 0 0 0 1px var(--border);
  }
}
@media (min-width: 40rem) { :root { --gutter: var(--s6); } }
@media (min-width: 64rem) { :root { --gutter: var(--s8); } }
/* Touch: every control grows to a 44px target. */
@media (max-width: 40rem), (pointer: coarse) {
  :root {
    --h-sm: 2.75rem;
    --h-md: 2.75rem;
  }
}

/* ---------- Base ---------- */

* { box-sizing: border-box; }
body {
  margin: 0 auto;
  max-width: calc(var(--page-wide) + 2 * var(--gutter));
  padding: 0 var(--gutter);
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font: var(--fs-md)/var(--lh-md) var(--font);
  background: var(--bg);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}
h1 { margin: 0; font-size: var(--fs-xl); line-height: var(--lh-xl); font-weight: 700; letter-spacing: -0.01em; overflow-wrap: anywhere; }
h2 { margin: 0; }
p { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent-text); text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
::placeholder { color: var(--muted); opacity: 1; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.muted { color: var(--muted); }
.si { width: 1.125rem; height: 1.125rem; flex: none; }
.ic { width: 1.25rem; height: 1.25rem; flex: none; object-fit: contain; display: inline-block; }
.ic.glyph { background: currentColor; mask: var(--mask) center / contain no-repeat; }
main { flex: 1; padding-block: var(--s6) var(--s8); }
.narrow { max-width: var(--page-narrow); margin-inline: auto; }
kbd {
  padding: 0 0.3em;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--raised);
  color: var(--text);
  font: var(--fs-xs)/1.4 ui-monospace, monospace;
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  *, ::before, ::after, ::backdrop { transition: none !important; animation: none !important; }
}

/* ---------- Components ---------- */

/* Button: .btn is secondary; .primary, .ghost, and .danger change its
   colours, .sm its size, and .icon-btn makes it a square for a lone icon,
   which then needs an aria-label. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  height: var(--h-md);
  min-width: var(--h-md);
  padding: 0 var(--s4);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background-color var(--t), border-color var(--t), color var(--t), box-shadow var(--t), scale var(--t);
}
.btn:hover { background: var(--raised); text-decoration: none; }
.btn:active { background: var(--raised-hover); scale: 0.98; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; scale: none; }
.btn .si { width: 1.125rem; height: 1.125rem; }
.btn.primary { border-color: var(--accent); background: var(--accent); color: var(--on-accent); font-weight: 600; }
.btn.primary:hover { border-color: var(--accent-hover); background: var(--accent-hover); }
.btn.ghost { border-color: transparent; background: transparent; }
.btn.ghost:hover { background: var(--raised); }
.btn.ghost:active { background: var(--raised-hover); }
.btn.danger { color: var(--danger-text); }
.btn.danger:hover { border-color: var(--danger-text); background: var(--danger-soft); }
.btn.ghost.danger:hover { border-color: transparent; }
.btn.primary.danger { border-color: var(--danger); background: var(--danger); color: var(--on-danger); }
.btn.primary.danger:hover { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 85%, black); }
.btn.sm { height: var(--h-sm); min-width: var(--h-sm); padding: 0 var(--s3); }
.btn.icon-btn { width: var(--h-md); padding: 0; }
.btn.sm.icon-btn { width: var(--h-sm); }
/* Busy: the label stays for screen readers and keeps the width; a spinner
   takes its place. The button stays clickable, as before. */
.btn[aria-busy="true"], .qa.pending .qa-undo { position: relative; color: transparent; }
:is(.btn[aria-busy="true"], .qa.pending .qa-undo)::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--on-accent);
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
:is(.btn:not(.primary)[aria-busy="true"], .qa.pending .qa-undo)::after { border-color: var(--text); border-right-color: transparent; }
@keyframes spin { to { rotate: 1turn; } }

/* Fields: every text input, select, and textarea looks the same; a select
   keeps the native control under a custom chevron. */
input:not([type="checkbox"], [type="radio"], [type="hidden"]), select, textarea {
  min-width: 0;
  height: var(--h-md);
  padding: 0 var(--s3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text);
  transition: border-color var(--t), box-shadow var(--t);
}
:is(input:not([type="checkbox"], [type="radio"], [type="hidden"]), select, textarea):hover { border-color: var(--text); }
:is(input:not([type="checkbox"], [type="radio"], [type="hidden"]), select, textarea):focus-visible {
  outline: none;
  border-color: var(--focus);
  box-shadow: 0 0 0 1px var(--focus);
}
select {
  appearance: none;
  padding-right: var(--s8);
  background: var(--surface) var(--chevron) right var(--s2) center / 1.125rem no-repeat;
  cursor: pointer;
}
textarea { height: auto; padding: var(--s2) var(--s3); resize: vertical; }
/* A field is a label above its control. */
.field { display: grid; gap: var(--s1); min-width: 0; }
.field > span:first-child, fieldset.group > legend {
  padding: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  font-weight: 500;
  color: var(--text);
}
fieldset.group { min-width: 0; margin: 0; padding: 0; border: 0; }
fieldset.group > legend { margin-bottom: var(--s1); }
.hint { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--muted); }

/* The real input stays in place, invisible, so it keeps focus and clicks. */
:is(.chip, .seg > label, .itog) input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: inherit; }

/* Chip: a checkbox or radio drawn as a pill, for filters and toggles. */
.chips { display: flex; flex-wrap: wrap; gap: var(--s2); }
.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  height: var(--h-sm);
  min-width: var(--h-sm);
  padding: 0 var(--s3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: var(--fs-sm);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background-color var(--t), border-color var(--t), color var(--t);
}
.chip:hover { background: var(--raised); }
.chip:has(.ic) { padding-left: var(--s2); }
.chip .ic { width: 1.125rem; height: 1.125rem; }
.chip:has(:checked) { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-text); box-shadow: inset 0 0 0 1px var(--accent-line); }
:is(.chip, .seg > label, .itog):has(:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
:is(.chip, .seg > label):has(:disabled) { opacity: 0.45; cursor: not-allowed; }

/* Radio chip: one choice in a list of long ones, with its dot. */
.chip.radio { justify-content: flex-start; }
.chip.radio::before {
  content: "";
  flex: none;
  width: 1rem;
  height: 1rem;
  border: 1.5px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  transition: border-width var(--t), border-color var(--t);
}
.chip.radio:has(:checked)::before { border: 5px solid var(--accent-line); }

/* Segmented control: one choice of a few, as a joined row. */
.seg {
  display: inline-flex;
  padding: 2px;
  gap: 2px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--raised);
}
.seg > :is(label, button) {
  position: relative;
  flex: 1 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: calc(var(--h-md) - 6px);
  min-width: 0;
  padding: 0 var(--s3);
  border-radius: calc(var(--r-md) - 2px);
  font-size: var(--fs-sm);
  line-height: 1.1;
  text-align: center;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  transition: background-color var(--t), color var(--t), box-shadow var(--t);
}
.seg > button { gap: 0.375rem; border: 0; background: none; font-family: inherit; }
.seg > :is(label, button):hover { color: var(--text); }
/* A segment's hit area takes in the track's padding, so it is as tall as
   the control. */
.seg > :is(label, button)::after { content: ""; position: absolute; inset: -3px -1px; }
.seg > :is(label:has(:checked), button[aria-pressed="true"]) { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--accent-line); }
.seg.sm > :is(label, button) { height: calc(var(--h-sm) - 6px); padding: 0 var(--s3); }
.seg .si { width: 1rem; height: 1rem; }

/* Stepper: − value +, for a quantity. */
.stepper {
  display: inline-flex;
  align-items: stretch;
  height: var(--h-md);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
  transition: border-color var(--t);
}
.stepper:hover { border-color: var(--text); }
.stepper:focus-within { border-color: var(--focus); box-shadow: 0 0 0 1px var(--focus); }
.stepper button {
  flex: none;
  width: var(--h-md);
  padding: 0;
  border: 0;
  background: transparent;
  font-size: var(--fs-md);
  cursor: pointer;
  transition: background-color var(--t);
}
.stepper button:hover { background: var(--raised); }
.stepper button:active { background: var(--raised-hover); }
.stepper button:focus-visible { outline-offset: -2px; }
.stepper input,
.stepper input:hover,
.stepper input:focus-visible {
  flex: 1 1 3rem;
  width: 3rem;
  height: auto;
  padding: 0;
  border: 0;
  border-inline: 1px solid var(--border);
  border-radius: 0;
  box-shadow: none;
  background: transparent;
  text-align: center;
  font-variant-numeric: tabular-nums;
  appearance: textfield;
}
.stepper input::-webkit-inner-spin-button, .stepper input::-webkit-outer-spin-button { appearance: none; margin: 0; }
.stepper.sm { height: var(--h-sm); }
.stepper.sm button { width: var(--h-sm); }
.stepper.sm input { font-size: var(--fs-sm); }

/* Badge: a small fact under a tile; a ban is a warning. */
.badges { list-style: none; margin: var(--s1) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--s1); }
.badges li {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0 0.375rem;
  height: 1.25rem;
  border-radius: var(--r-sm);
  background: var(--raised);
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1;
  white-space: nowrap;
}
.badges .si { width: 0.8125rem; height: 0.8125rem; }
.badges .ban { padding: 0; background: var(--warning-soft); color: var(--warning-text); font-weight: 600; box-shadow: inset 0 0 0 1px var(--warning); }
.badges .ban a { position: relative; display: inline-flex; align-items: center; gap: 0.25rem; height: 100%; padding: 0 0.375rem; border-radius: inherit; color: inherit; text-decoration: none; }
/* The badge stays small; its link's hit area reaches 44px. */
.badges .ban a::after { content: ""; position: absolute; inset: -0.75rem -0.25rem; }
/* Tag: marks the owner's public folder or list beside its totals. */
.tag {
  display: inline-flex;
  align-items: center;
  height: 1.25rem;
  margin-right: var(--s2);
  padding: 0 0.375rem;
  border-radius: var(--r-sm);
  background: var(--accent-soft);
  color: var(--accent-text);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1;
  vertical-align: 0.0625rem;
}

/* Removable chip: an active filter, which a click removes. */
.results-head { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s3); align-items: center; min-height: var(--h-sm); margin: var(--s5) 0 var(--s3); }
.active { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }
.active:empty { display: none; }
.achip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  height: var(--h-sm);
  padding: 0 var(--s1) 0 var(--s2);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-md);
  background: var(--accent-soft);
  color: var(--text);
  font-size: var(--fs-sm);
  line-height: 1;
  text-decoration: none;
  transition: background-color var(--t);
}
.achip:hover { background: var(--raised); text-decoration: none; }
.achip .ic { width: 1rem; height: 1rem; }
.achip .si { width: 1.25rem; height: 1.25rem; padding: 0.125rem; border-radius: var(--r-sm); color: var(--muted); }
.achip:hover .si { color: var(--text); }
.achip .muted { font-size: var(--fs-xs); }

/* Popover: a dialog, or a bottom sheet on a phone, with a head, a body, and
   a foot whose primary action sits on the right. Opening fades and rises. */
.pop {
  width: min(28rem, calc(100vw - 2rem));
  max-height: min(40rem, calc(100dvh - 4rem));
  margin: 8vh auto auto;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  flex-direction: column;
  opacity: 0;
  translate: 0 0.5rem;
  transition: opacity var(--t), translate var(--t), display var(--t) allow-discrete, overlay var(--t) allow-discrete;
}
/* Only while open: an author display rule would beat the UA's hiding of a
   closed popover. The rest of the layout stays on .pop, so it holds while the
   popover fades out. */
.pop:popover-open { display: flex; opacity: 1; translate: 0 0; }
@starting-style { .pop:popover-open { opacity: 0; translate: 0 0.5rem; } }
.pop::backdrop { background: transparent; transition: background-color var(--t), display var(--t) allow-discrete, overlay var(--t) allow-discrete; }
.pop:popover-open::backdrop { background: var(--backdrop); }
@starting-style { .pop:popover-open::backdrop { background: transparent; } }
.pop-form { display: flex; flex-direction: column; min-height: 0; margin: 0; }
.pop-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s2) var(--s3); padding: var(--s4) var(--s5) 0; }
.pop-title { min-width: 0; font-size: var(--fs-md); line-height: var(--lh-md); font-weight: 400; overflow-wrap: anywhere; }
.pop-title strong { font-weight: 650; font-variant-numeric: tabular-nums; }
.pop-sub { flex-basis: 100%; margin-top: calc(-1 * var(--s2)); font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--muted); }
.pop-head .seg { flex: none; }
.pop-head .seg > label { padding: 0 var(--s4); }
.pop-body { display: grid; gap: var(--s4); padding: var(--s4) var(--s5) var(--s5); overflow-y: auto; }
.pop-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--s2);
  padding: var(--s3) var(--s5) calc(var(--s3) + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border);
}
.pop-foot .btn { min-width: 6rem; }
.pop-body > p { margin: 0; }
.pop-empty { display: grid; gap: var(--s3); justify-items: start; padding: var(--s4) var(--s5) var(--s5); }

/* Toast: a short message above everything, an open popover included. */
.toast {
  inset: auto 0 calc(var(--s5) + env(safe-area-inset-bottom)) 0;
  width: fit-content;
  max-width: calc(100vw - 2rem);
  margin: 0 auto;
  padding: var(--s3) var(--s4);
  border: 0;
  border-radius: var(--r-md);
  background: var(--toast-bg);
  color: var(--toast-text);
  box-shadow: var(--shadow-lg);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  opacity: 0;
  translate: 0 0.5rem;
  transition: opacity var(--t), translate var(--t), display var(--t) allow-discrete, overlay var(--t) allow-discrete;
}
.toast:popover-open { opacity: 1; translate: 0 0; }
@starting-style { .toast:popover-open { opacity: 0; translate: 0 0.5rem; } }
.toast:has(.err) { background: var(--danger); color: var(--on-danger); }
.toast-msg { margin: 0; }
.toast a { color: inherit; font-weight: 600; margin-left: var(--s2); }
/* A toast's action, such as Retry after a failed request. */
.toast-action {
  position: relative;
  margin-left: var(--s3);
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font-weight: 650;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  cursor: pointer;
}
.toast-action::after { content: ""; position: absolute; inset: -0.75rem -0.5rem; }

/* Callout: a problem the owner can act on. */
.problem {
  display: flex;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  border-radius: var(--r-md);
  background: var(--danger-soft);
  color: var(--danger-text);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
}
.problem .si { margin-top: 0.0625rem; }

/* Empty state: what is missing and what to do about it. */
.empty {
  display: grid;
  justify-items: start;
  gap: var(--s3);
  padding: var(--s6);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-lg);
  color: var(--muted);
}
.empty p { max-width: 36rem; }
.empty strong { color: var(--text); font-weight: 600; }

/* Page head: the title, a line about it, and its actions on the right.
   Beside an action, the title is at least as tall as the action and centred
   on it, so one line lines up with it and a long title wraps down from it. */
.page-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--s1) var(--s4);
  margin-bottom: var(--s6);
}
.page-head > p { grid-column: 1 / -1; font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--muted); font-variant-numeric: tabular-nums; text-wrap: pretty; }
.page-head > .btn { grid-column: 2; grid-row: 1; }
.page-head:has(> .btn, > .download) > h1 { display: flex; align-items: center; min-height: var(--h-md); }
.page-head:has(> .download) > h1 { min-height: var(--h-sm); }
/* Owner bar: the Public / Private switch and the link to copy, which wrap,
   and Delete at the end of their first line. */
.page-head > .owner-bar { grid-column: 1 / -1; display: flex; align-items: flex-start; gap: var(--s3); margin-top: var(--s2); }
.owner-bar > .share { flex: 1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); }
.share-note { font-size: var(--fs-sm); line-height: var(--lh-sm); }
.page-head > .shared-by { font-variant-numeric: normal; }

/* Status page: a 404 or a 500, centred, with the way back first. */
.status-page { display: grid; justify-items: center; gap: var(--s3); margin-inline: auto; padding-block: var(--s12); text-align: center; }
.status-code { color: var(--muted); font-size: var(--fs-sm); line-height: var(--lh-sm); font-weight: 600; font-variant-numeric: tabular-nums; }
.status-detail { max-width: 32rem; color: var(--muted); text-wrap: pretty; }
.status-links { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2); margin-top: var(--s3); }

/* Section head: a heading over a group, with its count. */
.section-head {
  margin: var(--s8) 0 var(--s3);
  padding-bottom: var(--s2);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

/* Index row: a folder or a list with its totals and actions. */
.index { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.index-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--s1) var(--s4);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--border);
}
.index:has(> .empty) { border-top: 0; }
.index-row .totals { font-size: var(--fs-sm); line-height: var(--lh-sm); font-variant-numeric: tabular-nums; text-wrap: pretty; }
.index-row .totals > span { white-space: nowrap; }
.index-row .actions { display: flex; align-items: center; gap: var(--s2); }
/* A row's name opens it. The pencil swaps the name for a field, whose
   text lines up with the name's. The name's padding makes one line as tall
   as a control, and keeps the same space above its totals however many
   lines it wraps to. */
.index-name { justify-self: start; display: inline-flex; align-items: center; min-width: min(var(--h-md), 100%); padding-block: calc((var(--h-md) - var(--lh-md)) / 2); color: var(--text); font-weight: 600; text-decoration: none; overflow-wrap: anywhere; }
.index-name:hover { color: var(--accent-text); text-decoration: underline; }
.rename { display: none; min-width: 0; margin: 0; }
.editing .rename { display: flex; }
.editing .index-name { display: none; }
.rename input { field-sizing: content; min-width: 12rem; max-width: 100%; margin-left: calc(-1 * var(--s3) - 1px); font-weight: 600; }
.new-name { display: flex; gap: var(--s2); margin-top: var(--s5); }
.new-name input { flex: 1 1 12rem; }

/* Table: rows of a preview. */
.table { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: var(--fs-sm); line-height: var(--lh-sm); }
.table td { padding: var(--s2) var(--s3) var(--s2) 0; border-bottom: 1px solid var(--border); vertical-align: baseline; }
.table tr:last-child td { border-bottom: 0; }
.table td.qty { width: 2.5rem; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.table td.code { width: 8rem; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.table .why { width: 12rem; font-size: var(--fs-xs); }
.table td.what { width: 8rem; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ---------- Header and footer ---------- */

/* Skip link: hidden until a keyboard reaches it first. */
.skip { position: absolute; top: var(--s2); left: var(--s2); z-index: var(--z-tip); padding: var(--s2) var(--s3); border-radius: var(--r-md); background: var(--surface); box-shadow: var(--shadow-md); translate: 0 -200%; }
.skip:focus-visible { translate: 0 0; }
main:focus { outline: none; }

.top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0 var(--s4);
  min-height: 3.5rem;
  border-bottom: 1px solid var(--border);
}
/* Wordmark: the mark, then the name, "shelf" set lighter. */
.brand { display: inline-flex; align-items: center; gap: 0.625rem; min-height: 2.75rem; color: var(--text); font-size: 1.0625rem; font-weight: 700; letter-spacing: -0.02em; text-decoration: none; white-space: nowrap; }
.brand:hover { text-decoration: none; }
.brand-mark { flex: none; width: 1.75rem; height: 1.75rem; }
.brand-sub { font-weight: 450; color: var(--muted); }
.top nav { display: flex; align-items: stretch; align-self: stretch; gap: var(--s1); margin-left: auto; font-size: var(--fs-sm); }
.nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0 var(--s3);
  border: 0;
  background: none;
  color: var(--muted);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--t);
}
.nav-link:hover { color: var(--text); text-decoration: none; }
.nav-link[aria-current="page"] { color: var(--text); font-weight: 600; }
.nav-link[aria-current="page"]::after { content: ""; position: absolute; inset: auto var(--s3) -1px; height: 2px; border-radius: 2px; background: var(--nav-mark); }
.nav-link:focus-visible { outline-offset: -2px; border-radius: var(--r-sm); }
/* After the links: Log in, or the signed-in user's avatar, which opens the
   account menu. */
.nav-login { margin-left: var(--s2); }
.account-button {
  anchor-name: --account;
  display: inline-flex;
  align-items: center;
  gap: 0.125rem;
  height: 2.75rem;
  margin: 0 calc(-1 * var(--s1)) 0 var(--s2);
  padding: 0 var(--s1);
  border: 0;
  border-radius: var(--r-md);
  background: none;
  color: var(--muted);
  cursor: pointer;
  transition: background-color var(--t), color var(--t);
}
.account-button:hover, .account-button[aria-expanded="true"] { background: var(--raised); color: var(--text); }
.account-button .chev { width: 1rem; height: 1rem; transition: rotate var(--t); }
.account-button[aria-expanded="true"] .chev { rotate: 180deg; }
.avatar {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-text);
  font-size: var(--fs-sm);
  font-weight: 650;
  object-fit: cover;
}
.avatar.lg { width: 2.5rem; height: 2.5rem; }
.avatar.xl { width: 3.5rem; height: 3.5rem; font-size: var(--fs-lg); }

/* Menu: a short list of links and actions, dropped from its button. */
.menu {
  inset: 3.75rem var(--s4) auto auto;
  width: 16rem;
  margin: 0;
  padding: var(--s1);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  translate: 0 -0.25rem;
  transition: opacity var(--t), translate var(--t), display var(--t) allow-discrete, overlay var(--t) allow-discrete;
}
.menu:popover-open { opacity: 1; translate: 0 0; }
@starting-style { .menu:popover-open { opacity: 0; translate: 0 -0.25rem; } }
@supports (top: anchor(bottom)) {
  .menu { position-anchor: --account; top: anchor(bottom); right: anchor(right); margin-top: var(--s1); }
}
.menu form { margin: 0; }
.menu-head { display: flex; align-items: center; gap: var(--s3); padding: var(--s3); margin-bottom: var(--s1); border-bottom: 1px solid var(--border); }
.menu-head p { min-width: 0; display: grid; font-size: var(--fs-sm); line-height: var(--lh-sm); overflow-wrap: anywhere; }
.menu-head strong { font-weight: 600; }
.menu-head .muted { font-size: var(--fs-xs); line-height: var(--lh-xs); }
.menu-item {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--h-md);
  padding: 0 var(--s3);
  border: 0;
  border-radius: var(--r-md);
  background: none;
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--t);
}
.menu-item:hover { background: var(--raised); text-decoration: none; }
.menu-item:focus-visible { outline-offset: -2px; }
/* Download: a folder's or a list's files, in a menu dropped from its button
   in the owner bar, or beside the title for anyone else. Without anchor
   positioning the menu stays centred, as the UA places it. */
.download { flex: none; }
.page-head > .download { grid-column: 2; grid-row: 1; }
.download-button { anchor-name: --download; }
.download-button .chev { width: 1rem; height: 1rem; transition: rotate var(--t); }
.download-button[aria-expanded="true"] .chev { rotate: 180deg; }
.menu.download-menu { inset: 0; height: fit-content; margin: auto; }
@supports (top: anchor(bottom)) {
  .menu.download-menu { inset: auto; position-anchor: --download; top: anchor(bottom); right: anchor(right); margin: var(--s1) 0 0; position-try-fallbacks: flip-block; }
}
.download-menu .menu-item { flex-direction: column; align-items: flex-start; justify-content: center; padding-block: var(--s2); }
.download-menu .menu-item strong { font-weight: 600; }
.download-menu .menu-item .muted { font-size: var(--fs-xs); line-height: var(--lh-xs); font-weight: 400; }
/* The footer's surface runs the full window width: shadows spread past the
   body's max-width, and clip-path keeps them to the footer's own height. */
.legal {
  --legal-bg: var(--raised);
  display: grid;
  gap: var(--s1);
  padding: var(--s2) 0 calc(var(--s3) + env(safe-area-inset-bottom));
  background: var(--legal-bg);
  box-shadow: 0 0 0 100vmax var(--legal-bg), 0 -1px 0 100vmax var(--border);
  clip-path: inset(-1px -100vmax 0);
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: var(--lh-xs);
}
.legal-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 var(--s4); }
.legal-links { display: flex; flex-wrap: wrap; align-items: center; list-style: none; margin: 0 calc(-1 * var(--s2)); padding: 0; }
.legal-links li { display: flex; align-items: center; }
.legal-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-sm);
  padding: 0 var(--s2);
  border-radius: var(--r-md);
  color: var(--muted);
  font-size: 0.8125rem;
  font-weight: 500;
  text-decoration: none;
  transition: color var(--t), background-color var(--t);
}
.legal-link:hover { background: var(--raised-hover); color: var(--text); text-decoration: none; }
.legal-status { margin: 0; font-size: 0.8125rem; }
.legal-note { max-width: 42rem; margin: 0; padding-block: var(--s1); text-wrap: pretty; }
@media (prefers-color-scheme: dark) {
  .legal { --legal-bg: color-mix(in srgb, var(--bg) 70%, #000); }
  .legal-link:hover { background: var(--raised); }
}
@media (max-width: 40rem) {
  .legal-status { padding-block: var(--s2); }
}
@media (max-width: 40rem) {
  .top { padding-top: var(--s1); }
  .top nav { order: 1; flex-basis: 100%; margin-inline: calc(-1 * var(--s2)); overflow-x: auto; scrollbar-width: none; }
  :is(.account-button, .nav-login) { margin-left: auto; }
  .nav-link { padding: 0 var(--s2); }
  .nav-link[aria-current="page"]::after { inset-inline: var(--s2); }
}

/* ---------- Search ---------- */

.toolbar { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }
.searchbox { position: relative; flex: 1 1 18rem; min-width: 0; display: flex; align-items: center; }
.searchbox > .si { position: absolute; left: var(--s3); color: var(--muted); pointer-events: none; }
.searchbox input { width: 100%; padding-inline: 2.5rem; }
.searching {
  position: absolute;
  right: 2.75rem;
  padding-left: var(--s1);
  background: var(--surface);
  color: var(--muted);
  font-size: var(--fs-xs);
}
/* The clear button needs Datastar, so it replaces the browser's own only on
   a form Datastar has marked .js. */
/* An in-field icon button: a small circle inset from the field's edge, so
   its tint and focus ring stay inside the field's border. Its hit area
   reaches 44px past the circle. */
.in-field.btn {
  position: absolute;
  right: 0.375rem;
  width: 2rem;
  height: 2rem;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  color: var(--muted);
}
.in-field.btn:hover { background: var(--raised-hover); color: var(--text); }
.in-field.btn:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--focus); color: var(--text); }
.in-field.btn::after { content: ""; position: absolute; inset: -0.375rem; border-radius: 50%; }
.in-field .si { width: 1rem; height: 1rem; }
.clear-q { display: none; }
.js .searchbox input::-webkit-search-cancel-button { display: none; }
.js .searchbox input:not(:placeholder-shown) ~ .clear-q { display: inline-flex; }

.domains { display: flex; gap: var(--s1); border: 0; margin: 0; padding: 0; min-width: 0; }
.itog {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--h-md);
  height: var(--h-md);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  cursor: pointer;
  transition: background-color var(--t), border-color var(--t);
}
.itog:hover { background: var(--raised); }
.itog .ic { width: 1.5rem; height: 1.5rem; pointer-events: none; transition: filter var(--t), opacity var(--t); }
.itog:has(:checked) {
  border-color: var(--c);
  box-shadow: inset 0 0 0 1px var(--c);
  background: color-mix(in srgb, var(--c) 16%, var(--surface));
}
.domains:has(:checked) .itog:not(:has(:checked)) .ic { filter: grayscale(1); opacity: 0.45; }
.itog::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  translate: -50% 0;
  padding: 0.125rem var(--s2);
  border-radius: var(--r-sm);
  background: var(--toast-bg);
  color: var(--toast-text);
  font-size: var(--fs-xs);
  line-height: var(--lh-xs);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--t);
  z-index: var(--z-tip);
}
.itog:hover::after, .itog:has(:focus-visible)::after { opacity: 1; }
/* Touch has no hover: a tapped toggle names itself while it has focus. */
@media (hover: none) { .itog:has(:focus)::after { opacity: 1; } }

/* The sort's icon sits in the field; a sort other than the default tints it
   as an active filter tints the Filters button. */
.sort-field { position: relative; display: flex; align-items: center; }
.sort-field > .si { position: absolute; left: var(--s3); color: var(--muted); pointer-events: none; }
.sort-field select { padding-left: 2.375rem; font-size: var(--fs-sm); font-weight: 500; }
.sort-field:has(option:checked:not([value=""])) select { border-color: var(--accent-line); background-color: var(--accent-soft); color: var(--accent-text); }
.sort-field:has(option:checked:not([value=""])) > .si { color: var(--accent-text); }

.filters-btn { anchor-name: --filters; position: relative; padding: 0 var(--s3); }
.filters-btn:has(.badge) { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-text); }
.filters-btn .badge {
  position: absolute;
  top: -0.5rem;
  right: -0.5rem;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.3125rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--fs-xs);
  font-weight: 650;
  line-height: 1.25rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 2px var(--bg);
}
.filters-btn .chev { width: 1rem; height: 1rem; margin-left: calc(-1 * var(--s1)); color: var(--muted); }

.panel { width: min(46rem, calc(100vw - 2rem)); max-height: min(36rem, 80vh); }
/* Without anchor positioning the panel stays centred, as the UA places it. */
@supports (top: anchor(bottom)) {
  @media (min-width: 40.01rem) {
    .panel { position-anchor: --filters; inset: auto; top: anchor(bottom); right: anchor(right); margin: var(--s2) 0 0; translate: 0 -0.25rem; }
    .panel:popover-open { translate: 0 0; }
    @starting-style { .panel:popover-open { translate: 0 -0.25rem; } }
    .panel:popover-open::backdrop { background: transparent; }
  }
}
.panel-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s4) var(--s6);
  padding: var(--s3) var(--s5) var(--s5);
  overflow-y: auto;
}
.panel-grid .set { grid-column: 1 / -1; }
.type .ic.glyph { color: var(--text); }
.panel .pop-foot { justify-content: space-between; }

/* While a search runs, the results it will replace dim, after a beat so a
   quick answer never flickers. */
#results { transition: opacity 150ms; }
#search[data-fetching] ~ #results { opacity: 0.55; transition-delay: 150ms; }
.count { margin: 0; color: var(--muted); font-size: var(--fs-sm); line-height: var(--lh-sm); font-variant-numeric: tabular-nums; }
.grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  /* The tiles' seven rows repeat down the grid. The badge row keeps a
     badge's height when no tile in the row has one, so every row of tiles
     is spaced alike. */
  grid-auto-rows: auto auto auto minmax(1.5rem, auto) auto auto auto;
  column-gap: var(--s3);
}
.more { display: flex; margin: var(--s8) auto 0; }
#results > .empty { margin-top: var(--s2); }

/* Tile: a card's art, its code and name, and what the collection holds. */
/* Each tile spans seven rows of its grid and shares them as a subgrid, so
   a row of tiles lines up part by part whatever badges or owned line each
   has. A part's row is fixed, and an absent part leaves its row empty. */
.tile { display: grid; grid-row: span 7; grid-template-rows: subgrid; align-content: start; min-width: 0; padding-bottom: var(--s4); }
.tile > * { align-self: start; }
.tile > .art { grid-row: 1; }
.tile > .code { grid-row: 2; }
.tile > .name { grid-row: 3; }
.tile > .badges { grid-row: 4; }
.tile > :is(.own, .need) { grid-row: 5; }
.tile > :is(.held, .hold) { grid-row: 6; }
.tile > .kind { grid-row: 7; }
/* Art: the card's picture, which fades in over a card back: a frame and a
   soft centre, in the surface's own tints. A battlefield lies landscape at
   the top of its row's art cell, so the rows below still line up. */
.art {
  position: relative;
  align-self: start;
  border-radius: var(--r-md);
  background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 10%, var(--raised)), var(--raised)) center / 70% 60% no-repeat, var(--raised);
  box-shadow: inset 0 0 0 0.375rem var(--raised), inset 0 0 0 calc(0.375rem + 1px) var(--border);
}
.art:has(img.shown) { background: none; box-shadow: none; }
.art img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 744 / 1039;
  object-fit: contain;
  border-radius: var(--r-md);
  opacity: 0;
  transition: opacity 240ms ease-out, translate var(--t), box-shadow var(--t);
}
/* The art opens the card, as the name does: it lifts under a pointer. */
.art-link { display: block; border-radius: var(--r-md); cursor: pointer; }
@media (hover: hover) and (pointer: fine) {
  .art-link:hover img.shown { translate: 0 -3px; box-shadow: var(--shadow-md); }
}
.art img.shown { opacity: 1; }
@media (scripting: none) { .art img { opacity: 1; } }
.landscape .art img { aspect-ratio: 1039 / 744; }
/* A placeholder image's note: an icon in the card's bottom corner, over
   the fine print, which names itself under a pointer. */
.note {
  position: absolute;
  left: 0.375rem;
  bottom: 0.375rem;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: rgb(17 18 20 / 0.78);
  color: #fff;
  box-shadow: 0 0 0 1px rgb(255 255 255 / 0.22);
}
.note .si { width: 1rem; height: 1rem; }
/* A signed printing's borrowed picture lacks the signature: the note says
   Signed instead. */
.note.signed {
  width: auto;
  grid-auto-flow: column;
  gap: 0.25rem;
  padding: 0 0.5rem 0 0.375rem;
  border-radius: 999px;
  font-size: var(--fs-xs);
  font-weight: 600;
}
.note.signed .si { width: 0.875rem; height: 0.875rem; }
.card-art { position: relative; }
.card-art > .note { left: var(--s2); bottom: var(--s2); }
.card-art > .note::after { content: none; }
.note::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  padding: 0.125rem var(--s2);
  border-radius: var(--r-sm);
  background: var(--toast-bg);
  color: var(--toast-text);
  font-size: var(--fs-xs);
  line-height: var(--lh-xs);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--t);
  z-index: var(--z-tip);
}
.note:hover::after { opacity: 1; }
.tile p { margin: var(--s1) 0 0; font-size: var(--fs-sm); line-height: var(--lh-sm); }
/* Proportional figures: Inter's tabular ones widen a code's hyphen. */
.tile .code { display: flex; align-items: center; gap: 0.375rem; margin-top: var(--s2); color: var(--muted); font-size: var(--fs-xs); line-height: var(--lh-xs); }
.tile .code .ic { width: 0.9375rem; height: 0.9375rem; }
.tile .doms { margin-left: auto; display: inline-flex; gap: 1px; }
.tile .doms .ic { width: 1rem; height: 1rem; }
.tile .name { margin-top: 0.125rem; font-weight: 550; overflow-wrap: anywhere; }
.tile .name a { color: inherit; text-decoration: none; }
.tile .name a:hover { text-decoration: underline; }
.tile .own { color: var(--accent-text); font-weight: 600; font-size: var(--fs-xs); line-height: var(--lh-xs); font-variant-numeric: tabular-nums; }
.tile .own:empty { display: none; }
/* A tile's add button sits on the card's bottom corner, over the fine
   print rather than the stats. With a mouse it shows on hover and focus;
   on touch it stays, its target reaching 44px. */
.add-btn.btn {
  position: absolute;
  right: 0.375rem;
  bottom: 0.375rem;
  width: 2rem;
  height: 2rem;
  min-width: 0;
  border: 0;
  border-radius: 50%;
  background: rgb(17 18 20 / 0.78);
  color: #fff;
  box-shadow: 0 0 0 1px rgb(255 255 255 / 0.22), var(--shadow-md);
  transition: opacity var(--t), scale var(--t), background-color var(--t);
}
.add-btn.btn:hover, .add-btn.btn:active { background: var(--accent); color: var(--on-accent); }
.add-btn.btn::after { content: ""; position: absolute; inset: -0.375rem; border-radius: 50%; }
.add-btn .si { width: 1.125rem; height: 1.125rem; }
@media (hover: hover) and (pointer: fine) {
  .add-btn.btn { opacity: 0; scale: 0.9; }
  .tile:hover .add-btn.btn, .add-btn.btn:focus-visible { opacity: 1; scale: 1; }
}

/* A folder tile's holdings: one line each, the quantity first. The owner's
   line is a button that opens the holding editor. */
/* The lines' text meets the tile's edge; only their hover reaches past it. */
.held { list-style: none; margin: var(--s1) calc(-1 * var(--s1)) 0; padding: 0; }
.held li + li { border-top: 1px solid var(--border); }
.hl {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  width: 100%;
  min-height: 1.75rem;
  padding: 0 var(--s1);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: var(--lh-xs);
  text-align: left;
}
:is(button, summary).hl { cursor: pointer; user-select: none; transition: background-color var(--t), color var(--t); }
:is(button, summary).hl:hover { background: var(--raised); color: var(--text); }
:is(button, summary).hl:active { background: var(--raised-hover); }
.hl-n { flex: none; min-width: 1.5rem; color: var(--text); font-size: var(--fs-sm); font-weight: 600; font-variant-numeric: tabular-nums; }
.hl-what { flex: 1; min-width: 0; display: flex; align-items: center; gap: 0.25rem; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.hl .foil { flex: none; width: 0.8125rem; height: 0.8125rem; color: var(--accent-text); }
.hl .chev { flex: none; width: 1rem; height: 1rem; rotate: -90deg; transition: rotate var(--t); }
.held-more summary { list-style: none; color: var(--accent-text); font-weight: 600; }
.held-more summary::-webkit-details-marker { display: none; }
.held-more summary > span { flex: 1; padding-left: calc(1.5rem + 0.375rem); }
.held-more summary .chev { rotate: 0deg; }
.held-more details[open] > summary .chev { rotate: 180deg; }
.held-more details:not([open]) .opened, .held-more details[open] .closed { display: none; }
.held-more .held { margin: 0; border-top: 1px solid var(--border); }

/* ---------- Card page and modal ---------- */

/* The card modal: a dialog over the page a card was opened from, or a
   full-height sheet on a phone. The page behind stays where it was. */
.card-modal {
  width: min(64rem, calc(100vw - 2rem));
  max-width: none;
  max-height: calc(100dvh - 4rem);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  overflow: auto;
  overscroll-behavior: contain;
  opacity: 0;
  translate: 0 0.5rem;
  transition: opacity var(--t), translate var(--t), display var(--t) allow-discrete, overlay var(--t) allow-discrete;
}
.card-modal[open] { opacity: 1; translate: 0 0; }
@starting-style { .card-modal[open] { opacity: 0; translate: 0 0.5rem; } }
.card-modal::backdrop { background: transparent; transition: background-color var(--t), display var(--t) allow-discrete, overlay var(--t) allow-discrete; }
.card-modal[open]::backdrop { background: var(--backdrop); }
@starting-style { .card-modal[open]::backdrop { background: transparent; } }
html:has(.card-modal[open]) { overflow: hidden; }
.card-close { position: sticky; top: var(--s3); z-index: 1; float: right; margin: var(--s3) var(--s3) 0 0; background: var(--surface); }
#card-modal-body { padding: var(--s6); transition: opacity 150ms; }
/* Loading: nothing yet, or the last card dimmed while the next comes. */
#card-modal-body:empty { min-height: min(32rem, 70dvh); background: radial-gradient(closest-side, var(--raised), transparent) center / 12rem 12rem no-repeat; }
#card-modal-body[aria-busy="true"] { opacity: 0.55; transition-delay: 150ms; }
.card-modal .problem { margin: var(--s8) var(--s6); }

.card-detail { display: grid; grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); gap: var(--s6) var(--s8); align-items: start; }
.card-detail.landscape { grid-template-columns: minmax(0, 28rem) minmax(0, 1fr); }
.card-img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 744 / 1039;
  object-fit: contain;
  border-radius: var(--r-lg);
  background: var(--raised);
}
.landscape .card-img { aspect-ratio: 1039 / 744; }
.card-img.shown { background: none; }
/* A token card's two pictures lie one behind the other, and turn over
   around their vertical axis; each keeps its own orientation, as a Baron
   Pit front is landscape and its Gold back portrait. The side turned away
   takes no room, so the toggle sits under the side shown. Without
   scripting they show side by side. */
.flip-faces { position: relative; display: grid; perspective: 1600px; }
.flip-faces > .card-img { align-self: start; backface-visibility: hidden; transition: transform 450ms ease-in-out; }
.flip-faces > .card-img:not(.wide) { aspect-ratio: 744 / 1039; max-height: min(34rem, 75dvh); }
.flip-faces > .card-img.wide { aspect-ratio: 1039 / 744; }
.flip-faces > .card-img + .card-img, .flipped .flip-faces > .card-img:first-child { position: absolute; top: 0; left: 0; }
.flip-faces > .card-img + .card-img { transform: rotateY(180deg); }
.flipped .flip-faces > .card-img:first-child { transform: rotateY(-180deg); }
.flipped .flip-faces > .card-img + .card-img { position: static; transform: rotateY(0); }
.flip-btn { margin-top: var(--s3); }
.flip-btn[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent-text); }
@media (scripting: none) {
  .flip-faces { grid-template-columns: 1fr 1fr; gap: var(--s2); }
  .flip-faces > .card-img, .flip-faces > .card-img + .card-img { position: static; transform: none; }
  .flip-btn { display: none; }
}
.card-face { margin-top: var(--s5); }
.card-face + .card-face { padding-top: var(--s4); border-top: 1px dashed var(--border); }
.card-face-side { color: var(--muted); font-size: var(--fs-xs); line-height: var(--lh-xs); font-variant-numeric: tabular-nums; text-transform: uppercase; letter-spacing: 0.04em; }
.card-face-name { margin: 0.125rem 0 0; font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: 650; }
.card-body > .card-note { margin-top: var(--s3); }
.card-note { display: flex; gap: var(--s2); margin-top: var(--s3); padding: var(--s2) var(--s3); border-radius: var(--r-md); background: var(--accent-soft); color: var(--text); font-size: var(--fs-sm); line-height: var(--lh-sm); }
.card-note .si { margin-top: 0.0625rem; color: var(--accent-text); }
.card-kicker { color: var(--muted); font-size: var(--fs-sm); line-height: var(--lh-sm); font-variant-numeric: tabular-nums; }
.card-name:focus { outline: none; }
.card-name { margin-top: var(--s1); font-size: var(--fs-xl); line-height: var(--lh-xl); font-weight: 700; letter-spacing: -0.01em; overflow-wrap: anywhere; }
.card-type { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s3); margin-top: var(--s2); color: var(--muted); font-size: var(--fs-sm); line-height: var(--lh-sm); }
.card-type > .ic { width: 1rem; height: 1rem; margin-right: calc(-1 * var(--s2)); color: var(--text); }
.card-domain { display: inline-flex; align-items: center; gap: 0.25rem; }
.card-domain .ic { width: 1.125rem; height: 1.125rem; }
.card-stats { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s2) var(--s6); margin: var(--s4) 0 0; padding: 0; font-size: var(--fs-sm); }
.card-stats strong { margin-left: var(--s1); font-size: var(--fs-lg); font-weight: 700; font-variant-numeric: tabular-nums; }
/* Rules text: the card's own words, readable at last, with its keywords
   set off and its symbols drawn inline at the text's size. */
.rules { margin-top: var(--s4); padding: var(--s4) var(--s5); border-radius: var(--r-lg); background: var(--raised); line-height: 1.65; text-wrap: pretty; }
.rules p + :is(p, ul), .rules ul + :is(p, ul) { margin-top: var(--s2); }
.rules ul { margin: 0; padding-left: var(--s5); }
.kw { display: inline-block; margin-inline: 0.1em; padding: 0.1em 0.5em; border-radius: var(--r-sm); background: var(--surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--border-strong) 45%, transparent); font-size: 0.9em; font-weight: 650; line-height: 1.35; white-space: nowrap; }
.kw-then { margin-inline: 0.15em; color: var(--muted); }
.rb-energy { display: inline-grid; place-items: center; min-width: 1.3em; height: 1.3em; padding: 0 0.2em; border-radius: 1em; background: var(--text); color: var(--bg); font-size: 0.8em; font-weight: 700; line-height: 1; vertical-align: 0.05em; font-variant-numeric: tabular-nums; }
.rb-sym { display: inline-block; width: 1.15em; height: 1.15em; vertical-align: -0.2em; object-fit: contain; }
.rb-sym.glyph { background: currentColor; mask: var(--mask) center / contain no-repeat; }
.card-facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); gap: var(--s3) var(--s6); margin: var(--s5) 0 0; font-size: var(--fs-sm); line-height: var(--lh-sm); }
.card-facts dt { color: var(--muted); font-size: var(--fs-xs); line-height: var(--lh-xs); }
.card-facts dd { margin: 0.125rem 0 0; overflow-wrap: anywhere; }
.card-facts .with-icon { display: flex; align-items: center; gap: 0.375rem; }
.card-facts .ic { width: 1rem; height: 1rem; }
.card-part { margin-top: var(--s6); padding-top: var(--s4); border-top: 1px solid var(--border); }
.card-part-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); margin-bottom: var(--s2); }
.card-section { margin: 0 0 var(--s2); font-size: var(--fs-md); line-height: var(--lh-md); font-weight: 650; font-variant-numeric: tabular-nums; }
.card-part-head .card-section { margin: 0; }
.card-bans { list-style: none; display: grid; gap: var(--s1); margin: 0; padding: 0; font-size: var(--fs-sm); line-height: var(--lh-sm); }
.card-bans li { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s3); }
.card-ban-format { min-width: 6rem; font-weight: 600; }
.card-banned { display: inline-flex; align-items: center; gap: 0.25rem; color: var(--warning-text); font-weight: 600; }
.card-banned a { color: inherit; }
.card-banned .si { width: 1rem; height: 1rem; }
.card-held { display: grid; gap: var(--s1); font-size: var(--fs-sm); line-height: var(--lh-sm); }
.card-held .own { color: var(--accent-text); font-weight: 600; font-variant-numeric: tabular-nums; }
.card-held .held { margin-top: 0; }
a.hl { color: var(--muted); text-decoration: none; transition: background-color var(--t), color var(--t); }
a.hl:hover { background: var(--raised); color: var(--text); }
.hl-where { flex: none; max-width: 50%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); font-weight: 500; }
.printings { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr)); gap: var(--s2); margin: 0; padding: 0; }
.printing { display: grid; align-content: start; gap: 0.125rem; height: 100%; padding: var(--s1); border-radius: var(--r-md); color: var(--text); font-size: var(--fs-xs); line-height: var(--lh-xs); text-decoration: none; transition: background-color var(--t); }
.printing:hover { background: var(--raised); text-decoration: none; }
.printing[aria-current="page"] { background: var(--accent-soft); box-shadow: inset 0 0 0 2px var(--accent-line); }
.printing img { width: 100%; height: auto; aspect-ratio: 744 / 1039; margin-bottom: var(--s1); object-fit: contain; border-radius: var(--r-sm); background: var(--raised); }
.printing.landscape img { aspect-ratio: 1039 / 744; }
/* A code breaks between its parts, never inside one. */
.printing-code { display: flex; flex-wrap: wrap; column-gap: 0.3em; font-weight: 600; font-variant-numeric: tabular-nums; }
.printing-code > span { white-space: nowrap; }
.printing-what { color: var(--muted); }
@media (max-width: 48rem) {
  .card-detail { grid-template-columns: minmax(0, 1fr); }
  .card-figure { width: min(100%, 20rem); margin-inline: auto; }
  .card-detail.landscape .card-figure { width: 100%; }
}

/* ---------- Add popover and holding editor ---------- */

.pop-body .stepper { width: 10rem; }
/* Only the move section scrolls when a short phone caps the sheet. */
.pop-qty { flex: none; }
.pop-qty + .pop-form { border-top: 1px solid var(--border); }
.qty-row { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); }
.pop-section { font-size: var(--fs-sm); line-height: var(--lh-sm); font-weight: 600; }
/* Side by side only where a language name such as Chinese (Simplified) fits. */
.pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: var(--s4) var(--s3); }
.pop .finish .chips { align-items: center; }
/* A full name can be long, so each choice takes its own line. */
.needs .chips { flex-direction: column; align-items: stretch; }
.needs .chip { justify-content: flex-start; height: auto; min-height: var(--h-md); padding-block: var(--s2); white-space: normal; line-height: var(--lh-sm); text-align: left; }

/* ---------- List page ---------- */

.list-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); margin-bottom: var(--s2); }
.list-tools .copy-text { margin-left: auto; }
/* The view a list opens in is the class the head's gate set, so the
   toggle shows it before any script runs. */
.view-toggle > button[aria-pressed] { background: none; color: var(--muted); font-weight: 400; box-shadow: none; }
html:not(.list-images) .view-toggle > [data-view="text"], .list-images .view-toggle > [data-view="images"] { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--accent-line); }
@media (scripting: none) { .view-toggle, .copy-text { display: none; } }
.list-images .entries-text, html:not(.list-images) .entries-grid { display: none; }
/* Text view: each section's lines in columns, and the card under the
   pointer pictured beside them. */
.entries-text { display: grid; grid-template-columns: minmax(0, 1fr) 15rem; gap: var(--s8); align-items: start; margin-top: var(--s4); }
.text-sections { columns: 20rem 3; column-gap: var(--s8); }
.text-section { margin-bottom: var(--s5); }
.text-head { break-after: avoid; margin: 0 0 var(--s1); padding-bottom: var(--s1); border-bottom: 1px solid var(--border); font-size: var(--fs-sm); line-height: var(--lh-sm); font-weight: 650; font-variant-numeric: tabular-nums; }
.lines { list-style: none; margin: 0; padding: 0; }
/* A line's cells sit on its first line of text, so a name that wraps keeps
   its count and code beside its start. The whole line opens the card. The
   code column is wide enough for most codes, so rarity icons line up. */
.line {
  --line-h: 2rem;
  position: relative;
  display: grid;
  grid-template-columns: 1.5rem minmax(0, 1fr) auto auto;
  align-items: start;
  gap: var(--s2);
  min-height: var(--line-h);
  padding: calc((var(--line-h) - var(--lh-sm)) / 2) var(--s1);
  border-radius: var(--r-sm);
  break-inside: avoid;
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
}
.line:hover, .line:focus-within { background: var(--raised); }
.line-qty { text-align: right; font-weight: 650; font-variant-numeric: tabular-nums; }
.line-card { grid-column: 2; min-width: 0; overflow-wrap: anywhere; }
.line-name { color: var(--text); font-weight: 500; text-decoration: none; }
.line-name::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.line:hover .line-name { text-decoration: underline; }
.line-ban { position: relative; display: inline-flex; margin-left: var(--s1); vertical-align: -0.1875rem; color: var(--warning-text); }
.line-ban .si { width: 1rem; height: 1rem; }
/* Proportional figures: Inter's tabular ones widen a code's hyphen. */
.line-code { grid-column: 3; display: inline-flex; align-items: center; gap: 0.25rem; min-width: 5.25rem; min-height: var(--lh-sm); color: var(--muted); font-size: var(--fs-xs); white-space: nowrap; }
.line-code .ic { width: 0.875rem; height: 0.875rem; }
.line-own { grid-column: 4; display: inline-flex; align-items: center; justify-content: flex-end; gap: 0.125rem; min-width: 3.25rem; min-height: var(--lh-sm); font-size: var(--fs-xs); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.line[data-missing="0"] .line-own { color: var(--success-text); }
.line-own .si { width: 0.875rem; height: 0.875rem; }
.line-preview { position: sticky; top: var(--s4); }
.line-preview img { display: block; width: 100%; height: auto; aspect-ratio: 744 / 1039; object-fit: contain; border-radius: var(--r-lg); background: var(--raised); }
.line-preview img.landscape { aspect-ratio: 1039 / 744; }
body:has(#missing-only:checked) .line[data-missing="0"] { display: none; }
body:has(#missing-only:checked) .text-section:not(:has(.line:not([data-missing="0"]))) { display: none; }
/* Touch has no pointer to preview with: a tap on a name opens the card. */
@media (max-width: 64rem), (hover: none) {
  .entries-text { grid-template-columns: minmax(0, 1fr); }
  .line-preview { display: none; }
}
body:has(#missing-only:checked) .entry:has(.need[data-missing="0"]) { display: none; }
body:has(#missing-only:checked) .deck-section:not(:has(.need:not([data-missing="0"]))) { display: none; }
.deck-section:first-child .section-head { margin-top: var(--s4); }
.entry .need { margin-top: var(--s1); transition: opacity 150ms; }
/* An entry's counts dim while its new quantity saves. */
.entry:has(.hold[data-fetching]) .need { opacity: 0.5; }
.entry .need p { margin: 0.125rem 0 0; }
.entry .need .own { color: var(--text); font-weight: 600; }
.entry .need[data-missing="0"] .own { color: var(--success-text); }
.entry .where { font-size: var(--fs-xs); line-height: var(--lh-xs); }
/* An entry's controls share one label column. */
.entry .hold, .entry .kind { display: grid; grid-template-columns: 3.5rem minmax(0, 1fr); align-items: center; gap: var(--s1); margin: 0; font-size: var(--fs-xs); }
.entry .hold { padding-top: var(--s2); }
.entry .kind { margin-top: var(--s2); }
.entry :is(.hold, .kind) .what { color: var(--muted); }
.entry .hold .stepper { width: 100%; }
.entry .kind .seg > label { flex: 1 1 0; padding: 0 var(--s2); font-size: var(--fs-xs); }
#list-summary .banned { color: var(--warning-text); font-weight: 600; }

/* ---------- Import ---------- */

.import { display: grid; gap: var(--s4); max-width: 48rem; }
.import textarea { width: 100%; min-height: 12rem; font: var(--fs-sm)/1.5 ui-monospace, monospace; }
.import > p:has(.btn) { display: flex; }
#import-preview { display: grid; gap: var(--s4); }
#import-preview > p.muted { font-size: var(--fs-sm); }
.import-section .section-head { margin: var(--s4) 0 var(--s1); }
.import-section .pick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); margin-bottom: var(--s2); font-size: var(--fs-sm); }
.import-section .pick span { min-width: 6rem; font-weight: 600; }
.unmatched { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); font-size: var(--fs-sm); line-height: var(--lh-sm); }
.unmatched .code { font-weight: 600; }
.unmatched .muted { display: block; font-size: var(--fs-xs); line-height: var(--lh-xs); }
.dest { display: grid; gap: var(--s3); margin: 0; padding: var(--s4); border: 1px solid var(--border); border-radius: var(--r-lg); min-width: 0; }
.dest legend { padding: 0 var(--s1); font-size: var(--fs-sm); font-weight: 600; }
.dest-row { display: grid; grid-template-columns: 11rem minmax(0, 1fr); align-items: center; gap: var(--s2) var(--s3); }
.dest-row .chip { justify-content: flex-start; height: var(--h-md); }
.dest-row.existing { grid-template-columns: 11rem auto; }
.dest-row.existing .seg { grid-column: 2; justify-self: start; }
.dest:has([name="to"][value="new"]:checked) .dest-row:not(:first-of-type) :is(select, .seg) { color: var(--muted); }
.dest:has([name="to"][value="list"]:checked) .dest-row:first-of-type input[type="text"] { color: var(--muted); }
.dest > .seg { justify-self: start; }
.import .cond-default select { max-width: 16rem; }
.import-matched > summary { width: fit-content; min-height: var(--h-md); display: flex; align-items: center; gap: var(--s2); cursor: pointer; color: var(--accent-text); font-size: var(--fs-sm); font-weight: 600; }
.import-matched > summary::before { content: ""; width: 0.4rem; height: 0.4rem; border: solid currentColor; border-width: 0 2px 2px 0; rotate: -45deg; transition: rotate var(--t); }
.import-matched[open] > summary::before { rotate: 45deg; }
.import-matched > summary::-webkit-details-marker { display: none; }
/* Drop zone: a collection file dropped or chosen, over a hidden file
   field the zone's label stands for. */
.dropzone {
  display: grid;
  justify-items: center;
  gap: var(--s1);
  padding: var(--s6) var(--s4);
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--r-lg);
  background: var(--raised);
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  text-align: center;
  cursor: pointer;
  transition: background-color var(--t), border-color var(--t);
}
.dropzone:hover, .dropzone.over { border-color: var(--accent-line); background: var(--accent-soft); }
.dropzone:has(:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.dropzone input[type="file"] { width: 1px; height: 1px; min-width: 0; padding: 0; border: 0; }
.dropzone > .si { width: 1.5rem; height: 1.5rem; color: var(--accent-text); }
.dropzone strong { color: var(--text); font-weight: 600; }
.dropzone-choose { color: var(--accent-text); text-decoration: underline; text-underline-offset: 0.15em; }
.dropzone-file { margin-top: var(--s1); color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.mapping { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--muted); }
.mapping span { display: block; color: var(--text); font-weight: 600; }
.unmatched .row { display: block; margin-top: var(--s1); font: var(--fs-xs)/var(--lh-xs) ui-monospace, monospace; color: var(--muted); overflow-wrap: anywhere; }

/* ---------- Sign in ---------- */

/* The sign-in page: a centred card with the mark, what signing in gets
   you, the button, and what it shares. */
.login {
  display: grid;
  justify-items: center;
  gap: var(--s4);
  max-width: 26rem;
  margin: var(--s8) auto 0;
  padding: var(--s8) var(--s6);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  text-align: center;
}
.login-mark { width: 3rem; height: 3rem; }
.login-pitch { color: var(--muted); text-wrap: pretty; }
.login-options { display: grid; gap: var(--s3); width: 100%; }
.login .btn.provider { width: 100%; height: 3rem; font-size: var(--fs-md); }
.login .problem { width: 100%; text-align: left; }
.login-data { color: var(--muted); font-size: var(--fs-sm); line-height: var(--lh-sm); text-wrap: pretty; }
.login-links { font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--muted); }
.login-links a { display: inline-flex; align-items: center; min-height: var(--h-sm); padding: 0 var(--s2); }

/* The visitor intro: what the site is for, above search, until dismissed. */
.intro {
  display: flex;
  align-items: center;
  gap: var(--s3) var(--s4);
  margin-bottom: var(--s5);
  padding: var(--s3) var(--s3) var(--s3) var(--s5);
  border: 1px solid color-mix(in srgb, var(--accent-line) 35%, transparent);
  border-radius: var(--r-lg);
  background: var(--accent-soft);
}
.intro-text { flex: 1; min-width: 0; text-wrap: pretty; }
.intro-text strong { font-weight: 650; }
.intro-dismissed .intro { display: none; }
/* Getting started: three steps, each done or with what to do next. */
.onboarding { margin-bottom: var(--s5); padding: var(--s4) var(--s5) var(--s5); border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--shadow-sm); }
.onboarding-dismissed .onboarding { display: none; }
.onboarding-head { display: flex; align-items: center; gap: var(--s3); }
.onboarding-head h2 { font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: 650; }
.onboarding-head p { flex: 1; font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.steps { list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: var(--s4) var(--s6); margin: var(--s3) 0 0; padding: 0; }
.step { display: flex; gap: var(--s3); }
.step-mark { flex: none; display: grid; place-items: center; width: 1.75rem; height: 1.75rem; border-radius: 50%; background: var(--accent-soft); color: var(--accent-text); font-size: var(--fs-sm); font-weight: 700; }
.step.done .step-mark { background: var(--success-soft); color: var(--success-text); }
.step-mark .si { width: 1rem; height: 1rem; }
.step-body { display: grid; gap: var(--s2); min-width: 0; font-size: var(--fs-sm); line-height: var(--lh-sm); }
.step-title { font-size: var(--fs-md); line-height: 1.75rem; font-weight: 600; }
.step.done .step-title { color: var(--muted); }
.step-links { display: flex; flex-wrap: wrap; gap: var(--s2); }
.first-folder { display: flex; flex-wrap: wrap; gap: var(--s2); margin: 0; }
.first-folder input[type="text"] { flex: 1 1 10rem; }
.empty .first-folder { width: min(100%, 26rem); }
/* Under someone else's shared folder or list: an invitation, set apart
   from what is shared. */
.track-own {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3) var(--s4);
  margin-top: var(--s8);
  padding: var(--s4) var(--s5);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
}
.track-own strong { color: var(--text); font-weight: 600; }
/* Sign in with a provider, in its own colours. */
.btn.provider { gap: var(--s2); font-weight: 600; }
.btn.provider .si { width: 1.25rem; height: 1.25rem; }
/* Discord's blurple, as Simple Icons records it from https://discord.com/branding. */
.btn.discord { border-color: #5865f2; background: #5865f2; color: #ffffff; }
.btn.discord:hover { border-color: color-mix(in srgb, #5865f2 85%, black); background: color-mix(in srgb, #5865f2 85%, black); }
/* Google's light and dark themes, from
   https://developers.google.com/identity/branding-guidelines: fill, a 1px
   stroke, and text colours as given there, medium weight at 14/20, and the
   G at 20px with 12px before it and 10px after. The guidelines name Google
   Sans, which this site doesn't load; it uses its own font. */
.btn.google { gap: 10px; padding: 0 12px; border-color: #747775; background: #ffffff; color: #1f1f1f; font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; }
.btn.google:hover { background: color-mix(in srgb, #ffffff 92%, #1f1f1f); }
.login .btn.google { font-size: 0.875rem; }
@media (prefers-color-scheme: dark) {
  .btn.google { border-color: #8e918f; background: #131314; color: #e3e3e3; }
  .btn.google:hover { background: color-mix(in srgb, #131314 92%, #e3e3e3); }
}
/* Twitch Purple, with the white Glitch, from Twitch's Logo Usage
   Guidelines (https://brand.twitch.com). */
.btn.twitch { border-color: #9146ff; background: #9146ff; color: #ffffff; }
.btn.twitch:hover { border-color: color-mix(in srgb, #9146ff 85%, black); background: color-mix(in srgb, #9146ff 85%, black); }

/* ---------- Privacy and terms ---------- */

/* Prose: a page of reading, with headings and lists at a reading measure. */
.prose { line-height: 1.65; text-wrap: pretty; }
.prose h2 { margin: var(--s8) 0 var(--s2); font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: 650; }
.prose p, .prose ul { margin: var(--s3) 0 0; }
.prose ul { padding-left: var(--s5); }
.prose li + li { margin-top: var(--s2); }
.prose code { padding: 0 0.3em; border-radius: var(--r-sm); background: var(--raised); font-size: 0.875em; overflow-wrap: anywhere; }
.draft-note { display: flex; gap: var(--s2); margin-top: var(--s3); padding: var(--s2) var(--s3); border-radius: var(--r-md); background: var(--accent-soft); color: var(--text); font-size: var(--fs-sm); line-height: var(--lh-sm); }
.draft-note .si { margin-top: 0.0625rem; color: var(--accent-text); }
/* A gap only the site's owner can fill: plain to see, in a draft. */
.gap { padding: 0.125rem 0.375rem; border-radius: var(--r-sm); background: var(--warning-soft); color: var(--warning-text); box-shadow: inset 0 0 0 1px var(--warning); font-weight: 600; box-decoration-break: clone; -webkit-box-decoration-break: clone; }

/* ---------- Account ---------- */

.account-who { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3) var(--s4); padding: var(--s4); border: 1px solid var(--border); border-radius: var(--r-lg); }
.account-who p { flex: 1; min-width: 10rem; display: grid; overflow-wrap: anywhere; }
.account-who strong { font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: 650; }
.account-who .muted { font-size: var(--fs-sm); line-height: var(--lh-sm); }
.account-who form { margin: 0; }
.account-part > p { color: var(--muted); text-wrap: pretty; }
.account-part > p a { color: var(--accent-text); }
.account-identities { list-style: none; display: grid; gap: var(--s2); margin: var(--s4) 0 0; padding: 0; }
.account-identities li { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); min-height: calc(var(--h-sm) + 2 * var(--s2)); padding: var(--s2) var(--s2) var(--s2) var(--s4); border: 1px solid var(--border); border-radius: var(--r-md); }
.account-identities .si { width: 1.25rem; height: 1.25rem; }
.account-identities .discord .si { color: #5865f2; }
.identity-name { flex: 1; min-width: 8rem; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--s2); }
.identity-name .muted, .identity-only { font-size: var(--fs-sm); line-height: var(--lh-sm); }
.identity-only { padding-right: var(--s2); }
.account-identities form { margin: 0; }
.account-downloads { list-style: none; display: grid; gap: var(--s3); margin: var(--s4) 0 0; padding: 0; }
.account-downloads li { display: grid; grid-template-columns: 11rem minmax(0, 1fr); align-items: center; gap: var(--s2) var(--s4); font-size: var(--fs-sm); line-height: var(--lh-sm); }
.danger-zone .section-head { color: var(--danger-text); }
.danger-zone > .problem, .danger-zone > .btn { margin-top: var(--s4); }
#confirm-account-delete .field strong { color: var(--text); }

/* ---------- Quick add ---------- */

/* The settings bar and the entry box stay in view while the log scrolls
   under them. */
.quick-head {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  margin: calc(-1 * var(--s6)) calc(-1 * var(--gutter)) 0;
  padding: var(--s3) var(--gutter);
  /* The rule spans the content, as the header's does; the background
     reaches the window's edge under scrolled content. */
  background: linear-gradient(var(--border), var(--border)) bottom / calc(100% - 2 * var(--gutter)) 1px no-repeat, var(--bg);
}
.qbar { display: flex; flex-wrap: wrap; align-items: end; gap: var(--s2) var(--s3); }
.qset { display: flex; flex-wrap: wrap; align-items: end; gap: var(--s2) var(--s3); margin: 0; min-width: 0; }
.qset select { max-width: 15rem; }
.qbeep { margin-left: auto; height: var(--h-md); }
.qentry { margin: var(--s3) 0 0; }
.qentry input,
.qentry input:hover {
  width: 100%;
  height: 3.5rem;
  padding: 0 var(--s4);
  border: 2px solid var(--border-strong);
  border-radius: var(--r-lg);
  font-size: var(--fs-xl);
  font-variant-numeric: tabular-nums;
}
.qentry input:focus,
.qentry input:focus-visible { outline: none; border-color: var(--focus); box-shadow: 0 0 0 3px var(--accent-soft); }
.qhint { margin: var(--s2) 0 0; font-size: var(--fs-xs); line-height: 1.7; color: var(--muted); }
.qtotal { margin: var(--s4) 0 var(--s2); font-weight: 650; font-variant-numeric: tabular-nums; }
.qtotal.muted { font-weight: 400; }
.qlog { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.qlog:empty { border-top: 0; }
.qa { display: flex; align-items: center; gap: var(--s3); padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border); }
.qa-main { flex: 1; min-width: 0; }
.qa p { margin: 0; font-size: var(--fs-sm); line-height: var(--lh-sm); overflow-wrap: anywhere; }
.qa p + p { margin-top: 0.125rem; }
.qa-thumb {
  flex: none;
  width: 2.5rem;
  height: auto;
  aspect-ratio: 744 / 1039;
  object-fit: contain;
  border-radius: var(--r-sm);
  background: var(--raised);
}
/* A line not yet added, or never added, keeps a card's place, so its text
   lines up with the added lines' and it doesn't grow when it is added. */
.qa-slot { display: grid; place-items: center; color: var(--muted); }
.qa-slot .si { width: 1.25rem; height: 1.25rem; }
.qa:is(.error, .failed) .qa-slot { background: none; color: var(--danger-text); }
/* A pick list is taller than a card: its mark stays by its first line. */
.qa.pick .qa-slot { align-self: flex-start; height: var(--lh-sm); background: none; color: var(--accent-text); }
.qa-code { font-weight: 650; }
.qa-how { font-size: var(--fs-xs); line-height: var(--lh-xs); }
.qa-n { flex: none; font-weight: 650; font-variant-numeric: tabular-nums; }
/* Undone takes Undo's width, so quantities stay in one column. */
.qa-undo.btn, .qa-undone { min-width: 4rem; }
.qa-undone { flex: none; font-size: var(--fs-sm); text-align: center; }
.typed { font-weight: 650; font-variant-numeric: tabular-nums; }
.qa-problem { color: var(--danger-text); }
.qa-fail .btn { margin-left: var(--s2); vertical-align: middle; }
/* A line still on its way: a spinner in its card's place, and its text
   muted. */
.qa.pending .typed { color: var(--muted); }
.qa.pending .qa-slot > .si { display: none; }
.qa.pending .qa-slot::before {
  content: "";
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--muted);
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
.qa.pending .picks button { color: var(--muted); pointer-events: none; }
.qa.undone :is(.qa-what, .qa-how) { color: var(--muted); text-decoration: line-through; }
.qa.undone .qa-thumb { opacity: 0.4; }
.qa.error, .qa.failed { background: var(--danger-soft); }
.qa.cancelled .typed, .qa.cancelled .qa-ask { color: var(--muted); }
.picks { list-style: none; margin: var(--s2) 0 0; padding: 0; display: grid; gap: var(--s1); }
.picks button {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  min-height: var(--h-md);
  padding: var(--s1) var(--s3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: inherit;
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--t), border-color var(--t);
}
.picks button:hover { border-color: var(--accent-line); background: var(--accent-soft); }
.picks .qa-thumb { width: 2rem; }
.picks button > span { display: flex; flex-wrap: wrap; gap: 0 0.375rem; min-width: 0; }
/* The pick list the number keys answer: the oldest still open. */
.qa.pick:not(.pending):not(:has(~ .qa.pick:not(.pending))) { box-shadow: inset 3px 0 0 var(--pick-bar); background: var(--accent-soft); }
.qa.added { animation: qa-flash 0.9s ease-out; }
.qa.undone { animation: qa-flash-undo 0.9s ease-out; }
.qa.error { animation: qa-flash-error 0.9s ease-out; }
@keyframes qa-flash { from { background: color-mix(in srgb, var(--accent) 30%, var(--bg)); } }
@keyframes qa-flash-undo { from { background: var(--raised); } }
@keyframes qa-flash-error { from { background: color-mix(in srgb, var(--danger) 30%, var(--bg)); } }

/* ---------- Phone ---------- */

@media (max-width: 40rem) {
  .searchbox { flex: 1 1 0; }
  .filters-btn { order: 1; }
  /* On a phone the sort is a square like the Filters button: the picker
     names the sort, and the tint says one is chosen. */
  .sort-field { order: 1; }
  .sort-field select, .sort-field:has(option:checked:not([value=""])) select { width: var(--h-md); padding: 0; background-image: none; color: transparent; }
  /* The clear button shows only once there is text, so until then the
     placeholder may use its room. */
  .searchbox input:placeholder-shown { padding-right: var(--s3); }
  .sort-field option { color: var(--text); }
  .sort-field > .si { left: 50%; translate: -50% 0; }
  .domains { order: 2; flex: 1 1 100%; gap: 0.1875rem; }
  .itog { width: auto; flex: 1 1 0; }
  .filters-btn .filters-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .filters-btn .chev { display: none; }
  /* One row that scrolls sideways, so more chips never add a line. */
  .results-head { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); }
  .results-head .count, .active, .achip { flex: none; white-space: nowrap; }
  .active { flex-wrap: nowrap; }
  .card-modal { width: 100%; height: 100dvh; max-height: none; margin: 0; border: 0; border-radius: 0; translate: 0 1.5rem; }
  @starting-style { .card-modal[open] { translate: 0 1.5rem; } }
  #card-modal-body { padding: var(--s2) var(--s4) var(--s8); }
  .pop, .panel {
    inset: auto 0 0 0;
    width: 100%;
    max-width: none;
    max-height: 90dvh;
    margin: 0;
    border-width: 1px 0 0;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    translate: 0 1.5rem;
  }
  @starting-style { .pop:popover-open { translate: 0 1.5rem; } }
  .pop-foot { flex-direction: column-reverse; }
  .pop-foot .btn { width: 100%; }
  .panel .pop-foot { justify-content: flex-start; }
  .panel-grid { grid-template-columns: minmax(0, 1fr); }
  .pop-body .stepper { width: 100%; }
  .qty-row .stepper { flex: 1; width: auto; }
  /* The name's top padding reaches into the row's, so the name sits close
     under the rule and its totals close under it, while it and the rename
     field that replaces it stay 44px tall and take the same room. */
  .index-row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 0; padding-block: var(--s4); }
  :is(.index-name, .rename input) { margin-top: calc((var(--lh-md) - var(--h-md)) / 2); }
  .index-row .totals { grid-column: 1; }
  .index-row .actions { grid-column: 2; grid-row: 1 / span 2; }
  .table tr { display: grid; grid-template-columns: 1.5rem 7rem minmax(0, 1fr); column-gap: var(--s2); padding: var(--s2) 0; border-bottom: 1px solid var(--border); }
  .table tr:last-child { border-bottom: 0; }
  .table td, .table td.qty, .table td.code, .table .why { width: auto; border-bottom: 0; padding: 0; }
  .table :is(.what, .why) { grid-column: 3; }
  .dest > .seg { justify-self: stretch; }
  .import .cond-default select { max-width: none; }
  .dest-row, .dest-row.existing { grid-template-columns: minmax(0, 1fr); }
  .dest-row.existing .seg { grid-column: 1; justify-self: stretch; }
  .qbar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2); }
  .qset { display: contents; }
  .account-downloads li { grid-template-columns: minmax(0, 1fr); }
  .intro { flex-wrap: wrap; padding: var(--s4); position: relative; }
  .intro-text { flex-basis: 100%; padding-right: var(--s8); }
  .intro > .btn { flex: 1; }
  .intro-close { position: absolute; top: var(--s1); right: var(--s1); }
  .login { margin-top: var(--s4); padding: var(--s6) var(--s4); }
  .qset select { width: 100%; max-width: none; }
  .qset .seg { width: 100%; }
  .qbeep { margin: 0; justify-self: stretch; align-self: end; }
  .qentry input, .qentry input:hover { height: 3.5rem; font-size: 1.375rem; }
  .qhint { display: none; }
  .entry .hold, .entry .kind { grid-template-columns: minmax(0, 1fr); }
  .text-sections { columns: 1; }
  /* The owner bar keeps Private / Public, Copy link, Download, and Delete on
     one line at 390px. */
  .page-head > .owner-bar, .owner-bar > .share { column-gap: var(--s2); }
  .seg.sm > :is(label, button) { padding: 0 var(--s2); }
  /* Download and Copy as text are lone icons, as Delete is, so the share
     controls and the list tools each keep one line. Their labels stay for
     screen readers. */
  .btn:is(.download-button, .copy-text) { width: var(--h-sm); padding: 0; }
  :is(.download-button, .copy-text) > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .download-button .chev { display: none; }
}

/* On touch, the stepper's border sits outside its 44px buttons, and a
   holding's line is a 44px row. */
@media (max-width: 40rem), (pointer: coarse) {
  .stepper, .stepper.sm { height: calc(var(--h-md) + 2px); }
  :is(button, summary).hl { min-height: 2.75rem; }
  .line { --line-h: 2.75rem; }
}
