/* snailbin — the garage visual language, carried over deliberately.
   Flat / sharp / navy on paper. Jost for UI, IBM Plex Mono for data.
   No border-radius on structure, no shadows, hairline borders, high density. */

@font-face { font-family:'Jost'; src:url('/assets/fonts/jost-400.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:'Jost'; src:url('/assets/fonts/jost-500.woff2') format('woff2'); font-weight:500; font-display:swap; }
@font-face { font-family:'Jost'; src:url('/assets/fonts/jost-600.woff2') format('woff2'); font-weight:600; font-display:swap; }
/* Bold is 600 app-wide — the heaviest face shipped. One fewer font file on
   every cold load, and no browser-synthesized fake bold. */
b, strong { font-weight:600; }
@font-face { font-family:'IBM Plex Mono'; src:url('/assets/fonts/plexmono-400.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:'IBM Plex Mono'; src:url('/assets/fonts/plexmono-500.woff2') format('woff2'); font-weight:500; font-display:swap; }

:root {
  --navy:#1a2b4a; --ink:#1a2236; --paper:#eef0f4; --card:#fff;
  --line:#d2d7e0; --muted:#6a7184; --muted-soft:#9aa1b0;
  --ok:#1a7f4b; --warn:#9a6a00; --bad:#b3261e;
  --on-navy:#fff; --sunk:#e7eaf0; --hover:#f7f8fb; --photo:#13203a;
  --font-ui:'Jost', ui-sans-serif, system-ui, sans-serif;
  --font-mono:'IBM Plex Mono', ui-monospace, Consolas, monospace;
}

/* Dark palette — the same tokens, inverted ground. Applied for an explicit
   Dark choice, and for System via prefers-color-scheme (guarded so an
   explicit Light choice always wins). Fonts inherit from :root. */
:root[data-theme="dark"] {
  --navy:#8fb4e6; --ink:#e7ebf3; --paper:#0f131b; --card:#181d28;
  --line:#2b3242; --muted:#9aa1b0; --muted-soft:#697182;
  --ok:#4ccb8a; --warn:#d8ad55; --bad:#f0857b;
  --on-navy:#0f131b; --sunk:#232a38; --hover:#212734; --photo:#0b0f16;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  --navy:#8fb4e6; --ink:#e7ebf3; --paper:#0f131b; --card:#181d28;
  --line:#2b3242; --muted:#9aa1b0; --muted-soft:#697182;
  --ok:#4ccb8a; --warn:#d8ad55; --bad:#f0857b;
  --on-navy:#0f131b; --sunk:#232a38; --hover:#212734; --photo:#0b0f16;
  }
}

* { box-sizing:border-box; }
body { margin:0; background:var(--paper); color:var(--ink);
       font:15px/1.5 var(--font-ui); }
a { color:var(--navy); }

/* ---- Top bar --------------------------------------------------------- */
.topbar { height:60px; background:var(--card); border-bottom:1px solid var(--line);
          display:flex; align-items:center; gap:18px; padding:0 20px; }
.topbar .wordmark { font-weight:600; font-size:17px; letter-spacing:.12em;
          text-transform:uppercase; color:var(--ink); text-decoration:none; }
.topbar-links { margin-left:auto; display:flex; align-items:center; gap:18px; }
.topbar-links a { display:inline-flex; align-items:center; gap:6px;
          font-size:12px; letter-spacing:.08em; text-transform:uppercase;
          color:var(--muted); text-decoration:none; font-weight:500; }
.topbar-links a:hover { color:var(--navy); }
/* The form is the flex child, not the button — flatten it so the button
   aligns like its sibling links instead of riding the form's line box. */
.topbar-links form { margin:0; display:flex; align-items:center; }
.topbar-links button { display:inline-flex; align-items:center; gap:6px;
          font:500 12px/1.5 var(--font-ui); letter-spacing:.08em;
          text-transform:uppercase; color:var(--muted); background:none;
          border:0; padding:0; cursor:pointer; }
.topbar-links button:hover { color:var(--navy); }
.topbar-who { font-size:13px; color:var(--muted); white-space:nowrap; }
.topbar-who b { color:var(--ink); font-weight:600; }

/* The Galleries dropdown — the one place the design allows a shadow,
   matching garage's dropdown allowance. */
/* The details element is the flex child — flatten it like the logout form,
   and give the summary the links' exact metrics (12px/1.5; the bare font:
   shorthand resets line-height, which is what knocked Lock out of line too). */
.topbar-menu { position:relative; display:flex; align-items:center; }
.topbar-menu summary { display:inline-flex; align-items:center; gap:6px;
        font:500 12px/1.5 var(--font-ui); letter-spacing:.08em; text-transform:uppercase;
        color:var(--muted); cursor:pointer; list-style:none; }
.topbar-menu summary::-webkit-details-marker { display:none; }
.topbar-menu summary:hover, .topbar-menu[open] summary { color:var(--navy); }
.topbar-menu .menu { position:absolute; right:0; top:calc(100% + 14px); z-index:50;
        min-width:180px; background:var(--card); border:1px solid var(--line);
        box-shadow:0 6px 20px rgba(19,32,58,.13); }
.topbar-menu .menu a, .topbar-menu .menu button { display:flex; align-items:center;
        gap:10px; width:100%; padding:10px 14px; font:500 12px/1.5 var(--font-ui);
        letter-spacing:.08em; text-transform:uppercase; color:var(--muted);
        text-decoration:none; border:0; border-top:1px solid var(--line);
        background:none; cursor:pointer; text-align:left; }
.topbar-menu .menu a:first-child, .topbar-menu .menu form:first-child button { border-top:0; }
.topbar-menu .menu a:hover, .topbar-menu .menu button:hover { color:var(--navy); background:var(--hover); }
.topbar-menu .menu form { margin:0; }
.topbar-menu .menu .ic { width:15px; height:15px; }

.ic { display:block; width:18px; height:18px; flex:none; }
.topbar-links .ic { width:16px; height:16px; }
.topbar-links button .ic { width:14px; height:14px; }

/* ---- Page column ------------------------------------------------------ */
.wrap { max-width:740px; margin:0 auto; padding:24px 20px 8px; }

/* ---- Footer ----------------------------------------------------------- */
.site-foot { max-width:740px; margin:0 auto; padding:24px 20px 40px;
        display:flex; flex-wrap:wrap; justify-content:center; gap:6px 18px;
        font:500 10.5px var(--font-mono); letter-spacing:.12em;
        text-transform:uppercase; color:var(--muted-soft); }
.site-foot a { color:inherit; text-decoration:none; }
.site-foot a:hover { color:var(--navy); }
/* Running prose (legal.php): paragraphs share one block of padding. */
.wrap > section.legal > p + p { padding-top:0; }
.back-link { display:inline-block; font:500 11px var(--font-mono);
          letter-spacing:.12em; text-transform:uppercase; color:var(--muted);
          text-decoration:none; margin:0 0 14px; }
.back-link:hover { color:var(--navy); }

/* Every section is a flat card. */
.wrap > section { background:var(--card); border:1px solid var(--line);
          margin:0 0 16px; }
.wrap > section > h1, .wrap > section > h2 {
          margin:0; padding:16px 18px 0; font-size:19px; font-weight:600; }
.wrap > section > h2 { font-size:15px; }
.wrap > section > p, .wrap > section > form, .wrap > section > table,
.wrap > section > ul, .wrap > section > div { margin:0; }
.wrap > section > p, .wrap > section > form { padding:12px 18px 16px; }
.wrap > section > p + form, .wrap > section > form + form { padding-top:0; }
.eyebrow { font:500 10.5px var(--font-mono); letter-spacing:.14em;
          text-transform:uppercase; color:var(--muted-soft);
          padding:14px 18px 0; }
.eyebrow + h1, .eyebrow + h2 { padding-top:2px; }

.flash { max-width:740px; margin:16px auto -6px; padding:11px 18px;
          font-size:14px; border:1px solid var(--line); background:var(--card); }
.flash.ok { color:var(--ok); } .flash.error { color:var(--bad); }
.muted { color:var(--muted); font-size:13px; }
.empty { color:var(--muted); padding:14px 18px; font-size:14px; }

/* ---- Forms ------------------------------------------------------------ */
label { display:block; margin:0 0 4px; font:500 11px var(--font-mono);
        letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
input[type=text], input[type=email], input[type=password], input[type=search],
input[type=number], select, textarea {
        width:100%; margin:0 0 12px; border:1px solid var(--line);
        border-radius:0; font:15px var(--font-ui); background:var(--card); color:var(--ink); }
/* Single-line controls share one 36px height so they read trim and line up
   with buttons on a row without per-field tuning. Textareas keep their own
   padding, being multi-line. */
input[type=text], input[type=email], input[type=password], input[type=search],
input[type=number], select {
        height:36px; padding:0 11px; }
input[type=number] { width:90px; }
textarea { min-height:64px; padding:9px 11px; resize:vertical; }
button, .btn { display:inline-flex; align-items:center; gap:8px;
        padding:9px 18px; border:1px solid var(--navy); background:var(--navy);
        color:var(--on-navy); font:500 14px var(--font-ui); cursor:pointer; border-radius:0;
        text-decoration:none; }
button.quiet, .btn-ghost { background:var(--card); color:var(--navy); }
input[type=file] { font-size:13px; }
.inline-form { display:flex; gap:10px; align-items:flex-end; flex-wrap:wrap; }
.inline-form > div { flex:1 1 150px; }
.inline-form input { margin-bottom:0; }
/* Inline buttons match the 36px control height so a row aligns cleanly. */
.inline-form button, .inline-form .btn, .inline-form .btn-ghost {
        white-space:nowrap; height:36px; padding:0 16px; line-height:normal; }

/* ---- Settings overview tiles ------------------------------------------- */
.head-badge { font:400 11px var(--font-mono); letter-spacing:.04em;
        color:var(--muted); text-transform:none; margin-left:8px; }
/* A true grid: the line colour is the backdrop and 1px gaps let it through,
   so every cell edge is drawn, empty cells included, and nothing depends on
   fractional column widths lining up. */
.stat-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(120px, 1fr));
        gap:1px; background:var(--line); border:1px solid var(--line);
        margin:14px 18px 18px; }
.stat { background:var(--card); padding:14px 16px 12px; }
.stat-n { font-size:24px; font-weight:600; line-height:1.2; }
.stat-label { font:500 10.5px var(--font-mono); letter-spacing:.12em;
        text-transform:uppercase; color:var(--muted); margin-top:2px; }

.btn-row { display:flex; gap:10px; margin:0 0 16px; flex-wrap:wrap; }
.btn-row .btn, .btn-row .btn-ghost { flex:1 1 160px; justify-content:center; }
.btn-row form { display:contents; }
/* A cancel is a way out, not a second button of equal weight. */
.btn-row .cancel { flex:0 0 auto; }

/* ---- Bin list --------------------------------------------------------- */
ul.bin-list { list-style:none; margin:0; padding:0 0 2px; }
.bin-row { border-top:1px solid var(--line); }
.bin-row > a { display:flex; align-items:center; gap:15px; padding:14px 18px;
        text-decoration:none; color:inherit; }
.bin-idx { width:46px; height:46px; flex:none; background:var(--navy); color:var(--on-navy);
        font:500 15px var(--font-mono); display:flex; align-items:center;
        justify-content:center; }
.bin-idx .ic { width:22px; height:22px; }
.bin-idx-system { background:var(--muted); }
/* Bin art (feature: binart): the drawn tote takes the number's slot. An
   undressed bin shows the ghost — dashed, transparent, quiet. */
.bin-idx-art { background:var(--card); border:1px solid var(--line); }
.binart-ghost { color:var(--muted-soft); }
.bin-idx-art svg { display:block; max-width:40px; }
.binhead.has-art { display:flex; align-items:center; gap:16px; }
.binhead-art { flex:none; }
.binhead-art svg, .binhead-art img { display:block; height:52px; width:auto; }
.bin-meta { min-width:0; }
.bin-name { font-weight:500; font-size:15.5px; }
.bin-sub { font-size:13px; color:var(--muted); }
.bin-count { margin-left:auto; font:400 12px var(--font-mono); color:var(--muted);
        white-space:nowrap; }
.bin-type { display:inline-block; margin-left:9px; padding:2px 7px;
        border:1px solid var(--line); font:400 10px var(--font-mono);
        letter-spacing:.07em; text-transform:uppercase; color:var(--muted);
        vertical-align:middle; }
.binhead h1 .bin-type { margin-left:12px; }
.bin-chevron { color:var(--muted-soft); font-size:18px; }

/* ---- Item rows -------------------------------------------------------- */
ul.item-list { list-style:none; margin:0; padding:0 0 2px; }
.item-row { display:flex; align-items:center; gap:14px; padding:13px 18px;
        border-top:1px solid var(--line); }
.item-main { display:flex; align-items:center; gap:14px; min-width:0; flex:1;
        text-decoration:none; color:inherit; }
.thumb { width:52px; height:52px; flex:none; object-fit:contain;
        background:var(--sunk); border:1px solid var(--line); }
.thumb-placeholder { display:flex; align-items:center; justify-content:center;
        color:var(--muted-soft); font:500 10px var(--font-mono); }
.item-meta { min-width:0; display:flex; flex-direction:column; }
.item-name { font-weight:500; font-size:15.5px; }
.item-name.untitled, h1.untitled { color:var(--muted); }
.item-desc { font-size:13px; color:var(--muted); overflow:hidden;
        text-overflow:ellipsis; white-space:nowrap; max-width:46vw; }
.item-by { font-size:12px; color:var(--muted-soft); }
.item-qty { font:400 12px var(--font-mono); color:var(--muted); white-space:nowrap; }
.item-code { font:400 11.5px var(--font-mono); color:var(--muted-soft); }

/* ---- Capture ---------------------------------------------------------- */
.add-buttons { display:flex; gap:10px; flex-wrap:wrap; padding:14px 18px 4px; }
.add-buttons label { display:inline-flex; align-items:center; gap:8px;
        padding:10px 18px; margin:0; cursor:pointer; font:500 14px var(--font-ui);
        letter-spacing:0; text-transform:none; }
.add-buttons .btn { border:1px solid var(--navy); background:var(--navy); color:var(--on-navy); }
.add-buttons .btn-ghost { border:1px solid var(--navy); background:var(--card); color:var(--navy); }
.capture-hint { padding:6px 18px 14px; color:var(--muted); font-size:13px; }
/* The "add a …" kind selector above the capture buttons: quiet, inline. */
.capture-kind { display:flex; align-items:center; gap:12px; padding:16px 18px 0; }
.capture-kind label { margin:0; }
.capture-kind select { width:auto; margin:0; }
#capture-form .add-buttons { padding-top:12px; }
/* The bin's QR, no longer in the header: a quiet label block, image beside
   its caption. */
.binlabel { display:flex; align-items:center; gap:18px; }
.binlabel .qrbox { flex:none; }
.binlabel-text > h2 { margin:0; padding:0; font-size:15px; }
.binlabel-text > p { margin:4px 0 12px; font-size:13px; }
.binlabel-text .btn-ghost { }

/* ---- Capture tabs ------------------------------------------------------ */
.tab-bar { display:flex; overflow-x:auto; border-bottom:1px solid var(--line); }
.tab { display:inline-flex; align-items:center; gap:7px; padding:11px 16px;
        font:500 12px var(--font-mono); letter-spacing:.08em; text-transform:uppercase;
        color:var(--muted); background:none; border:0; cursor:pointer;
        text-decoration:none; white-space:nowrap; }
.tab.is-active { color:var(--navy); box-shadow:inset 0 -2px 0 var(--navy); }
.tab .ic { width:15px; height:15px; }
.req { color:var(--bad); font-style:normal; font-size:10px; }
.check-label { display:flex; align-items:center; gap:8px; margin:0 0 12px;
        font:inherit; letter-spacing:0; text-transform:none; color:var(--ink);
        font-size:14px; }
.check-label input { width:auto; margin:0; }

/* ---- Cover grid (galleries) -------------------------------------------- */
.gallery-tabs { background:var(--card); border:1px solid var(--line); margin:0 0 16px; }
.cover-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(96px, 1fr));
        gap:12px; padding:14px 18px 18px; }
.cover { display:block; border:1px solid var(--line); background:var(--sunk);
        aspect-ratio:2/3; overflow:hidden; }
.cover-img { width:100%; height:100%; object-fit:cover; display:block; }
.cover-placeholder { display:flex; align-items:center; justify-content:center;
        color:var(--muted-soft); }
.cover-placeholder .ic { width:30px; height:30px; }
.gallery-filters { padding:12px 18px 0 !important; }
.pager { display:flex; gap:10px; justify-content:center; padding:0 18px 16px; }
.item-kind { display:inline-flex; align-items:center; gap:6px; }
.item-kind .ic { width:14px; height:14px; }
.detail-fields { font-size:13.5px; }

/* ---- Categories & galleries page --------------------------------------- */
/* Three doors on one page. Same metrics as the capture tabs, stacked. */
.tile-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:10px;
        margin:0 0 16px; }
.tile { display:flex; flex-direction:column; align-items:center; gap:8px;
        padding:16px 8px 14px; background:var(--card); border:1px solid var(--line);
        text-decoration:none; color:var(--muted); text-align:center;
        font:500 11px var(--font-mono); letter-spacing:.1em; text-transform:uppercase; }
.tile .ic { width:22px; height:22px; }
.tile:hover { color:var(--navy); }
.tile.is-active { color:var(--navy); border-color:var(--navy);
        box-shadow:inset 0 -2px 0 var(--navy); }
td.actions { white-space:nowrap; text-align:right; }
td.actions .btn-ghost, td.actions button { padding:4px 10px; font-size:12px;
        line-height:1.5; vertical-align:middle; }
td.actions form { margin-left:4px; }
button:disabled { opacity:.4; cursor:not-allowed; }

/* The icon picker: a row of radios that look like what they choose. */
.icon-grid { display:flex; flex-wrap:wrap; gap:8px; margin:0 0 12px; }
.icon-grid label { position:relative; width:44px; height:44px; margin:0;
        display:flex; align-items:center; justify-content:center;
        border:1px solid var(--line); background:var(--card); color:var(--muted); cursor:pointer; }
.icon-grid label:hover { color:var(--navy); }
.icon-grid label:has(input:checked) { color:var(--navy); border-color:var(--navy);
        box-shadow:inset 0 0 0 1px var(--navy); }
.icon-grid input { position:absolute; opacity:0; width:0; height:0; }
.icon-grid .ic { width:20px; height:20px; }

/* Gallery opt-in: the name only matters once the box is ticked. */
.gallery-opt .gallery-name-field { display:none; }
.gallery-opt:has(input[type=checkbox]:checked) .gallery-name-field { display:block; }
.gallery-form td .check-label { margin:0; white-space:nowrap; }
.gallery-form td .gallery-name { margin:0; }
.gallery-row:not(:has(input[type=checkbox]:checked)) .gallery-name { visibility:hidden; }
td.order { white-space:nowrap; text-align:right; width:1%; }
.gallery-form button.move { padding:4px 8px; font-size:10px; line-height:1.6; }
.gallery-form .muted { padding:10px 18px 12px; margin:0; }

/* ---- Category field builder ------------------------------------------- */
.field-row { display:flex; gap:8px; flex-wrap:wrap; align-items:center;
        margin:0 0 8px; }
.field-row input[type=text] { flex:1 1 140px; width:auto; margin:0; }
.field-row select { flex:0 1 110px; width:auto; margin:0; }
.field-row .check-label { margin:0; font-size:13px; white-space:nowrap; }
/* Choices and the gallery filter only mean something for a choices field. */
.field-row .opts, .field-row .opts-only { display:none; }
.field-row:has(select option[value=select]:checked) .opts { display:block; }
.field-row:has(select option[value=select]:checked) .opts-only { display:flex; }

/* ---- Bin header + QR --------------------------------------------------- */
.btn-ghost { display:inline-flex; align-items:center; gap:8px; padding:9px 14px;
        border:1px solid var(--navy); background:var(--card); color:var(--navy);
        font:500 13px/1.5 var(--font-ui); text-decoration:none; cursor:pointer; }
.binhead-sec { position:relative; }
.binhead { padding:16px 18px; }
.binhead .binmeta { min-width:0; padding-right:44px; }
.binhead .eyebrow { padding:0 0 2px; }
.binhead h1 { margin:0; padding:0; font-size:22px; font-weight:600; }
.binhead p { margin:0; padding:0; }
/* Editing hides behind a pencil at the top-right — it also gives the header a
   right-hand anchor now that the QR has moved out. */
/* Header tools: the pencil (edit) and qr (label) toggles, top-right; each is a
   <details> summary, revealing its panel full-width below. right offset is set
   inline per toggle. */
.binhead-tool { position:absolute; top:14px; z-index:1;
        display:flex; align-items:center; justify-content:center;
        width:34px; height:34px; color:var(--muted); cursor:pointer;
        list-style:none; border:1px solid transparent; }
.binhead-tool::-webkit-details-marker { display:none; }
.binhead-tool:hover { color:var(--navy); }
.binhead-sec details[open] > .binhead-tool { color:var(--navy); border-color:var(--line); background:var(--card); }
.binedit-body, .binlabel-body { border-top:1px solid var(--line); padding:14px 18px; }
.binedit-body { padding-bottom:4px; }
.binedit-body .inline-form { padding:0; }
.binedit-body .inline-form > div { flex:1 1 200px; }
.binedit-body form + form { padding:0; margin-top:4px; }
.qrbox { width:104px; height:104px; border:1px solid var(--line); padding:6px; background:#fff; color:#1a2236; }
.qrbox svg { display:block; width:100%; height:100%; }

/* ---- QR print sheet ---------------------------------------------------- */
.page-qr { background:#fff; color:#1a2236; font-family:var(--font-ui); }
.qr-toolbar { display:flex; gap:10px; justify-content:center; padding:16px;
        border-bottom:1px solid var(--line); }
.qr-sheet { text-align:center; padding:34px 24px; max-width:480px; margin:0 auto; }
.qr-box { width:320px; max-width:86vw; aspect-ratio:1/1; margin:0 auto 16px;
        border:1px solid var(--line); padding:10px; background:#fff; }
.qr-box svg { width:100%; height:100%; display:block; }
.qr-title { font-weight:600; font-size:26px; letter-spacing:-.01em; margin:4px 0; }
.qr-loc { font-family:var(--font-mono); font-size:12px; letter-spacing:.04em;
        text-transform:uppercase; color:#6a7184; margin:0 0 10px; }
.qr-url { font-family:var(--font-mono); font-size:10.5px; color:#9aa1b0;
        word-break:break-all; }

@media print {
  .no-print, .mobnav, .topbar { display:none !important; }
  body, .page-qr { background:#fff; }
  .qr-sheet { padding:0; }
  .qr-box { width:70vw; border-color:#000; }
}

/* The folder picker is a desktop affordance; phone pickers do folders their
   own way (feature batchadd). */
@media (max-width:560px) { .batch-folder { display:none; } }

/* Select & move (feature multimove): checkboxes on the contents, a
   destination bar under them. */
.select-toggle { float:right; font:500 13px var(--font-ui); letter-spacing:0;
        text-transform:none; }
.item-pick { width:20px; height:20px; flex:none; margin:0; accent-color:var(--navy); }
.move-bar { display:flex; gap:12px; align-items:center; flex-wrap:wrap;
        padding:12px 18px 16px; border-top:1px solid var(--line); }
.move-bar select { width:auto; margin:0; flex:1 1 180px; }
.move-all { display:flex; align-items:center; gap:8px; margin:0;
        font:500 13px var(--font-ui); }
.move-all input { width:20px; height:20px; margin:0; accent-color:var(--navy); }
/* Delete stands apart from Move — the far side, in the app's danger red. */
.move-delete { margin-left:auto; color:var(--bad); border-color:var(--bad); }

/* ---- Site banner: one admin-set line, in the tone of the news ---------- */
/* display:flex would silently beat the hidden attribute — the dismiss works
   BY that attribute, so it must win. */
.sitebanner[hidden] { display:none; }
.sitebanner { display:flex; align-items:center; justify-content:center; gap:14px;
        padding:10px 16px; font:500 13.5px var(--font-ui); background:var(--card);
        color:var(--ink); border-bottom:1px solid var(--line); text-align:center; }
.sitebanner button { background:none; border:0; color:var(--muted); font-size:19px;
        line-height:1; cursor:pointer; padding:2px 6px; }
.sitebanner-warn { border-bottom:2px solid var(--warn); }
.sitebanner-crit { border-bottom:2px solid var(--bad); background:color-mix(in srgb, var(--bad) 8%, var(--card)); }
.sitebanner-good { border-bottom:2px solid var(--ok); }

/* ---- Space grid (feature spacegrid) ------------------------------------ */
.space-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; padding:14px 18px 0; }
.space-card { display:flex; flex-direction:column; align-items:center; justify-content:center;
        gap:12px; padding:26px 12px 20px; background:var(--sunk); border:1px solid var(--line);
        color:var(--ink); font:500 15px var(--font-ui); letter-spacing:0; text-transform:none;
        cursor:pointer; width:100%; }
.space-card svg { width:44px; height:44px; color:var(--navy); }
.space-card:active { background:var(--hover); }
.space-other { flex-direction:row; margin:12px 18px 16px; padding:14px 12px;
        width:calc(100% - 36px); }
.space-other span { display:inline-flex; align-items:center; gap:8px; }
.space-dialog { border:1px solid var(--line); background:var(--card); color:var(--ink);
        padding:18px; min-width:min(320px, 86vw); }
.space-dialog::backdrop { background:rgba(10, 14, 22, .45); }

/* ---- Status page gauges ------------------------------------------------ */
.status-table th { text-align:left; font-weight:500; color:var(--muted);
        font-size:13px; padding:10px 18px; border-top:1px solid var(--line);
        vertical-align:top; width:40%; }
.status-table td { font:400 13px var(--font-mono); padding:10px 18px;
        border-top:1px solid var(--line); word-break:break-word; }
.status-table tr:first-child th, .status-table tr:first-child td { border-top:0; }
.val-ok { color:var(--ok); } .val-warn { color:var(--warn); } .val-bad { color:var(--bad); }

/* ---- Signed-out landing (what the root is before anyone signs in) ------ */
.landing { min-height:100svh; display:flex; flex-direction:column;
        background:var(--paper); color:var(--ink); }
.landing-hero { flex:1; display:flex; flex-direction:column; align-items:center;
        justify-content:center; gap:16px; padding:24px; }
.landing-mark { color:var(--navy); }
.landing-hero h1 { margin:0; font:600 30px var(--font-ui); letter-spacing:.18em;
        text-transform:uppercase; }
.landing-sub { margin:0; color:var(--muted); font-size:15px; }
.landing-actions { display:flex; gap:12px; margin-top:12px; }
.landing-actions .btn, .landing-actions .btn-ghost { padding:12px 26px;
        font-size:14px; gap:9px; }
.landing-foot { display:flex; align-items:center; justify-content:center;
        gap:18px; flex-wrap:wrap; color:var(--muted); font-size:13px;
        padding:18px 20px calc(18px + env(safe-area-inset-bottom)); }
.landing-foot a { color:inherit; }
.landing-social { display:flex; gap:15px; }
.landing-social a { display:flex; }

/* ---- Item page hero --------------------------------------------------- */
.full-photo { width:100%; max-height:70vh; object-fit:contain; background:var(--photo);
        border-bottom:1px solid var(--line); display:block; }
.full-placeholder { height:240px; background:var(--sunk); display:flex;
        align-items:center; justify-content:center; color:var(--muted-soft);
        font:500 12px var(--font-mono); letter-spacing:.12em; }
.detail-head { display:flex; align-items:baseline; gap:12px; padding:14px 18px 0; }
.detail-head .item-code { font-size:12px; }

/* ---- Search ----------------------------------------------------------- */
/* Buttonless, garage-style: a tall full-width field with the glass inside.
   Enter submits — a search field needs no button to say what it is.
   Scoped past the global input[type=…] rules, which outrank a bare class. */
.search-block { position:relative; margin:0 0 16px; }
.search-block .ic-search { position:absolute; left:15px; top:50%;
        transform:translateY(-50%); width:18px; height:18px;
        color:var(--muted-soft); pointer-events:none; }
.search-block input[type=search] { width:100%; height:50px; margin:0;
        padding:0 16px 0 44px; border:1px solid var(--line);
        background:var(--card); font-size:15px; outline:none; }
.search-block input[type=search]:focus { border-color:var(--navy); }
.search-block input[type=search]::placeholder { color:var(--muted-soft); }

/* ---- Tables (status, people) ------------------------------------------ */
table { width:100%; border-collapse:collapse; }
/* A table wider than the screen scrolls inside its own card instead of
   widening the page — the page body must never scroll sideways on mobile.
   Scoped with :has so only table-bearing cards get a scroll context. */
.wrap > section:has(table) { overflow-x:auto; }
th, td { text-align:left; padding:10px 18px; border-top:1px solid var(--line);
        vertical-align:middle; font-size:13.5px; }
th { font:500 11px var(--font-mono); letter-spacing:.08em; text-transform:uppercase;
        color:var(--muted); }
td { font-size:14px; }
td.mono, .ok, .warn, .bad { font-family:var(--font-mono); font-size:12.5px; }
.ok { color:var(--ok); } .warn { color:var(--warn); } .bad { color:var(--bad); }
td form { display:inline; }
td button { padding:4px 10px; font-size:12px; }
td.thumb-cell { width:60px; padding-right:0; }

/* ---- Mobile bottom nav ------------------------------------------------ */
.mobnav { display:none; }
@media (max-width:560px) {
  .topbar-links { display:none; }
  .mobnav { display:grid; grid-auto-flow:column; grid-auto-columns:1fr;
        position:fixed; left:0; right:0; bottom:0; z-index:40;
        background:var(--card); border-top:1px solid var(--line);
        padding-bottom:env(safe-area-inset-bottom); }
  .mobnav a, .mobnav button { position:relative; height:54px; display:flex;
        align-items:center; justify-content:center; text-decoration:none;
        color:var(--muted); background:none; border:0; width:100%; cursor:pointer; }
  .mobnav .ic { width:23px; height:23px; }
  .mobnav .is-here { color:var(--navy); }
  .mobnav .is-here::before { content:''; position:absolute; top:0; left:50%;
        transform:translateX(-50%); width:26px; height:2px; background:var(--navy); }
  /* Feature appnav: labels, and capture raised in the middle. */
  .mobnav-app a { flex-direction:column; gap:3px; height:58px;
        font:500 10px var(--font-ui); letter-spacing:.05em; }
  .mobnav-app .ic { width:22px; height:22px; }
  .mobnav-app .mobnav-capture { overflow:visible; }
  .mobnav-app .mobnav-capture .cap { width:50px; height:50px; margin-top:-22px;
        border-radius:50%; background:var(--navy); color:var(--on-navy);
        border:1px solid var(--line); display:flex; align-items:center;
        justify-content:center; }
  .mobnav-app .mobnav-capture .cap .ic { width:24px; height:24px; }
  .mobnav-app .mobnav-capture:active .cap { background:var(--ink); }
  /* Clearance for the bar plus the raised capture circle above it. */
  .site-foot { padding-bottom:calc(96px + env(safe-area-inset-bottom)); }
  /* Capture at arm's length: on a phone the camera is the whole product, so
     the capture controls are the biggest thing on the bin page — full-width,
     stacked, tall enough to hit one-handed over a shelf. */
  .add-buttons { flex-direction:column; gap:10px; padding:14px 16px 6px; }
  .add-buttons label { width:100%; justify-content:center; padding:17px 18px;
        font-size:16px; }
  .add-buttons label .ic { width:22px; height:22px; }
  /* The galleries table has five columns; a phone has room for two lines
     per category instead: icon, name, tick, order on the first, the gallery
     name on the second. */
  .gallery-form table tr:first-child { display:none; }
  .gallery-row { display:grid; grid-template-columns:26px 1fr auto auto;
        align-items:center; gap:8px 10px; padding:10px 18px;
        border-top:1px solid var(--line); }
  .gallery-row td { display:block; padding:0; border:0; width:auto !important; }
  .gallery-row td:nth-child(4) { grid-column:2 / -1; grid-row:2; }
  .gallery-row td.order { grid-column:4; grid-row:1; text-align:right; }

  /* The header's QR column and its padding together can exceed a narrow
     screen; shrink both rather than let the page scroll sideways. */
  .binhead { padding:14px 16px; }
  .qrbox { width:70px; height:70px; padding:4px; }
}

/* ---- sign-in page: the Sign in | Register tabs sit on top of the card ---- */
.auth-tabs { background:var(--card); border:1px solid var(--line); border-bottom:0; }
.auth-tabs + section { margin-top:0; }

/* ---- Danger zone (settings): the one place red is structural ---------- */
.wrap > section.danger { border-color:var(--bad); }
.wrap > section.danger > h2 { color:var(--bad); }
.btn-ghost.danger, .reveal[open] > summary.danger { color:var(--bad); border-color:var(--bad); }
button.danger { background:var(--bad); border-color:var(--bad); }

/* ---- reveal: a button that opens a form in place, no JavaScript ----
   <details class="reveal"><summary class="btn-ghost">…</summary><form>…</form></details> */
.reveal { display:inline-block; }
.reveal > summary { list-style:none; cursor:pointer; }
.reveal > summary::-webkit-details-marker { display:none; }
.reveal[open] > summary { color:var(--navy); }
.reveal > form { margin-top:12px; padding:0; }
.reveal[open] { display:block; width:100%; }

/* ---- Theme chooser (settings + onboarding) ----------------------------
   A segmented control; each segment is a submit button, so one click
   applies the theme — no save step, no JavaScript. */
.seg { display:inline-flex; border:1px solid var(--line); margin:0; }
.seg-opt { appearance:none; -webkit-appearance:none; border:0;
        border-right:1px solid var(--line); border-radius:0;
        background:var(--card); color:var(--muted); cursor:pointer;
        font:500 12px var(--font-mono); letter-spacing:.08em;
        text-transform:uppercase; padding:9px 18px; }
.seg-opt:last-child { border-right:0; }
.seg-opt:hover { color:var(--navy); }
.seg-opt.is-on { background:var(--navy); color:var(--on-navy); }
.theme-row label { display:block; margin:0 0 6px; }
